summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Hazel <ph10@hermes.cam.ac.uk>2004-10-07 15:04:35 +0000
committerPhilip Hazel <ph10@hermes.cam.ac.uk>2004-10-07 15:04:35 +0000
commit495ae4b01f36d0d8bb0e34a1d7263c2b8224aa4a (patch)
treefcfaa2c623d4f155eef907b50b950b602829a30b
parent0756eb3cb50d73a77b486e47528f7cb1bffdb299 (diff)
Start
-rwxr-xr-xdoc/doc-scripts/BuildFAQ59
-rwxr-xr-xdoc/doc-scripts/BuildHTML12
-rwxr-xr-xdoc/doc-scripts/BuildInfo32
-rwxr-xr-xdoc/doc-scripts/BuildPDF10
-rwxr-xr-xdoc/doc-scripts/DoConts71
-rwxr-xr-xdoc/doc-scripts/DoIndex430
-rwxr-xr-xdoc/doc-scripts/JoinPS130
-rw-r--r--doc/doc-scripts/Makefile31
-rwxr-xr-xdoc/doc-scripts/f2h338
-rwxr-xr-xdoc/doc-scripts/f2txt107
-rwxr-xr-xdoc/doc-scripts/faqchk102
-rwxr-xr-xdoc/doc-scripts/fc2k344
-rwxr-xr-xdoc/doc-scripts/g2h1451
-rwxr-xr-xdoc/doc-scripts/g2man251
-rwxr-xr-xdoc/doc-scripts/g2t1347
-rw-r--r--doc/doc-src/FAQ.src7015
-rw-r--r--doc/doc-src/filter.src1644
-rw-r--r--doc/doc-src/markup.sg86
-rw-r--r--doc/doc-src/spec.src27935
-rw-r--r--doc/doc-txt/ChangeLog2058
-rw-r--r--doc/doc-txt/ChangeLog.02862
-rw-r--r--doc/doc-txt/Exim3.upgrade673
-rw-r--r--doc/doc-txt/Exim4.upgrade1732
-rw-r--r--doc/doc-txt/NewStuff605
-rw-r--r--doc/doc-txt/OptionLists.txt927
-rw-r--r--doc/doc-txt/README84
-rw-r--r--doc/doc-txt/README.SIEVE433
-rw-r--r--doc/doc-txt/dbm.discuss.txt322
-rw-r--r--doc/doc-txt/pcrepattern.txt1413
-rw-r--r--doc/doc-txt/pcretest.txt455
30 files changed, 52959 insertions, 0 deletions
diff --git a/doc/doc-scripts/BuildFAQ b/doc/doc-scripts/BuildFAQ
new file mode 100755
index 000000000..9712eff4e
--- /dev/null
+++ b/doc/doc-scripts/BuildFAQ
@@ -0,0 +1,59 @@
+#! /bin/sh
+# $Cambridge: exim/doc/doc-scripts/BuildFAQ,v 1.1 2004/10/07 15:04:35 ph10 Exp $
+
+# Script to build the Exim FAQ in text and HTML formats.
+
+/bin/rm -f FAQ.txt* html/FAQ* FAQ-html/* FAQ-html.tar.*
+/bin/rm -f config.samples.tar.gz config.samples.tar.bz2
+
+# The FAQchk Perl script checks for the numbers being in order and for the
+# right number of blank lines at various places.
+
+faqchk FAQ.src
+if [ $? != 0 ]; then exit 1; fi
+
+# HTML version
+
+f2h FAQ.src html
+echo "html/FAQ*.html made"
+
+fc2k
+echo "html/FAQ-KWIC*.html made"
+
+cp html/FAQ* html/*.txt FAQ-html
+echo "copied to FAQ-html"
+
+tar cf FAQ-html.tar FAQ-html
+gzip FAQ-html.tar
+echo "FAQ-html.tar.gz made"
+
+tar cf FAQ-html.tar FAQ-html
+bzip2 -9 FAQ-html.tar
+echo "FAQ-html.tar.gz2 made"
+
+# ASCII version
+
+f2txt FAQ.src FAQ.txt
+echo "FAQ.txt made"
+
+cp FAQ.txt FAQ.txt-t
+gzip -v --best FAQ.txt-t
+mv FAQ.txt-t.gz FAQ.txt.gz
+echo "FAQ.txt.gz made"
+
+cp FAQ.txt FAQ.txt-t
+bzip2 -v -9 FAQ.txt-t
+mv FAQ.txt-t.bz2 FAQ.txt.bz2
+echo "FAQ.txt.bz2 made"
+
+# Configuration samples
+
+tar cf config.samples.tar config.samples
+gzip config.samples.tar
+echo "config.samples.tar.gz made"
+
+tar cf config.samples.tar config.samples
+bzip2 -9 config.samples.tar
+echo "config.samples.tar.bz2 made"
+
+# End
diff --git a/doc/doc-scripts/BuildHTML b/doc/doc-scripts/BuildHTML
new file mode 100755
index 000000000..9d60034ea
--- /dev/null
+++ b/doc/doc-scripts/BuildHTML
@@ -0,0 +1,12 @@
+#! /bin/sh
+# $Cambridge: exim/doc/doc-scripts/BuildHTML,v 1.1 2004/10/07 15:04:35 ph10 Exp $
+
+if [ $# != 1 ]; then
+ echo "*** Usage: BuildHTML <Exim version>"
+ exit 1
+fi
+
+g2h -split chapter filter.src "Exim Filter Specification"
+g2h -split chapter spec.src "Exim $1 Specification"
+
+# End
diff --git a/doc/doc-scripts/BuildInfo b/doc/doc-scripts/BuildInfo
new file mode 100755
index 000000000..9f8d10591
--- /dev/null
+++ b/doc/doc-scripts/BuildInfo
@@ -0,0 +1,32 @@
+#! /bin/sh
+# $Cambridge: exim/doc/doc-scripts/BuildInfo,v 1.1 2004/10/07 15:04:35 ph10 Exp $
+
+if [ "$1" = "filter" ]; then
+g2t -filter filter.src >filter.texinfo
+if [ $? != 0 ]; then exit 1; fi
+cd info
+makeinfo filter.texinfo
+if [ $? != 0 ]; then exit 1; fi
+echo ""
+echo info filter.info
+echo ""
+info -f ./filter.info
+exit
+fi
+
+if [ "$1" = "" ]; then
+g2t spec.src >spec.texinfo
+if [ $? != 0 ]; then exit 1; fi
+cd info
+makeinfo spec.texinfo
+if [ $? != 0 ]; then exit 1; fi
+echo ""
+echo info spec.info
+echo ""
+info -f ./spec.info
+exit
+fi
+
+echo "***Usage: null or filter argument required"
+
+####
diff --git a/doc/doc-scripts/BuildPDF b/doc/doc-scripts/BuildPDF
new file mode 100755
index 000000000..c8a2bc2be
--- /dev/null
+++ b/doc/doc-scripts/BuildPDF
@@ -0,0 +1,10 @@
+#! /bin/sh
+# $Cambridge: exim/doc/doc-scripts/BuildPDF,v 1.1 2004/10/07 15:04:35 ph10 Exp $
+
+echo "PDFing the spec"
+ps2pdf spec.ps spec.pdf
+
+echo "PDFing the filter spec"
+ps2pdf filter.ps filter.pdf
+
+# End
diff --git a/doc/doc-scripts/DoConts b/doc/doc-scripts/DoConts
new file mode 100755
index 000000000..410c3baa1
--- /dev/null
+++ b/doc/doc-scripts/DoConts
@@ -0,0 +1,71 @@
+#! /usr/bin/perl -w
+# $Cambridge: exim/doc/doc-scripts/DoConts,v 1.1 2004/10/07 15:04:35 ph10 Exp $
+
+$style = (@ARGV > 0)? $ARGV[0] : "a4ps";
+
+open(IN, "z-rawindex") || die "Can't open z-rawindex\n";
+open(OUT, ">z-contents") || die "Can't open z-contents\n";
+
+print OUT <<'EOF';
+.if ~~sys.fancy
+.linelength ~~sys.linelength + 0.2in
+.pagedepth ~~sys.pagedepth - 0.2in
+.linedepth 12.24
+.fi
+.include "markup.sg"
+.set chapter -1
+.set p 0
+.format p roman
+.tabset 2em 2em
+.
+.foot
+.set p ~~sys.pagenumber
+$c [~~p]
+.endfoot
+.
+.chapter Contents
+.disable filling
+.justify left
+EOF
+
+while(<IN>)
+ {
+ if (/\$e/)
+ {
+ s/\$e\s*$//; # "see also" lines have no line number
+ s/--\s*\d+$//; # remove "extra" number for index page
+
+ s/\n$//; # trailing newline
+
+ if (!/^\$/)
+ {
+ print OUT ".blank\n";
+ print OUT ".if ~~sys.leftonpage < 2*~~sys.linedepth\n";
+ print OUT ".newpage\n";
+ print OUT ".fi\n";
+ print OUT "\$shead\{$_\}\n";
+ print OUT ".blank\n";
+ }
+ else
+ {
+ print OUT "$_\n";
+ }
+ }
+ }
+
+close(IN);
+close(OUT);
+
+system("sgcal z-contents -to zc-gcode -style $style -index /dev/null");
+if ($style eq "a4ps")
+ {
+ system("sgtops zc-gcode -to zc-ps");
+ print "PostScript in zc-ps\n";
+ }
+else
+ {
+ system("mv -f zc-gcode zc-txt");
+ print "Text in zc-txt\n";
+ }
+
+# End
diff --git a/doc/doc-scripts/DoIndex b/doc/doc-scripts/DoIndex
new file mode 100755
index 000000000..1caddbd6f
--- /dev/null
+++ b/doc/doc-scripts/DoIndex
@@ -0,0 +1,430 @@
+#! /usr/bin/perl -w
+# $Cambridge: exim/doc/doc-scripts/DoIndex,v 1.1 2004/10/07 15:04:35 ph10 Exp $
+
+# Script for producing the Index for the Exim manual from the output of the
+# SGCAL run. This is copied from the script for the Exim book.
+
+
+##############################################################################
+# Patterns for matching things to be removed from the sort keys
+
+# This was copied from the Exim book processor, but we have now found a
+# better way of doing this. Leave the code until I am quite sure...
+
+# $pat[0] = qr/ \(\\\*see also\*\\[^)]+\)/;
+# $pat[1] = qr/(?<!@)\/\//; # //
+# $pat[2] = qr/(?<!@)\/\\/; # /\
+# $pat[3] = qr/(?<!@)\\\//; # \/
+# $pat[4] = qr/(?<!@) \\ # non-@ \, followed by one of
+# (?:
+# [\.\/] | # dot or slash
+# !- | # !-
+# !\+ | # !+
+# !\. | # !.
+# "\+ | # "+
+# \([.\/]? | # ( and optional . or slash
+# [[\$\\%?!-"] | # [ $ \ % ! " or -
+# \*{1,2} | # * or **
+# \^{1,2}\/? # ^ or ^^ and optional slash
+# )/x;
+# $pat[5] = qr/(?: []\$\\%)?!"] | # ] $ \ % ) ? " or ! )
+# \*{1,2} | # * or ** ) optional
+# \^{1,2})? # ^ or ^^ )
+# \\/x; # then \
+# $pat[6] = qr/(?<!@)::/;
+# $pat[7] = qr/\sR[FS]\b/;
+# $pat[8] = qr/``/;
+# $pat[9] = qr/''/;
+# $pat[10] = qr/`/;
+# $pat[11] = qr/'/;
+# $pat[12] = qr/,/;
+# $pat[13] = qr/\(e?s\)/;
+
+
+# Other patterns
+
+# $keysplit = qr/^(.*?)(\|\|.*?)?\s(R[AZ])?\s?(\d+)$/;
+
+$keysplit = qr/^(.*?)(\@\|\@\|.*?)?\s(R[AZ])?\s?(\d+)$/;
+
+
+# The sort function
+
+sub cf {
+my($x,$y) = ($a,$b);
+
+############old#############
+#foreach $pattern (@pat) # Remove strings by pattern
+# {
+# $x =~ s/$pattern//g;
+# $y =~ s/$pattern//g;
+# }
+##########################
+
+
+# Turn || into @|@|
+
+$x =~ s/\|\|/@|@|/g;
+$y =~ s/\|\|/@|@|/g;
+
+# Remove all special characters, except those preceded by @
+
+$x =~ s/(?<!\@)[^\w\@\s]//g;
+$y =~ s/(?<!\@)[^\w\@\s]//g;
+
+# Remove the escaping @s
+
+#$x =~ s/\@(.)/$1/g;
+#$y =~ s/\@(.)/$1/g;
+
+
+
+################old ########################
+#$x =~ s/:(\w+):/$1/g; # :fail: etc => fail
+#$y =~ s/:(\w+):/$1/g;
+
+#$x =~ s/^\@[^a-z]+/\@/i; # Make keys starting with @
+#$y =~ s/^\@[^a-z]+/\@/i; # sort on @ followed by the first letter
+##############################################3
+
+
+$x =~ s/\@_/\x7f/g; # Make underscore sort late (option names)
+$y =~ s/\@_/\x7f/g;
+
+# Split up to sort on individual parts
+
+my($xp,$xs,$xr,$xn) = $x =~ /$keysplit/;
+my($yp,$ys,$yr,$yn) = $y =~ /$keysplit/;
+
+$xr = "" if !defined $xr;
+$yr = "" if !defined $yr;
+
+$xs = "" if !defined $xs;
+$ys = "" if !defined $ys;
+
+if ($show_keys)
+ {
+ print "a=$a\n x=$x\n xp=$xp\n xs=$xs\n xr=$xr\n xn=$xn\n";
+ print "b=$b\n y=$y\n yp=$yp\n ys=$ys\n yr=$yr\n yn=$yn\n";
+ }
+
+my ($c) = "\L$xp" cmp "\L$yp"; # Caseless, primary text only
+$c = $xp cmp $yp if $c == 0; # Caseful, primary text only
+$c = "\L$xs" cmp "\L$ys" if $c == 0; # Caseless, secondary text only
+$c = $xs cmp $ys if $c == 0; # Caseful, secondary text only
+$c = $xn <=> $yn if $c == 0; # Compare the numbers
+$c = $xr cmp $yr if $c == 0; # Sort RA before RZ
+return $c;
+}
+
+
+
+##############################################################################
+# Function for getting the next line from the @lines vector, using the global
+# index $1. If the next pair of lines specifies a range of pages, combine them.
+# That's why $linenumber has to be global - so we can increment it. If there's
+# a range error, return "".
+
+sub getnextentry {
+my($line) = $lines[$linenumber];
+my($aa,$zz,$tline,$nextline,$tnextline);
+
+if ($line =~ / RA (\d+)/)
+ {
+ $aa = $1;
+ $nextline = $lines[++$linenumber];
+ if ($nextline =~ / RZ (\d+)/)
+ {
+ $zz = $1;
+ }
+ else
+ {
+ print STDERR "** Bad range data (1)\n";
+ print STDERR " $line\n";
+ print STDERR " $nextline\n";
+ return "";
+ }
+
+ $tline = $line;
+ $tnextline = $nextline;
+
+ $tline =~ s/ RA \d+//;
+ $tnextline =~ s/ RZ \d+//;
+
+ if ($tline ne $tnextline)
+ {
+ print STDERR "** Bad range data (2)\n";
+ print STDERR " $line\n";
+ print STDERR " $nextline\n";
+ return "";
+ }
+
+ $line = ($aa eq $zz)? "$tline $aa" : "$tline $aa--$zz";
+ }
+
+elsif ($line =~ / RZ (\d+)/)
+ {
+ print STDERR "** Bad range data (RZ without RA)\n";
+ print STDERR " $line\n";
+ return "";
+ }
+
+return $line
+}
+
+
+
+
+##############################################################################
+# Function for outputting a line, checking for the current primary
+# and indenting a bit for secondaries. We also need a newpar
+# before each item, because the main indent is set to a largish indent
+# for long reference lists, but the parindent is set to counter this.
+# This is where we handle the break between letters. We know that any non-
+# alphamerics at the start of lines are markup, except for @. A reference
+# value of 99999 is for the "see also" lines. Suppress it.
+
+sub outline {
+my($text,$ref) = ($_[0],$_[1]);
+my ($letter) = $text =~ /^[^A-Za-z0-9\@]*(.)/;
+
+return if $text =~ /^\s*$/;
+
+if ($ref eq "99999") # dummy for see also
+ {
+ $ref = ""
+ }
+else
+ {
+ $ref = "#$ref"; # prepend space
+ }
+
+if ($letter =~ /\d/) { $letter = "0"; } else { $letter = "\U$letter"; }
+
+print OUT ".newpar\n";
+
+if ($letter ne $currentletter && $letter ge "A")
+ {
+ print OUT ".newletter\n";
+ $currentletter = $letter;
+ }
+
+$text =~ s/\@'/\$'/g; # Turns @' into $' so that it prints a non-curly quote
+
+if ($text =~ /^(.+)\|\|(.*)$/)
+ {
+ my($primary,$secondary) = ($1,$2);
+
+ if ($primary ne $lastprimary)
+ {
+ print OUT ".primary $primary\n";
+ $lastprimary = $primary;
+ }
+
+ $primary =~ s/"/""/g;
+ $secondary =~ s/"/""/g;
+
+ my($contprim) = $primary;
+ $contprim =~ s/ \(\\\*see also\*\\[^)]+\)//;
+
+ print OUT ".secondary \"$primary\" \"$secondary$ref\" \"$contprim\"\n";
+ }
+
+# Not a two-part item; insert @ if the first char is a dot
+
+else
+ {
+ print OUT "@" if $text =~ /^\./;
+ print OUT "$text$ref\n";
+ $lastprimary = $text;
+ }
+}
+
+
+
+
+
+##############################################################################
+# The main script
+
+$save_sorted = 0;
+$test_index = 0;
+$show_keys = 0;
+
+while (@ARGV > 0)
+ {
+ my($arg) = shift @ARGV;
+ if ($arg eq "-k") { $show_keys = 1; }
+ elsif ($arg eq "-s") { $save_sorted = 1; }
+ elsif ($arg eq "-t") { $test_index = $save_sorted = 1; }
+ else { die "Unknown option $arg\n"; }
+ }
+
+if ($test_index)
+ {
+ open(IN, "z-testindex") || die "Can't open z-testindex\n";
+ }
+else
+ {
+ open(IN, "z-rawindex") || die "Can't open z-rawindex\n";
+ }
+
+open(OUT, ">z-index") || die "Can't open z-index\n";
+
+# Extract index lines ($e lines are contents). Until we hit the first
+# $e line, we are dealing with "see also" index lines, for which we want
+# to turn the line number into 99999.
+
+$#lines = -1;
+$prestuff = 1;
+
+while (<IN>)
+ {
+ s/\n$//;
+ if (/\$e/)
+ {
+ $prestuff = 0;
+ }
+ else
+ {
+ s/(\D)$/$1 99999/ if $prestuff; # No number in "see also"
+ push(@lines, $_);
+ }
+ $index_pagenumber = $1 if /^Index\$e(\d+)/;
+ }
+close(IN);
+
+# Sort, ignoring markup
+
+print STDERR "Sorting ...\n";
+@lines = sort cf @lines;
+
+# Keep a copy of the sorted data, for reference
+
+if ($save_sorted)
+ {
+ open(X, ">z-indexsorted") || die "Can't open z-indexsorted\n";
+ foreach $line (@lines)
+ {
+ print X "$line\n";
+ }
+ close(X);
+ }
+
+# Heading for the index file
+
+print OUT <<"EOF";
+.library "a4ps"
+.linelength ~~sys.linelength + 16.0
+
+.include "markup.sg"
+
+.indent 3em
+.parspace 0
+.parindent -3em
+.justify left
+.
+.foot
+\$c [~~sys.pagenumber]
+.endfoot
+.
+.cancelflag #
+.flag # "\$S*1"
+.set INDEX true
+.
+.macro primary "text"
+.if ~~sys.leftonpage < 2ld
+.newcolumn
+.fi
+~~1
+.newpar
+.endm
+.
+.macro secondary "prim" "sec" "contprim"
+.if ~~sys.leftonpage < 1ld
+.newcolumn
+.newpar
+~~3 \$it\{(continued)\}
+.newpar
+.fi
+##~~2
+.endm
+.
+.macro newletter
+.if ~~sys.leftonpage < 4ld
+.newcolumn
+.else
+.space 1ld
+.fi
+.newpar
+.endm
+.
+.set chapter -1
+.page $index_pagenumber
+.chapter Index
+.columns 2
+.newpar
+.
+EOF
+
+# Process the lines and output the result.
+# Note that $linenumber is global, and is changed by getnextentry() for
+# pairs of lines that represent ranges.
+
+$lastprimary = "";
+$lastref = "";
+$currenttext = $currentref = "";
+$currentletter = "";
+$badrange = 0;
+
+print STDERR "Processing ...\n";
+
+for ($linenumber = 0; $linenumber < @lines; $linenumber++)
+ {
+ $line = &getnextentry();
+
+ if ($line eq "") # Bad range data - but carry on to get all of it
+ {
+ $badrange = 1;
+ next;
+ }
+
+ # Split off the text and reference
+
+ ($text,$ref) = $line =~ /^(.*)\s+([\d-]+)$/;
+
+ # If same as current text, just add the new reference, unless its a duplicate
+
+ if ($text eq $currenttext)
+ {
+ if ($ref ne $lastref)
+ {
+ $currentref .= ", $ref";
+ $lastref = $ref;
+ }
+ next;
+ }
+
+ # Not the same as the current text. Output the current text, then
+ # set up a new current.
+
+ &outline($currenttext, $currentref);
+
+ $currenttext = $text;
+ $currentref = $lastref = $ref;
+ }
+
+# Output the final line and close the file
+
+&outline($currenttext, $currentref);
+close(OUT);
+
+die "** Aborted\n" if $badrange;
+
+# Format the index
+
+system("sgcal z-index -to zi-gcode -index /dev/null");
+system("sgtops zi-gcode -to zi-ps");
+print "PostScript in zi-ps\n";
+
+# End
diff --git a/doc/doc-scripts/JoinPS b/doc/doc-scripts/JoinPS
new file mode 100755
index 000000000..92ba59a5f
--- /dev/null
+++ b/doc/doc-scripts/JoinPS
@@ -0,0 +1,130 @@
+#!/usr/bin/perl
+# $Cambridge: exim/doc/doc-scripts/JoinPS,v 1.1 2004/10/07 15:04:35 ph10 Exp $
+
+# Make the basic PostScript file for the Exim spec from the gcode file, then
+# join it together with the contents and the index, to make a single
+# PostScript file, suitable for double-sided printing.
+
+sub blank_page {
+my($title) = shift @_;
+printf(OUT "%%%%Page: %s %d\nxpage\n\n", $title, $pagenumber++);
+}
+
+
+@roman = ("i", "ii", "iii", "iv", "v", "vi", "vii", "viii", "ix", "x",
+ "xi", "xii", "xiii", "xiv", "xv", "xvi", "xvii", "xviii", "xix");
+
+$pagenumber = 1;
+
+system("sgtops z-gcode -to z-ps") && die "sgtops run failed\n";
+
+open(SPEC, "z-ps") || die "Can't open z-ps\n";
+open(CONTS, "zc-ps") || die "Can't open zc-ps\n";
+open(INDEX, "zi-ps") || die "Can't open zi-ps\n";
+open(OUT, ">spec.ps") || die "Can't open spec.ps\n";
+
+# Copy spec headings etc.
+
+while (<SPEC>)
+ {
+ last if (/^%%Page:/) ;
+ print OUT;
+ }
+
+# Copy the first two pages - the title page, and its blank verso
+
+for ($i = 1; $i < 3; $i++)
+ {
+ printf(OUT "%%%%Page: title%s %d\n", ($i == 1)? "" : "-verso", $pagenumber++);
+ while (<SPEC>)
+ {
+ last if (/^%%Page:/) ;
+ print OUT;
+ }
+ }
+
+# Skip the contents heading
+
+while (<CONTS>)
+ {
+ last if (/^%%Page:/) ;
+ }
+
+# Output the contents pages - fudge the roman numerals as we know there
+# won't be a vast number of them.
+
+$subpagenumber = 0;
+while (!eof CONTS)
+ {
+ printf(OUT "%%%%Page: %s %d\n", $roman[$subpagenumber++], $pagenumber++);
+ while (<CONTS>)
+ {
+ next if (/^%%Pages:/);
+ next if (/^%%Trailer/);
+ last if (/^%%Page:/) ;
+ print OUT;
+ }
+ }
+printf(OUT "\n");
+
+# If contents was an odd number of pages, insert a blank page
+
+&blank_page("contents-pad") if ($pagenumber & 1) == 0;
+
+# Copy the rest of the main file
+
+$subpagenumber = 1;
+
+while (!eof SPEC)
+ {
+ printf(OUT "%%%%Page: %d %d\n", $subpagenumber++, $pagenumber++);
+ while (<SPEC>)
+ {
+ next if (/^%%Pages:/);
+ next if (/^%%Trailer/);
+ last if (/^%%Page:/) ;
+ print OUT;
+ }
+ }
+printf(OUT "\n");
+
+# If contents was an odd number of pages, insert a blank page
+
+&blank_page("body-pad") if ($pagenumber & 1) == 0;
+
+# Skip the index heading
+
+while (<INDEX>)
+ {
+ last if (/^%%Page:/) ;
+ }
+
+# Copy the index pages
+
+$subpagenumber = 1;
+
+while (!eof INDEX)
+ {
+ printf(OUT "%%%%Page: I%d %d\n", $subpagenumber++, $pagenumber++);
+ while (<INDEX>)
+ {
+ next if (/^%%Pages:/);
+ next if (/^%%Trailer/);
+ last if (/^%%Page:/) ;
+ print OUT;
+ }
+ }
+
+# Add final comments
+
+printf(OUT "%%%%Trailer\n");
+printf(OUT "%%%%Pages: %d\n", $pagenumber-1);
+
+# That's it
+
+close(SPEC);
+close(CONTS);
+close(INDEX);
+close(OUT);
+
+# End
diff --git a/doc/doc-scripts/Makefile b/doc/doc-scripts/Makefile
new file mode 100644
index 000000000..79b1f0490
--- /dev/null
+++ b/doc/doc-scripts/Makefile
@@ -0,0 +1,31 @@
+# $Cambridge: exim/doc/doc-scripts/Makefile,v 1.1 2004/10/07 15:04:35 ph10 Exp $
+
+# Makefile for Exim documentation
+
+ps:; sgcal-fr spec.src -v -to z-gcode -index z-rawindex
+ sgtops z-gcode -to z-ps
+
+txt:; g2man
+ sgcal-fr spec.src -style online -v -to z-txt -index z-rawindex
+
+contents:; @DoConts
+
+index:; @DoIndex
+
+# The file z-rawindex is included by the filter source to create a TOC.
+# First empty it, then do a dummy format to create it, then do a second
+# pass. This works because the TOC occupies no more than the rest of the
+# first page.
+
+filterps:; /bin/rm -rf z-rawindex
+ touch z-rawindex
+ sgcal-fr filter.src -v -to z-gcode -index z-rawindex
+ sgcal-fr filter.src -v -to z-gcode -index /dev/null
+ sgtops z-gcode -to filter.ps
+
+filtertxt:; /bin/rm -rf z-rawindex
+ touch z-rawindex
+ sgcal-fr filter.src -style online -v -to filter.txt -index z-rawindex
+ sgcal-fr filter.src -style online -v -to filter.txt -index /dev/null
+
+clean:; /bin/rm -f z*
diff --git a/doc/doc-scripts/f2h b/doc/doc-scripts/f2h
new file mode 100755
index 000000000..426e46e67
--- /dev/null
+++ b/doc/doc-scripts/f2h
@@ -0,0 +1,338 @@
+#!/usr/bin/perl
+# $Cambridge: exim/doc/doc-scripts/f2h,v 1.1 2004/10/07 15:04:35 ph10 Exp $
+
+# Script to turn the Exim FAQ into HTML.
+
+use integer;
+
+# Function to do text conversions that apply to both displays and non displays
+
+sub process_both {
+my($s) = $_[0];
+$s =~ s/</&#60;/g; # Deal with < and >
+$s =~ s/>/&#62;/g;
+return $s;
+}
+
+
+# Function to do text conversions to display paragraphs
+
+sub process_display {
+my($s) = $_[0];
+$s =~ s/^==>/ /;
+my($indent) = $s =~ /^(\s+)/;
+my($remove) = " " x (length($indent) - 3);
+$s =~ s/^$remove//mg;
+$s = &process_both($s);
+return $s;
+}
+
+
+# Function to do text conversions to paragraphs not in displays.
+
+sub process_non_display {
+my($s) = &process_both($_[0]);
+
+$s =~ s/@\\/@@backslash@@/g; # @\ temporarily hidden
+
+$s =~ s/\\#/&nbsp;/g; # \# is a hard space
+
+$s =~ s/\\\*\*([^*]*)\*\*\\/<b>$1<\/b>/g; # \**...**\ => bold
+$s =~ s/\\\*([^*]*)\*\\/<i>$1<\/i>/g; # \*.....*\ => italic
+$s =~ s/\\"([^"]*)"\\/<tt>$1<\/tt>/g; # \"....."\ => fixed pitch
+$s =~ s/\\\$([^\$]*)\$\\/<i>\$$1<\/i>/g; # \$.....$\ => $italic
+$s =~ s/\\\\([^\\]*)\\\\/<small>$1<\/small>/g; # \\.....\\ => small
+$s =~ s/\\\(([^)]*)\)\\/<i>$1<\/i>/g; # \(.....)\ => italic
+$s =~ s/\\-([^\\]*)-\\/<b>-$1<\/b>/g; # \-.....-\ => -bold
+$s =~ s/\\\[([^]]*)\]\\/&\#60;<i>$1<\/i>&\#62;/gx; # \[.....]\ => <italic>
+$s =~ s/\\\?(.*?)\?\\/<a href="$1">$1<\/a>/g; # \?.....?\ => URL
+$s =~ s/\\\^\^([^^]*)\^\^\\/<i>$1<\/i>/g; # \^^...^^\ => italic
+$s =~ s/\\\^([^^]*)\^\\/<i>$1<\/i>/g; # \^.....^\ => italic
+$s =~ s/\\%([^%]*)%\\/<b>$1<\/b>/g; # \%.....%\ => bold
+$s =~ s/\\\/([^\/]*)\/\\/<i>$1<\/i>/g; # \/...../\ => italic
+$s =~ s/\\([^\\]+)\\/<tt>$1<\/tt>/g; # \.......\ => fixed pitch
+
+$s =~ s"//([^/\"]*)//"<i>$1</i>"g; # //.....// => italic
+$s =~ s/::([^:]*)::/<i>$1:<\/i>/g; # ::.....:: => italic:
+
+$s =~ s/``(.*?)''/&#147;$1&#148;/g; # ``.....'' => quoted text
+
+$s =~ s/\s*\[\[br\]\]\s*/<br>/g; # [[br]] => <br>
+
+$s =~ s/@@backslash@@/\\/g; # Put back single backslash
+
+$s =~ s/^(\s*\(\d\)\s)/$1&nbsp;/; # Extra space after (1), etc.
+
+# Cross references within paragraphs
+
+$s =~ s/Q(\d{4})(?!:)/<a href="$xref{$1}">$&<\/a>/xg;
+
+# References to configuration samples
+
+$s =~ s/\b([CFLS]\d\d\d)\b/<a href="$1.txt">$1<\/a>/g;
+
+# Remove white space preceding a newline in the middle of paragraphs,
+# to keep the file smaller (and for human reading when debugging).
+
+$s =~ s/^\s+//mg;
+
+return $s;
+}
+
+
+# Main program
+
+# We want to read the file paragraph by paragraph; Perl only does this if the
+# separating lines are truly blank. Having been caught by lines containing
+# whitespace before, do a detrailing pass first.
+
+open(IN, "$ARGV[0]") || die "can't open $ARGV[0] (preliminary)\n";
+open(OUT, ">$ARGV[0]-$$") || die "can't open $ARGV[0]-$$\n";
+while (<IN>)
+ {
+ s/[ \t]+$//;
+ print OUT;
+ }
+close(IN);
+close(OUT);
+rename("$ARGV[0]-$$", "$ARGV[0]") ||
+ die "can't rename $ARGV[0]-$$ as $ARGV[0]\n";
+
+# The second argument is the name of a directory into which to put multiple
+# HTML files. We start off with FAQ.html.
+
+$hdir = $ARGV[1];
+open(OUT, ">$hdir/FAQ.html") || die "can't open $hdir/FAQ.html\n";
+
+# Initial output
+
+print OUT <<End ;
+<html>
+<head>
+<title>The Exim FAQ</title>
+</head>
+<body bgcolor="#F8F8F8" text="#00005A" link="#0066FF" alink="#0066FF" vlink="#000099">
+<h1>The Exim FAQ</h1>
+End
+
+$/ = "";
+
+# First pass to read the titles and questions and create the table of
+# contents. We save it up in a vector so that it can be written after the
+# introductory paragraphs.
+
+open(IN, "$ARGV[0]") || die "can't open $ARGV[0] (first time)\n";
+
+$toc = 0;
+$sec = -1;
+$inul = 0;
+
+while ($_ = <IN>)
+ {
+ $count = s/\n/\n/g - 1; # Number of lines in paragraph
+
+ if ($count == 1 && /^\d+\./) # Look for headings
+ {
+ chomp;
+ push @toc, "</ul>" if $inul;
+ $inul = 0;
+ push @toc, "<br>\n\n" if $sec++ >= 0;
+ push @toc, "<a name=\"TOC$toc\" href=\"FAQ_$sec.html\">$_</a>\n";
+ $toc++;
+
+ ($number,$title) = /^(\d+)\.\s+(.*)$/;
+ if ($title ne "UUCP" && $title ne "IRIX" && $title ne "BSDI" &&
+ $title ne "HP-UX")
+ {
+ ($initial,$rest) = $title =~ /^(.)(.*)$/;
+ $title = "$initial\L$rest";
+ $title =~ s/isdn/ISDN/;
+ $title =~ s/\btls\b/TLS/;
+ $title =~ s/\bssl\b/SSL/;
+ $title =~ s/ os x/ OS X/;
+ }
+ push @seclist, "<a href=\"FAQ_$sec.html\">$number. $title</a>";
+
+ next;
+ }
+
+ if (/^(Q\d{4})/) # Q initial paragraph
+ {
+ if (!$inul)
+ {
+ push @toc, "<ul>\n";
+ $inul = 1;
+ }
+ $num = $1;
+ $rest = $';
+ $xref{substr($num,1)} = "FAQ_$sec.html#TOC$toc";
+ $rest =~ s/^: /:&nbsp;&nbsp;/;
+ $rest = &process_non_display($rest);
+ push @toc, "<li><a name=\"TOC$toc\" href=\"FAQ_$sec.html#TOC$toc\">$num</a>$rest<br><br></li>\n";
+ $toc++;
+ next;
+ }
+ }
+
+push @toc, "</ul>\n" if $inul;
+close(IN);
+
+
+# This is the main processing pass. We have to detect the different kinds of
+# "paragraph" and do appropriate things.
+
+open(IN, "$ARGV[0]") || die "can't open $ARGV[0] (second time)\n";
+
+# Skip the title line
+
+$_ = <IN>;
+
+# Handle the rest of the file
+
+$toc = 0;
+$maxsec = $sec;
+$sec = -1;
+
+while ($_ = <IN>)
+ {
+ $count = s/\n/\n/g - 1; # Number of lines in paragraph
+ chomp; # Trailing newlines
+
+ if (/^The FAQ is divided into/)
+ {
+ my($count) = scalar(@seclist);
+ my($cols) = ($count + 1)/2;
+
+ print OUT "<hr><a name=\"TOC\"><h1>Index</h1></a>\n";
+ print OUT "<p>A <i>Keyword-in-context</i> <a href=\"FAQ-KWIC_A.html\">index</a> " .
+ "to the questions is available. This is usually the " .
+ "quickest way to find information in the FAQ.</p>\n";
+
+ print OUT "<h1>Contents</h1>\n";
+ print OUT "<p>The FAQ is divided into the following sections:<br><br></p>\n";
+
+ print OUT "<table>\n";
+
+ for ($i = 0; $i < $cols; $i++)
+ {
+ print OUT "<tr>\n";
+ print OUT " <td>", "&nbsp;" x 4, "</td>\n";
+ print OUT " <td>&nbsp;$seclist[$i]</td>\n";
+ print OUT " <td>", "&nbsp;" x8, "$seclist[$cols+$i]</td>\n"
+ if $cols+$i < $count;
+ print OUT "</tr>\n";
+ }
+ print OUT "</table><br><p>\n<hr><br>\n";
+ print OUT "<h1>List of questions</h1>\n";
+
+ $_ = <IN>; # Skip section list
+ next;
+ }
+
+ if ($count == 1 && /^\d+\./) # Look for headings
+ {
+ if (@toc != 0) # TOC when hit first heading
+ {
+ while (@toc != 0) { print OUT shift @toc; }
+ }
+
+ # Output links at the bottom of this page
+
+ print OUT "<hr><br>\n";
+ print OUT "<a href=\"FAQ.html#TOC\">Contents</a>&nbsp;&nbsp;\n";
+ if ($sec > 0)
+ {
+ printf OUT ("<a href=\"FAQ_%d.html\">Previous</a>&nbsp;&nbsp;\n", $sec-1);
+ }
+ printf OUT ("<a href=\"FAQ_%d.html\">Next</a>\n", $sec+1);
+
+ # New section goes in new file
+
+ print OUT "</body>\n</html>\n";
+ close OUT;
+
+ $sec++;
+ open(OUT, ">$hdir/FAQ_$sec.html") ||
+ die "Can't open $hdir/FAQ_$sec.html\n";
+
+ print OUT "<html>\n<head>\n" .
+ "<title>The Exim FAQ Section $sec</title>\n" .
+ "</head>\n" .
+ "<body bgcolor=\"#F8F8F8\" text=\"#00005A\" " .
+ "link=\"#FF6600\" alink=\"#FF9933\" vlink=\"#990000\">\n";
+
+ printf OUT "<h1>The Exim FAQ</h1>\n";
+
+ print OUT "<a href=\"FAQ.html#TOC\">Contents</a>&nbsp;&nbsp;\n";
+ if ($sec > 0)
+ {
+ printf OUT ("<a href=\"FAQ_%d.html\">Previous</a>&nbsp;&nbsp;\n", $sec-1);
+ }
+ if ($sec < $maxsec)
+ {
+ printf OUT ("<a href=\"FAQ_%d.html\">Next</a>\n", $sec+1);
+ }
+
+ print OUT "<hr><br>\n";
+
+ print OUT "<h2><a href=\"FAQ.html#TOC$toc\">$_</a></h2>\n";
+ $toc++;
+ next;
+ }
+
+ s/^([QA]\d{4}|[CFLS]\d{3}): /$1:&nbsp;&nbsp;/;
+
+ if (/^(Q\d{4}:)/) # Q initial paragraph
+ {
+ print OUT "<p>\n<a name=\"TOC$toc\" href=\"FAQ.html#TOC$toc\">$1</a>";
+ $_ = &process_non_display($');
+ print OUT "$_\n</p>\n";
+ $toc++;
+ next;
+ }
+
+ if (/^A\d{4}:/) # A initial paragraph
+ {
+ $_ = &process_non_display($_);
+ s/^(A\d{4}:)/<font color="#00BB00">$1<\/font>/;
+ print OUT "<p>\n$_\n</p>\n";
+ next;
+ }
+
+ # If a paragraph begins ==> it is a display which must remain verbatin
+ # and not be reformatted. The flag gets turned into spaces.
+
+ if ($_ =~ /^==>/)
+ {
+ $_ = &process_display($_);
+ chomp;
+ print OUT "<pre>\n$_</pre>\n";
+ }
+
+ # Non-display paragraph; massage the final line & my sig.
+
+ elsif (/^\*\*\* End of Exim FAQ \*\*\*/)
+ {
+ }
+
+ else
+ {
+ $_ = &process_non_display($_);
+ if (/^Philip Hazel/)
+ {
+ s/\n/<br>\n/g;
+ s/<br>$/<hr><br>/;
+ }
+ print OUT "<p>\n$_\n</p>\n";
+ }
+ }
+
+close(IN);
+
+print OUT "<hr><br>\n";
+print OUT "<a href=\"FAQ.html#TOC\">Contents</a>&nbsp;&nbsp;\n";
+printf OUT ("<a href=\"FAQ_%d.html\">Previous</a>\n", $sec-1);
+
+print OUT "</body>\n</html>\n";
+close(OUT);
+End
diff --git a/doc/doc-scripts/f2txt b/doc/doc-scripts/f2txt
new file mode 100755
index 000000000..ff5d70392
--- /dev/null
+++ b/doc/doc-scripts/f2txt
@@ -0,0 +1,107 @@
+#!/usr/bin/perl
+# $Cambridge: exim/doc/doc-scripts/f2txt,v 1.1 2004/10/07 15:04:35 ph10 Exp $
+
+# Script to turn the Exim FAQ into plain ASCII.
+
+use integer;
+
+
+# Function to do text conversions to display paragraphs
+
+sub process_display {
+my($s) = $_[0];
+$s =~ s/^==>/ /;
+return $s;
+}
+
+
+# Function to do text conversions to paragraphs not in displays.
+
+sub process_non_display {
+my($s) = $_[0];
+
+$s =~ s/@\\/@@backslash@@/g; # @\ temporarily hidden
+
+$s =~ s/\\#/ /g; # \# is a hard space
+
+$s =~ s/\\\*\*([^*]*)\*\*\\/$1/g; # \**...**\ => text
+$s =~ s/\\\*([^*]*)\*\\/"$1"/g; # \*.....*\ => "text"
+$s =~ s/\\"([^"]*)"\\/"$1"/g; # \"....."\ => "text"
+$s =~ s/\\\$([^\$]*)\$\\/\$$1/g; # \$.....$\ => $text
+$s =~ s/\\\\([^\\]*)\\\\/$1/g; # \\.....\\ => text
+$s =~ s/\\\(([^)]*)\)\\/$1/g; # \(.....)\ => text
+$s =~ s/\\-([^-]*)-\\/-$1/g; # \-.....-\ => -text
+$s =~ s/\\\[([^]]*)\]\\/<$1>/gx; # \[.....]\ => <text>
+$s =~ s/\\\?(.*?)\?\\/$1/g; # \?.....?\ => text
+$s =~ s/\\\^\^([^^]*)\^\^\\/$1/g; # \^^...^^\ => text
+$s =~ s/\\\^([^^]*)\^\\/$1/g; # \^.....^\ => text
+$s =~ s/\\%([^%]*)%\\/"$1"/g; # \%.....%\ => "text"
+$s =~ s/\\\/([^\/]*)\/\\/$1/g; # \/...../\ => text
+$s =~ s/\\([^\\]+)\\/"$1"/g; # \.......\ => "text"
+
+$s =~ s"//([^/\"]*)//"$1"g; # //.....// => text
+$s =~ s/::([^:]*)::/$1:/g; # ::.....:: => text:
+
+$s =~ s/``(.*?)''/"$1"/g; # ``.....'' => "text"
+
+$s =~ s/\s*\[\[br\]\]\s*\n/\n/g; # Remove [[br]]
+
+$s =~ s/@@backslash@@/\\/g; # Put back single backslash
+
+return $s;
+}
+
+
+# Main program
+
+# We want to read the file paragraph by paragraph; Perl only does this if the
+# separating lines are truly blank. Having been caught by lines containing
+# whitespace before, do a detrailing pass first.
+
+open(IN, "$ARGV[0]") || die "can't open $ARGV[0] (preliminary)\n";
+open(OUT, ">$ARGV[0]-$$") || die "can't open $ARGV[0]-$$\n";
+while (<IN>)
+ {
+ s/[ \t]+$//;
+ print OUT;
+ }
+close(IN);
+close(OUT);
+rename("$ARGV[0]-$$", "$ARGV[0]") ||
+ die "can't rename $ARGV[0]-$$ as $ARGV[0]\n";
+
+# The second argument is the name of the output file.
+
+open(IN, "$ARGV[0]") || die "can't open $ARGV[0] (for real)\n";
+open(OUT, ">$ARGV[1]") || die "can't open $ARGV[1]\n";
+
+$/ = "";
+
+while ($_ = <IN>)
+ {
+ # Comment lines start with ##
+
+ next if /^\#\#/;
+
+ # If a paragraph begins ==> it is a display which must remain verbatin
+ # and not be reformatted. The flag gets turned into spaces.
+
+ if ($_ =~ /^==>/)
+ {
+ $_ = &process_display($_);
+ }
+
+ # Non-display paragraph
+
+ else
+ {
+ $_ = &process_non_display($_);
+ }
+
+ print OUT;
+ }
+
+close(IN);
+close(OUT);
+
+End
diff --git a/doc/doc-scripts/faqchk b/doc/doc-scripts/faqchk
new file mode 100755
index 000000000..939d0b253
--- /dev/null
+++ b/doc/doc-scripts/faqchk
@@ -0,0 +1,102 @@
+#!/usr/bin/perl -w
+# $Cambridge: exim/doc/doc-scripts/faqchk,v 1.1 2004/10/07 15:04:35 ph10 Exp $
+
+# Script to check the FAQ source and make sure I have all the numbers
+# in the right order without duplication. Also check the numbers of blank
+# lines. It gives up on any error (other than bad blank line counts).
+
+sub oops {
+print "\nLine $line: $_[0]\n";
+print;
+exit 1;
+}
+
+sub poops {
+print "\nLine $line: $_[0]\n";
+print;
+$precede_fail = 1;
+}
+
+
+$line = 0;
+$section = -1;
+$expect_answer = 0;
+$precede_fail = 0;
+
+while (<>)
+ {
+ $line++;
+ if (/^\s*$/)
+ {
+ $blankcount++;
+ next;
+ }
+ $preceded = $blankcount;
+ $blankcount = 0;
+
+ if (/^(\d+)\./)
+ {
+ &poops("$preceded empty lines precede (3 expected)") if $preceded != 3;
+ &oops(sprint("Answer %02d%02d is missing\n", $section, $question))
+ if $expect_answer;
+ $section = $1;
+ $question = ($section == 20)? 0 : 1;
+ $expected = 1;
+ if ($section == 99)
+ {
+ $c = 1;
+ $f = 1;
+ }
+ next;
+ }
+
+ if ($section != 99)
+ {
+ if (/^Q(\d\d)(\d\d):/)
+ {
+ &poops("$preceded empty lines precede ($expected expected)")
+ if $preceded != $expected;
+ $expected = 2;
+
+ &oops("Answer expected") if $expect_answer;
+ &oops("Q$1$2 is in the wrong section") if ($1 != $section);
+ &oops("Q$1$2 is out of order") if $2 != $question;
+
+ $expect_answer = 1;
+ next;
+ }
+
+ if (/^A(\d\d)(\d\d):/)
+ {
+ &poops("$preceded empty lines precede (1 expected)") if $preceded != 1;
+
+ &oops("Question expected") if !$expect_answer;
+ &oops("A$1$2 is in the wrong section") if $1 != $section;
+ &oops("A$1$2 is out of order") if $2 != $question++;
+
+ $expect_answer = 0;
+ next;
+ }
+ }
+
+ else
+ {
+ if (/^C(\d\d\d):/)
+ {
+ &oops("C$1 is mixed up in the Fs") if $f != 1;
+ # Some Cxxx configs are omitted (not translated from Exim 3) so can
+ # only check increasing number.
+ &oops("C$1 is out of order") if $1 < $c;
+ $c = $1;
+ }
+ elsif (/^F(\d\d\d):/)
+ {
+ &oops("F$1 is out of order") if $1 != $f++;
+ next;
+ }
+ }
+ }
+
+exit 1 if $precede_fail;
+
+# End
diff --git a/doc/doc-scripts/fc2k b/doc/doc-scripts/fc2k
new file mode 100755
index 000000000..936392979
--- /dev/null
+++ b/doc/doc-scripts/fc2k
@@ -0,0 +1,344 @@
+#! /usr/bin/perl -w
+# $Cambridge: exim/doc/doc-scripts/fc2k,v 1.1 2004/10/07 15:04:35 ph10 Exp $
+
+# Script to read the HTML table of contents for the Exim FAQ and create an
+# HTML KWIC index out of it.
+
+
+########################################################################
+# List of words to ignore - kept alphabetically for reference, but they
+# don't have to be in order.
+
+$ignore_list = "
+
+a ability able about address addresses addressed affect affected
+after against all allow allowed allows already also although always am an and
+and/or any anybody anyone anything anywhere are aren't arrange arrive as at
+
+back bad based basically be because been behave behaviour being best between
+bob both bug build builds built busy but by
+
+call called calls can can't cannot causes causing central certain code comes
+coming command commands complain complaining complains configure configured
+conjunction contact contain contains contained correct correctly could
+currently customer
+
+day days defined deliver delivers delivered delivery deliveries did do does
+doesn't doing don't down during
+
+e-mail e-mails each easy else email emails entirely entries entry especially
+etc even ever every example exim exim's experiencing
+
+far few file files find fine fly following for form found from fully
+
+get gets getting given gives giving go goes going got
+
+handle handles handled handling happen happens has have haven't having helpful
+him host hosts how however
+
+i i'd i'm i've if in indeed instead into is issue issues isn't it it's its
+
+jim just
+
+keep keeps know knows
+
+like line lines look looked looking lot
+
+machine machines machine's mail mails main make me mean means message messages
+might more must my myself
+
+near need neither no nor not now
+
+occur of off often ok on one only or other our out over own
+
+part parts particular per place possibility possible present problem problems
+put puts
+
+quite
+
+raised rather really reason rid right round run runs
+
+same say saying see seeing seem seems seen sees set setting she should so some
+somehow something sometimes stand state statement still strange such supposed
+system systems
+
+take takes than that the their them then there these they things think this
+those to try though to/for told too tried tries trying
+
+under until up use uses used using usually
+
+valid value values via
+
+want wanted wanting was way we we've well what what's when where whereabouts
+whenever whether which while who whose why will with within without wish won't
+wondered work worked working works would wrong
+
+xxx
+
+yet yyy
+
+";
+########################################################################
+
+
+# The regular expression fragment that defines the separator between words
+
+$wordgap = "(?:[]().?,;:\"']|(?><[^>]*>))*(?:\\s+|\$)(?:[[(\"'`]|(?><[^>]*>))*";
+
+
+########################################################################
+# Function to add to a length to accommodate HTML stuff
+
+sub setlen{
+my($len, $s) = @_;
+
+$len += length($1) while ($s =~ /(<\/?[a-z]+>)/ig);
+$len += 1 while ($s =~ /&#\d+;/g);
+
+return $len;
+}
+
+
+########################################################################
+# Function to write out the list of initials with references
+
+sub write_initials {
+my($this_initial) = "$_[0]";
+
+print OUT "<p>\n&nbsp;&nbsp;";
+
+foreach $initial (sort keys %initials)
+ {
+ if ($initial eq $this_initial)
+ {
+ print OUT "&nbsp;&nbsp;&nbsp;<font size=7 color=\"#FF0A0A\"><b>$initial</b></font>&nbsp;";
+ }
+ else
+ {
+ print OUT "<a href=\"FAQ-KWIC_$initial.html\">&nbsp;&nbsp;$initial</a>";
+ }
+ }
+
+print OUT "&nbsp;"x4 . "<a href=\"FAQ.html#TOC\">FAQ Contents</a>\n</p>\n";
+}
+
+
+
+########################################################################
+# The main program. We can pick out the contents lines because they lie
+# between <li> and </li> in the file, sometimes on more than one physical
+# line.
+
+# Turn the list of ignorable words into a hash for quick lookup. Add the
+# empty word to the list.
+
+@words = split /\s+/, $ignore_list;
+foreach $word (@words) { $ignore{$word} = 1; }
+$ignore{""} = 1;
+
+
+# Open the file and do the job
+
+open(IN, "html/FAQ.html") || die "Can't open html/FAQ.html\n";
+
+while (<IN>)
+ {
+ next unless /^<li>/;
+ $_ .= <IN> while !/<\/li>$/;
+ chomp;
+ s/\n\s*/ /g;
+
+ # Extract the operative text into $text, with the beginning in $pre.
+
+ my($pre,$text,$post) = /^<li>(.*<\/a>:(?:&nbsp;)*)(.*)<br><br><\/li>$/;
+
+ # Now split into words. As well as punctuation, there may be HTML thingies
+ # between words. Absorb them into the separators.
+
+ my(@words) = split /$wordgap/, $text;
+
+ # Lower case all the words, and remove those that we don't want.
+ # Then keep a list of all the used initials.
+
+ REMOVE_IGNORE:
+ for ($i = 0; $i < scalar @words; $i++)
+ {
+ my($word) = $words[$i] = "\L$words[$i]\E";
+
+ # Remove certain forms of word and those on the ignore list
+
+ if (defined $ignore{$word} || # word on ignore list
+ $word =~ /^-+$/ || # word consists entirely of hyphens
+ $word =~ /^-[^a-z]/ || # follows leading hyphen with non-letter
+ $word =~ /^[^a-z-]/ || # starts with a non-letter or hyphen
+ $word =~ /[@^.]/ # contains @ or ^ or .
+ )
+ {
+ splice(@words, $i, 1);
+ redo REMOVE_IGNORE if $i < scalar @words;
+ }
+
+ # Otherwise, build up a list of initials
+
+ else
+ {
+ my($inword) = $word;
+ $inword =~ s/^-//;
+ $initial = substr($inword, 0, 1);
+ $initials{"\U$initial\E"} = 1;
+ }
+ }
+
+ # Create the lines for the KWIC index, and store them in associative
+ # arrays, with the keyword as the key. That will get them sorted
+ # automatically.
+
+ while (scalar @words > 0)
+ {
+ my($word) = shift @words;
+ my($pretext, $casedword, $posttext) =
+ $text =~ /(.*?)(?<![a-z])(\Q$word\E)(?![a-z])(.*)/i;
+
+ # Remove a leading hyphen from $word so that it sorts according to
+ # the leading letter. What is actually output is $casedword, which
+ # retains the hyphen.
+
+ $word =~ s/^-//;
+
+ my($prelen) = length $pretext;
+ my($postlen) = length $posttext;
+
+ # We want to chop excessively long entries on either side. We can't set
+ # a fixed length because of the HTML control data. Call a function to
+ # add the given length to allow for HTML stuff. This is crude, but it
+ # does roughtly the right thing.
+
+ my($leftlen) = &setlen(70, $pretext);
+ my($rightlen) = &setlen(70, $posttext);
+
+ if ($prelen > $leftlen)
+ {
+ my($cutoff) = $leftlen;
+ $cutoff++
+ while ($cutoff < $prelen && substr($pretext, -$cutoff, 1) ne " ");
+ $pretext = "... " . substr($pretext, -$cutoff);
+ }
+
+ if ($postlen > $rightlen)
+ {
+ my($cutoff) = $rightlen;
+ $cutoff++
+ while ($cutoff < $postlen && substr($posttext, $cutoff, 1) ne " ");
+ $posttext = substr($posttext, 0, $cutoff) . "...";
+ }
+
+ # If the pre text has a font-ending not preceded by a font beginning
+ # (i.e. we've chopped the beginning off), we must insert a beginning.
+
+ while ($pretext =~ /^(.*?)<\/(small|tt|b|i)>/ && $1 !~ /<$2>/)
+ {
+ $pretext = "<$2>" . $pretext;
+ }
+
+ # If the pre text ends in a special font, we have to terminate that,
+ # and reset it at the start of the post text.
+
+ my($poststart) = "";
+
+ while ($pretext =~ /<(small|tt|b|i)>(?!.*?<\/\1>)/)
+ {
+ $pretext .= "</$1>";
+ $poststart .= "<$1>";
+ }
+
+ # If the post text changes font but doesn't close it, we must add
+ # the closure.
+
+ while ($posttext =~ /<(small|tt|b|i)>(?!.*?<\/\1>)/)
+ {
+ $posttext .= "</$1>";
+ }
+
+ # Remove any unnecessary changes in either of them
+
+ $pretext =~ s/<(small|tt|b|i)>\s*<\/\1>//g;
+ $posttext =~ s/<(small|tt|b|i)>\s*<\/\1>//g;
+
+ # Save the texts in associative arrays. Add the question number to
+ # the end of the word to make the key.
+
+ $pre =~ /(Q\d\d\d\d)/;
+ my($key) = "$word-$1";
+
+ $tableft{$key} = $pre . $pretext;
+ $tabright{$key} = $poststart .
+ "<font color=\"#FF0A0A\">$casedword</font>" . $posttext;
+ }
+ }
+
+close(IN);
+
+# Now write out the files. Each letter in the index goes in a different file
+
+$current_initial = "";
+
+foreach $key (sort keys %tableft)
+ {
+ my($initial) = $key =~ /^(.)/;
+ $initial = "\U$initial\E";
+
+ if ($initial ne $current_initial)
+ {
+ if ($current_initial ne "")
+ {
+ print OUT "</table>\n";
+ &write_initials($current_initial);
+ print OUT "</body>\n</html>\n";
+ close OUT;
+ }
+
+ open (OUT, ">html/FAQ-KWIC_$initial.html") ||
+ die "Can't open html/FAQ-KWIC_$initial.html\n";
+ print OUT
+ "<html>\n" .
+ "<head>\n" .
+ "<title>Exim FAQ: KWIC index section $initial</title>\n" .
+ "</head>\n" .
+ "<body bgcolor=\"#F8F8F8\" text=\"#00005A\" link=\"#0066FF\" alink=\"#0066FF\" vlink=\"#000099\">\n" .
+ "<h1>Exim FAQ: Keyword-in-context index</h1>\n";
+
+ write_initials($initial);
+
+ if ($initial eq "A")
+ {
+ print OUT <<End ;
+<p>
+This <i>Keyword-in-context</i> index for the Exim FAQ is generated
+automatically from the FAQ source. Browsers may not display the data very
+prettily, but it is hoped that it may provide a useful aid for finding things
+in the FAQ.
+</p>
+End
+ }
+
+ print OUT "<table border>\n";
+ $current_initial = $initial;
+ }
+
+ print OUT "<tr>\n";
+ print OUT "<td align=\"right\">$tableft{$key}</td>\n";
+ print OUT "<td align=\"left\">$tabright{$key}</td>\n";
+ print OUT "</tr>\n";
+ }
+
+# Close the final file
+
+if ($current_initial ne "")
+ {
+ print OUT "</table>\n";
+ &write_initials($current_initial);
+ print OUT "</body>\n</html>\n";
+ close OUT;
+ }
+
+# End
diff --git a/doc/doc-scripts/g2h b/doc/doc-scripts/g2h
new file mode 100755
index 000000000..e940e669b
--- /dev/null
+++ b/doc/doc-scripts/g2h
@@ -0,0 +1,1451 @@
+#! /usr/bin/perl -w
+# $Cambridge: exim/doc/doc-scripts/g2h,v 1.1 2004/10/07 15:04:35 ph10 Exp $
+
+# This is a script that turns the SGCAL source of Exim's documentation into
+# HTML. It can be used for both the filter document and the main Exim
+# specification. The syntax is
+#
+# g2h [-split no|section|chapter] <source file> <title>
+#
+# Previously, -split section was used for the filter document, and -split
+# chapter for the main specification. However, the filter document has gained
+# some chapters, so they are both split by chapter now. Only one -split can be
+# specified.
+#
+# A number of assumptions about the style of the input markup are made.
+#
+# The HTML is written into the directory html/ using the source file base
+# name as its base.
+
+# Written by Philip Hazel
+# Starting 21-Dec-2001
+# Last modified 26-Nov-2003
+
+#############################################################################
+
+
+
+##################################################
+# Open an output file #
+##################################################
+
+sub openout {
+open (OUT, ">$_[0]") || die "Can't open $_[0]\n";
+
+# Boilerplate
+
+print OUT "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">\n";
+
+print OUT "<html>\n<head>\n<title>$doctitle" .
+ (($thischapter > 0)? " chapter $thischapter" : "") .
+ (($thissection > 0)? " section $thissection" : "") .
+ "</title>\n</head>\n" .
+ "<body bgcolor=\"#F8F8F8\" text=\"#00005A\" " .
+ "link=\"#FF6600\" alink=\"#FF9933\" vlink=\"#990000\">\n";
+
+# Forward/backward links when chapter splitting
+
+if ($chapsplit)
+ {
+ print OUT "<font size=2>\n";
+ printf OUT ("<a href=\"${file_base}_%s.html\">Previous</a>&nbsp;&nbsp;\n",
+ $thischapter - 1) if $thischapter > 1;
+ printf OUT ("<a href=\"${file_base}_%s.html\">Next</a>&nbsp;&nbsp;\n",
+ $thischapter + 1) if $thischapter < $maxchapter;
+ print OUT "<a href=\"${file_base}_toc.html\">Contents</a>\n";
+ print OUT "&nbsp;" x 6, "($doctitle)\n</font><hr>\n";
+ }
+
+# Forward/backward links when section splitting
+
+elsif ($sectsplit)
+ {
+ print OUT "<font size=2>\n";
+ printf OUT ("<a href=\"${file_base}_%s.html\">Previous</a>&nbsp;&nbsp;\n",
+ $thissection - 1) if $thissection > 1;
+ printf OUT ("<a href=\"${file_base}_%s.html\">Next</a>&nbsp;&nbsp;\n",
+ $thissection + 1) if $thissection < $maxsection;
+ print OUT "<a href=\"${file_base}_toc.html\">Contents</a>\n";
+ print OUT "&nbsp;" x 6, "($doctitle)\n</font><hr>\n";
+ }
+
+# Save the final component of the current file name (for TOC creation)
+
+$_[0] =~ /^(?:.*)\/([^\/]+)$/;
+$current_file = $1;
+}
+
+
+
+##################################################
+# Close an output file #
+##################################################
+
+# The first argument is one of:
+#
+# "CHAP" a chapter is ending
+# "SECT" a section is ending
+# "" the whole thing is ending
+#
+# In the first two cases $thischapter and $thissection contain the new chapter
+# and section numbers, respectively. In the third case, we can deduce what is
+# ending from the flags. The variables contain the current values.
+
+sub closeout {
+my($s) = $_[0];
+
+print OUT "<hr>\n" if !$lastwasrule;
+&setpar(0);
+
+if ($s eq "CHAP")
+ {
+ print OUT "<font size=2>\n";
+ printf OUT ("<a href=\"${file_base}_%s.html\">Previous</a>&nbsp;&nbsp;",
+ $thischapter - 2) if ($thischapter > 2);
+ print OUT "<a href=\"${file_base}_$thischapter.html\">Next</a>&nbsp;&nbsp;";
+ print OUT "<a href=\"${file_base}_toc.html\">Contents</a>\n";
+ print OUT "&nbsp;" x 6, "($doctitle)\n</font>\n";
+ }
+
+elsif ($s eq "SECT")
+ {
+ print OUT "<font size=2>\n";
+ printf OUT ("<a href=\"${file_base}_%s.html\">Previous</a>&nbsp;&nbsp;",
+ $thissection - 2) if ($thissection > 2);
+ print OUT "<a href=\"${file_base}_$thissection.html\">Next</a>&nbsp;&nbsp;";
+ print OUT "<a href=\"${file_base}_toc.html\">Contents</a>\n";
+ print OUT "&nbsp;" x 6, "($doctitle)\n</font>\n";
+ }
+
+else
+ {
+ if ($chapsplit)
+ {
+ print OUT "<font size=2>\n";
+ printf OUT ("<a href=\"${file_base}_%s.html\">Previous</a>&nbsp;&nbsp;",
+ $thischapter - 1) if ($thischapter > 1);
+ print OUT "<a href=\"${file_base}_toc.html\">Contents</a>\n";
+ print OUT "&nbsp;" x 6, "($doctitle)\n</font>\n";
+ }
+ elsif ($sectsplit)
+ {
+ print OUT "<font size=2>\n";
+ printf OUT ("<a href=\"${file_base}_%s.html\">Previous</a>&nbsp;&nbsp;",
+ $thissection - 1) if ($thissection > 1);
+ print OUT "<a href=\"${file_base}_toc.html\">Contents</a>\n";
+ print OUT "&nbsp;" x 6, "($doctitle)\n</font>\n";
+ }
+ }
+
+print OUT "</body>\n</html>\n";
+close(OUT);
+}
+
+
+
+##################################################
+# Handle an index line #
+##################################################
+
+# This function returns an empty string so that it can be called as part
+# of an s operator when handling index items within paragraphs. The two
+# arguments are:
+#
+# the text to index, already converted to HTML
+# 1 for the concept index, 0 for the options index
+
+sub handle_index {
+my($text) = $_[0];
+my($hash) = $_[1]? \%cindex : \%oindex;
+my ($key,$ref);
+
+# Up the index count, and compute the reference to the file and the
+# label within it.
+
+$index_count++;
+$ref = $chapsplit?
+ "${file_base}_$thischapter.html#IX$index_count"
+ : $sectsplit?
+ "${file_base}_$thissection.html#IX$index_count"
+ :
+ "#IX$index_count";
+
+# Create the index key, which consists of the text with all the HTML
+# coding and any leading quotation marks removed. Turn the primary/secondary
+# splitting string "||" into ":".
+
+$text =~ s/\|\|/:/g;
+
+$key = "$text";
+$key =~ s/<[^>]+>//g;
+$key =~ s/&#(\d+);/chr($1)/eg;
+$key =~ s/^`+//;
+
+# Turn all spaces in the text into &nbsp; so that they don't ever split.
+# However, there may be spaces in the HTML that already exists in the
+# text, so we have to avoid changing spaces inside <>.
+
+$text =~ s/ (?=[^<>]*(?:<|$))/&nbsp;/g;
+
+# If this is the first encounter with this index key, we create a
+# straightforward reference.
+
+if (!defined $$hash{$key})
+ {
+ $$hash{$key} = "<a href=\"$ref\">$text</a>";
+ }
+
+# For the second and subsequent encounters, add "[2]" etc. to the
+# index text. We find out the number by counting occurrences of "<a"
+# in the existing string.
+
+else
+ {
+ my($number) = 1;
+ $number++ while $$hash{$key} =~ /<a/g;
+ $$hash{$key} .= " &nbsp;<a href=\"$ref\">[$number]</a>";
+ }
+
+# Place the name in the current output
+
+print OUT "<a name=\"IX$index_count\"></a>\n";
+return "";
+}
+
+
+
+##################################################
+# Handle emphasis bars #
+##################################################
+
+# Set colour green for text marked with "emphasis bars", keeping
+# track in case the matching isn't perfect.
+
+sub setinem {
+if ($_[0])
+ {
+ return "" if $inem;
+ $inem = 1;
+ return "<font color=green>\n";
+ }
+else
+ {
+ return "" if !$inem;
+ $inem = 0;
+ return "</font>\n";
+ }
+}
+
+
+
+##################################################
+# Convert marked-up text #
+##################################################
+
+# This function converts text from SGCAL markup to HTML markup, with a couple
+# of exceptions:
+#
+# 1. We don't touch $t because that is handled by the .display code.
+#
+# 2. The text may contain embedded .index, .em, and .nem directives. We
+# handle .em and .nem, but leave .index because it must be done during
+# paragraph outputting.
+#
+# In a non-"rm" display, we turn $rm{ into cancelling of <tt>. Otherwise
+# it is ignored - in practice it is only used in that special case.
+#
+# The order in which things are done in this function is highly sensitive!
+
+sub handle_text {
+my($s) = $_[0];
+my($rmspecial) = $_[1];
+
+# Escape all & characters (they aren't involved in markup) but for the moment
+# use &+ instead of &# so that we can handle # characters in the text.
+
+$s =~ s/&/&+038;/g;
+
+# Turn SGCAL literals into HTML literals that don't look like SGCAL
+# markup, so won't be touched by what follows. Again, use + instead of #.
+
+$s =~ s/@@/&+064;/g;
+$s =~ s/@([^@])/"&+".sprintf("%0.3d",ord($1)).";"/eg;
+
+# Now turn any #s that are markup into spaces, and convert the previously
+# created literals to the correct form.
+
+$s =~ s/#/&nbsp;/g;
+$s =~ s/&\+(\d+);/&#$1;/g;
+
+# Some simple markup that doesn't involve argument text.
+
+$s =~ s/\$~//g; # turn $~ into nothing
+$s =~ s/__/_/g; # turn __ into _
+$s =~ s/--(?=$|\s|\d)/&#150;/mg; # turn -- into endash in text or number range
+$s =~ s/\(c\)/&copy;/g; # turn (c) into copyright symbol
+
+# Use double quotes
+
+# $s =~ s/`([^']+)'/``$1''/g;
+
+$s =~ s/`([^']+)'/&#147;$1&#148;/g;
+
+# This is a fudge for some specific usages of $<; can't just do a global
+# is it occurs in things like "$<variable name>" as well.
+
+$s =~ s/(\d)\$<-/$1-/g; # turn 0$<- into 0-
+$s =~ s/\$<//g; # other $< is ignored
+
+# Turn <<...>> into equivalent SGCAL markup that doesn't involve the use of
+# < and >, and then escape the remaining < and > characters in the text.
+
+$s =~ s/<<([^>]*?)>>/<\$it{$1}>/g; # turn <<xxx>> into <$it{xxx}>
+$s =~ s/</&#060;/g;
+$s =~ s/>/&#062;/g;
+
+# Other markup...
+
+$s =~ s/\$sm\{//g; # turn $sm{ into nothing
+$s =~ s/\$smc\{//g; # turn $smc{ into nothing
+$s =~ s/\$smi\{//g; # turn $smi{ into nothing
+
+$s =~ s/\$tt\{([^\}]*?)\}/<tt>$1<\/tt>/g; # turn $tt{xxx} into <tt>xxx</tt>
+$s =~ s/\$it\{([^\}]*?)\}/<em>$1<\/em>/g; # turn $it{xxx} into <em>xxx</em>
+$s =~ s/\$bf\{([^\}]*?)\}/<b>$1<\/b>/g; # turn $bf{xxx} into <b>xxx</b>
+
+$s =~ s/\$cb\{([^\}]*?)\}/<tt><b>$1<\/b><\/tt>/g; # turn $cb{xxx} into
+ # <tt><b>xxx</b></tt>
+
+$s =~ s/\\\\([^\\]*?)\\\\/<font size=-1>$1<\/font>/g; # turn \\xxx\\ into
+ # small font
+$s =~ s/\\\?([^?]*?)\?\\/<a href="$1">$1<\/a>/g; # turn \?URL?\ into URL
+
+$s =~ s/\\\(([^)]*?)\)\\/<i>$1<\/i>/g; # turn \(xxx)\ into <i>xxx</i>
+$s =~ s/\\\"([^\"]*?)\"\\/<tt>$1<\/tt>/g; # turn \"xxx"\ into <tt>xxx</tt>
+
+
+$s =~ s/\\\$([^\$]*?)\$\\/<tt>\$$1<\/tt>/g; # turn \$xxx$\ into <tt>$xxx</tt>
+$s =~ s/\\\-([^\\]*?)\-\\/<i>-$1<\/i>/g; # turn \-xxx-\ into -italic
+$s =~ s/\\\*\*([^*]*?)\*\*\\/<b>$1<\/b>/g; # turn \**xxx**\ into <b>xxx</b>
+$s =~ s/\\\*([^*]*?)\*\\/<i>$1<\/i>/g; # turn \*xxx*\ into italic
+$s =~ s/\\%([^*]*?)%\\/<b>$1<\/b>/g; # turn \%xxx%\ into bold
+$s =~ s/\\([^\\]*?)\\/<tt>$1<\/tt>/g; # turn \xxx\ into <tt>xxx</tt>
+$s =~ s/::([^\$]*?)::/<i>$1:<\/i>/g; # turn ::xxx:: into italic:
+$s =~ s/\$\*\$/\*/g; # turn $*$ into *
+
+# Handle $rm{...}
+
+if ($rmspecial)
+ {
+ $s =~ s/\$rm\{([^\}]*?)\}/<\/tt>$1<tt>/g; # turn $rm{xxx} into </tt>xxx<tt>
+ }
+else
+ {
+ $s =~ s/\$rm\{([^\}]*?)\}/$1/g; # turn $rm{xxx} into xxx
+ }
+
+# There is one case where the terminating } of an escape sequence is
+# in another paragraph - this follows $sm{ - it can be fixed by
+# removing any stray } in a paragraph that contains no { chars.
+
+$s =~ s/\}//g if !/\{/;
+
+# Remove any null flags ($$)
+
+$s =~ s/\$\$//g;
+
+# If the paragraph starts with $c\b, remove it.
+
+$s =~ s/^\$c\b//;
+
+# If the paragraph starts with $e\b, indent it slightly.
+
+$s =~ s/^\$e\b/&nbsp;&nbsp;/;
+
+# Handle .em, and .nem directives that occur within the paragraph
+
+$s =~ s/\.em\s*\n/&setinem(1)/eg;
+$s =~ s/\.nem\s*\n/&setinem(0)/eg;
+
+# Explicitly included HTML
+
+$s =~ s/\[\(([^)]+)\)\]/<$1>/g; # turn [(...)] into <...>
+
+# Finally, do the substitutions and return the modified text.
+
+$s =~ s/~~(\w+)/$var_value{$1}/eg;
+
+return $s;
+}
+
+
+
+##################################################
+# Start/end a paragraph #
+##################################################
+
+# We want to leave paragraphs unterminated until we know that a horizontal
+# rule does not follow, to avoid getting space inserted before the rule,
+# which doesn't look good. So we have this function to help control things.
+# If the argument is 1 we are starting a new paragraph; if it is 0 we want
+# to force the ending of any incomplete paragraph.
+
+sub setpar {
+if ($inpar)
+ {
+ print OUT "</p>\n";
+ $inpar = 0;
+ }
+if ($_[0])
+ {
+ print OUT "<p>\n";
+ $inpar = 1;
+ }
+}
+
+
+
+##################################################
+# Handle a "paragraph" #
+##################################################
+
+# Read a paragraph of text, which may contain many lines and may contain
+# .index, .em, and .nem directives within it. We may also encounter
+# ".if ~~html" within paragraphs. Process those directives,
+# convert the markup, and output the rest as an HTML paragraph.
+
+
+sub handle_paragraph{
+my($par) = $_;
+my($htmlcond) = 0;
+while(<IN>)
+ {
+ if (/^\.if\s+~~html\b/)
+ {
+ $htmlcond = 1;
+ $par =~ s/\s+$//; # lose unwanted whitespace and newlines
+ next;
+ }
+ elsif ($htmlcond && /^\.else\b/)
+ {
+ while (<IN>) { last if /^\.fi\b/; }
+ $htmlcond = 0;
+ next;
+ }
+ elsif ($htmlcond && /^\.fi\b/)
+ {
+ $htmlcond = 0;
+ next;
+ }
+
+ last if /^\s*$/ || (/^\./ && !/^\.index\b/ && !/^\.em\b/ && !/^\.nem\b/);
+ $par .= $_;
+ }
+$par = &handle_text($par, 0);
+
+# We can't handle .index until this point, when we do it just before
+# outputting the paragraph.
+
+if ($par !~ /^\s*$/)
+ {
+ &setpar(1);
+ $par =~ s/\.index\s+([^\n]+)\n/&handle_index($1, 1)/eg;
+ print OUT "$par";
+ }
+}
+
+
+
+##################################################
+# Handle a non-paragraph directive #
+##################################################
+
+# The directives .index, .em, and .nem can also appear within paragraphs,
+# and are then handled within the handle_paragraph() code.
+
+sub handle_directive{
+my($new_lastwasitem) = 0;
+
+$lastwasrule = 0;
+
+if (/^\.r?set\b/ || /^\.(?:\s|$)/) {} # ignore .(r)set and comments
+
+elsif (/^\.justify\b/) {} # and .justify
+
+elsif (/^\.newline\b/) { print OUT "<br>\n"; }
+
+elsif (/^\.blank\b/ || /^\.space\b/) { print OUT "<br>\n"; }
+
+elsif (/^\.rule\b/) { &setpar(0); print OUT "<hr>\n"; $lastwasrule = 1; }
+
+elsif (/^\.index\s+(.*)/) { &handle_index(&handle_text($1), 1); }
+
+# Emphasis is handled by colour
+
+elsif (/^\.em\b/)
+ {
+ &setpar(0);
+ print OUT "<font color=green>" if ! $inem;
+ $inem = 1;
+ }
+
+elsif (/^\.nem\b/)
+ {
+ &setpar(0);
+ print OUT "</font>" if $inem;
+ $inem = 0;
+ }
+
+# Ignore tab setting stuff - we use tables instead.
+
+elsif (/^\.tabs(?:et)?\b/) {}
+
+# .tempindent is used only to align some of the expansion stuff nicely;
+# just ignore it. It is used in conjunction with .push/.pop.
+
+elsif (/^\.(tempindent|push|pop)\b/) {}
+
+# There are some instances of .if ~~sys.fancy in the source. Some of those
+# that are not inside displays are two-part things, in which case we just keep
+# the non-fancy part. For diagrams, however, they are in three parts:
+#
+# .if ~~sys.fancy
+# <aspic drawing stuff for PostScript and PDF>
+# .elif !~~html
+# <ascii art for txt and Texinfo>
+# .else
+# <HTML instructions for including a gif>
+# .fi
+#
+# In this case, we skip to the third part.
+
+elsif (/^\.if\s+~~sys\.fancy/ || /^\.else\b/)
+ {
+ while (<IN>)
+ { last if /^\.else\b/ || /^\.elif\s+!\s*~~html/ || /^\.fi\b/; }
+
+ if (/^\.elif\b/)
+ {
+ while (<IN>) { last if /^\.else\b/ || /^\.fi\b/; }
+ }
+ }
+
+# Similarly, for .if !~~sys.fancy, take the non-fancy part.
+
+elsif (/^\.if\s+!\s*~~sys.fancy/) {}
+
+# There are some explicit tests for ~~html for direct HTML inclusions
+
+elsif (/^\.if\s+~~html\b/) {}
+
+# There are occasional requirements to do things differently for Texinfo/HTML
+# and PS/txt versions. The latter are produced by SGCAL, so that's what the
+# flag is called.
+
+elsif (/\.if\s+~~sgcal/)
+ {
+ while (<IN>) { last if /\.else\b/ || /\.fi\b/; }
+ }
+
+# Also there is a texinfo flag
+
+elsif (/^\.if\s+~~texinfo\b/)
+ {
+ while (<IN>)
+ { last if /^\.else\b/ || /^\.elif\s+!\s*~~html/ || /^\.fi\b/; }
+ }
+
+# Ignore any other .if, .else, or .fi directives
+
+elsif (/^\.if\b/ || /^\.fi\b/ || /^\.else\b/) {}
+
+# Ignore .indent
+
+elsif (/^\.indent\b/) {}
+
+# Various flavours of numberpars map to corresponding list types.
+
+elsif (/^\.numberpars\b/)
+ {
+ $rest = $';
+ &setpar(0);
+
+ if ($rest =~ /(?:\$\.|\" \")/)
+ {
+ unshift @endlist, "ul";
+ unshift @listtype, "";
+ print OUT "<ul>\n<li>";
+ }
+ else
+ {
+ $nptype = ($rest =~ /roman/)? "a" : "1";
+ unshift @endlist, "ol";
+ unshift @listtype, " TYPE=\"$nptype\"";
+ print OUT "<ol>\n<li$listtype[0]>";
+ }
+ }
+
+elsif (/^\.nextp\b/)
+ {
+ &setpar(0);
+ print OUT "</li>\n<li$listtype[0]>";
+ }
+
+elsif (/^\.endp\b/)
+ {
+ &setpar(0);
+ print OUT "</li>\n</$endlist[0]>\n";
+ shift @listtype;
+ shift @endlist;
+ }
+
+# .display asis can use <pre> which uses a typewriter font.
+# Otherwise, we have to do our own line breaking. Turn tabbed lines
+# into an HTML table. There will always be a .tabs line first.
+
+elsif (/^\.display\b/)
+ {
+ my($intable) = 0;
+ my($asis) = /asis/;
+ my($rm) = /rm/;
+ my($eol,$indent);
+
+ # For non asis displays, start a paragraph, and set up to put an
+ # explicit break after every line.
+
+ if (!$asis)
+ {
+ &setpar(1);
+ $eol = "<br>";
+ $indent = "<tt>&nbsp;&nbsp;</tt>";
+ }
+
+ # For asis displays, use <pre> and no explicit breaks
+
+ else
+ {
+ print OUT "<pre>\n";
+ $eol = "";
+ $indent = "&nbsp;&nbsp;";
+ }
+
+ # Now read through until we hit .endd (or EOF, but that shouldn't happen)
+ # and process the lines in the display.
+
+ while (<IN>)
+ {
+ last if /^\.endd\b/;
+
+ # The presence of .tabs[et] starts a table
+
+ if (/^\.tabs/)
+ {
+ $intable = 1;
+ print OUT "<table cellspacing=0 cellpadding=0>\n";
+ }
+
+ # Some displays have an indent setting - ignore
+
+ elsif (/^\.indent\b/) {}
+
+ # Some displays have .blank inside them
+
+ elsif (/^\.blank\b/)
+ {
+ print OUT "<br>\n";
+ }
+
+ # Some displays have emphasis inside them
+
+ elsif (/^\.em\b/)
+ {
+ print OUT "<font color=green>" if ! $inem;
+ $inem = 1;
+ }
+
+ elsif (/^\.nem\b/)
+ {
+ print OUT "</font>" if $inem;
+ $inem = 0;
+ }
+
+ # There are occasional instances of .if [!]~~sys.fancy inside displays.
+ # In both cases we want the non-fancy alternative. (The only thing that
+ # matters in practice is noticing .tabs[et] actually.) Assume the syntax
+ # is valid.
+
+ elsif (/^\.if\s+~~sys.fancy/ || /^\.else\b/)
+ {
+ while (<IN>)
+ {
+ last if /^\.fi\b/ || /^\.else/;
+ }
+ }
+
+ elsif (/^\.if\s+!\s*~~sys.fancy/) {}
+
+ elsif (/^\.fi\b/) {}
+
+ # Ignore .newline and .linelength
+
+ elsif (/^\.newline\b/ || /^\.linelength\b/) {}
+
+ # Ignore comments
+
+ elsif (/^\.(\s|$)/) {}
+
+ # There shouldn't be any other directives inside displays
+
+ elsif (/^\./)
+ {
+ print "*** Ignored directive inside .display: $_";
+ }
+
+ # Handle a data line within a display. If it's an asis display, the only
+ # conversion is to escape the HTML characters. Otherwise, process the
+ # SGCAL markup.
+
+ else
+ {
+ chomp;
+ if ($asis)
+ {
+ s/&/&#038;/g;
+ s/</&#060;/g;
+ s/>/&#062;/g;
+ }
+ else
+ {
+ $_ = &handle_text($_, !$rm);
+ $_ = "<tt>$_</tt>" if !$rm && $_ ne "";
+ }
+
+ # In a table, break fields at $t. For non-rm we must break the
+ # <tt> group as well.
+
+ if ($intable)
+ {
+ if ($rm)
+ {
+ s/\s*\$t\s*/&nbsp;&nbsp;<\/td><td>/g;
+ }
+ else
+ {
+ s/\s*\$t\s*/&nbsp;&nbsp;<\/tt><\/td><td><tt>/g;
+ }
+ s/<tt><\/tt>//g;
+ print OUT "<tr><td>&nbsp;&nbsp;$_</td></tr>\n";
+ }
+
+ # Otherwise, output straight, with <br> for non asis displays
+
+ else
+ {
+ s/<tt><\/tt>//g;
+ print OUT "$indent$_$eol\n";
+ }
+ }
+ } # Loop for display contents
+
+ # Finish off the table and the <pre> - leave a paragraph open
+
+ print OUT "</table>\n" if $intable;
+ print OUT "</pre>\n" if $asis;
+ }
+
+# Handle configuration option definitions
+
+elsif (/^\.startconf\b/) {}
+
+elsif (/^\.conf\b/)
+ {
+ my($option, $type, $default) =
+ /^\.conf\s+(\S+)\s+("(?:[^"]|"")+"|\S+)\s+("(?:[^"]|"")+"|.*)/;
+
+ $option =~ s/\@_/_/g; # Underscore will be quoted in option name
+
+ # If $type ends with $**$, add ",expanded" as there doesn't seem to be
+ # a dagger character generally available.
+
+ $type =~ s/^"([^"]+)"/$1/;
+ $type =~ s/\$\*\*\$/, expanded/;
+
+ # Default may be quoted, and it may also have quotes that are required,
+ # if it is a string.
+
+ $default =~ s/^"(.*)"$/$1/;
+ $default =~ s/""/"/g;
+ $default = &handle_text($default, 0);
+
+ print OUT "<hr>";
+ &setpar(0);
+ &handle_index($option, 0);
+ print OUT "<h3>$option</h3>\n" .
+ "<i>Type:</i>&nbsp; $type<br><i>Default:</i>&nbsp; $default<br>\n";
+ }
+
+elsif (/^\.endconf\b/)
+ {
+ print OUT "<hr><br>\n";
+ }
+
+
+# Handle "items" - used for expansion items and the like. We force the
+# item text into bold, and put a rule between items.
+
+elsif (/^\.startitems\b/) {}
+
+elsif (/^\.item\s+(.*)/)
+ {
+ my($arg) = $1;
+ chomp($arg);
+ $arg =~ s/^"(.*)"$/$1/;
+ $arg = &handle_text($arg, 0);
+
+ # If there are two .items in a row, we don't want to put in the
+ # separator line or start a new paragraph.
+
+ if ($lastwasitem)
+ {
+ print OUT "<br>";
+ }
+ else
+ {
+ print OUT "<hr>";
+ &setpar(1);
+ }
+ print OUT "<b>$arg</b>\n";
+ $new_lastwasitem = 1;
+ }
+
+elsif (/^\.enditems\b/)
+ {
+ print OUT "<hr><br>\n";
+ }
+
+
+# Handle command line option items
+
+elsif (/^\.startoptions\b/) {}
+
+elsif (/^\.option\s+(.*)/)
+ {
+ my($arg) = $1;
+ $arg =~ s/^"(.*)"$/$1/;
+
+ print OUT "<hr>";
+ &setpar(0);
+
+ # For indexing, we want to take up to the first # or < in the line,
+ # before processing.
+
+ my($name) = $arg =~ /^([^#<]+)/;
+ $name = &handle_text($name, 0);
+ &handle_index("-$name", 0);
+
+ # Output as heading, after the index
+
+ $arg = &handle_text($arg, 0);
+ print OUT "<h3>-$arg</h3>\n";
+ }
+
+elsif (/^\.endoptions\b/)
+ {
+ print OUT "<hr><br>\n";
+ }
+
+# Found an SGCAL directive that isn't dealt with. Oh dear.
+
+else
+ {
+ print "*** Unexpected SGCAL directive: line $. ignored:\n";
+ print "$_\n";
+ }
+
+# Remember if last was a .item, and read the next line
+
+$lastwasitem = $new_lastwasitem;
+$_ = <IN>;
+}
+
+
+
+##################################################
+# First Pass - collect references #
+##################################################
+
+sub pass_one{
+$thischapter = 0;
+
+open (IN, $source_file) || die "Can't open $source_file (first pass)\n";
+$_ = <IN>;
+
+# At the start of the specification text, there are some textual replacement
+# definitions. They set values, but not cross-references.
+
+while (/^\.r?set\s+(\S+)\s+"?([^"]+)\"?\s*$/)
+ {
+ $var_value{$1} = $2;
+ $_ = <IN>;
+ }
+
+# Now skip on till we hit the start of the first chapter. It will be numbered
+# 0 if we hit ".set chapter -1". There is only ever one unnumbered chapter.
+
+while (!/^\.chapter/)
+ {
+ $thischapter = -1 if /^\.set\s+chapter\s+-1/;
+ $_ = <IN>;
+ }
+
+# Loop for handling chapters
+
+while ($_)
+ {
+ $thischapter++;
+ $thissection = 0;
+
+ # Scan through chapter, setting up cross-references to the chapter
+ # and to the sections within it.
+
+ while (<IN>)
+ {
+ last if /^\.chapter/;
+ chomp;
+
+ if (/^\.section/)
+ {
+ $thissection++;
+ next;
+ }
+
+ # Handle .(r)set directives.
+
+ if (/^\.r?set\s+(\S+)\s+"?([^"]+)\"?\s*$/ && $1 ne "runningfoot")
+ {
+ my($key,$value) = ($1,$2);
+ $value =~ s/~~chapter/$thischapter/e;
+ $value =~ s/~~section/$thissection/e;
+
+ # Only one of $chapsplit or $sectsplit can be set.
+
+ if ($key =~ /^CHAP/)
+ {
+ $value = $chapsplit?
+ "<a href=\"${file_base}_$thischapter.html\">$value</a>"
+ :
+ "<a href=\"#CHAP$thischapter\">$value</a>";
+ }
+
+ elsif ($key =~ /^SECT/)
+ {
+ $value = $chapsplit?
+ "<a href=\"${file_base}_$thischapter.html" .
+ "#SECT$thischapter.$thissection\">$value</a>"
+ :
+ $sectsplit? "<a href=\"${file_base}_$thissection.html\">$value</a>"
+ :
+ "<a href=\"#SECT$thischapter.$thissection\">$value</a>";
+ }
+
+ $var_value{$key} = $value;
+ }
+ }
+ }
+
+close(IN);
+}
+
+
+
+
+
+##################################################
+# Second Pass - generate HTML #
+##################################################
+
+sub pass_two{
+my($tocn) = 0;
+my($inmacro) = 0;
+my($insection) = 0;
+
+$inem = 0;
+$thischapter = 0;
+$thissection = 0;
+
+# Open the source file and get the first line
+
+open (IN, $source_file) || die "Can't open $source_file (2nd pass)\n";
+$_ = <IN>;
+
+# Skip on till we hit the start of the first chapter, but note if we
+# pass ".set chapter -1", which is used to indicate no chapter numbering for
+# the first chapter (we number is 0). Keep track of whether we are in macro
+# definitions or not, and when not, notice occurrences of .index, because this
+# are the "x see y" type entries.
+
+while (!/^\.chapter/)
+ {
+ $thischapter = -1 if /^\.set\s+chapter\s+-1/;
+ $inmacro = 1 if /^\.macro/;
+ $inmacro = 0 if /^\.endm/;
+ if (!$inmacro && /^\.index\s+(.*)/)
+ {
+ my($key);
+ my($s) = $1;
+ $s = &handle_text($s, 0);
+ $s =~ s/ /&nbsp;/g; # All spaces unsplittable
+ $key = "\L$s";
+ $key =~ s/<[^>]+>//g;
+ $key =~ s/&#(\d+);/chr($1)/eg;
+ $cindex{$key} = $s;
+ }
+ $_ = <IN>;
+ }
+
+# Open the TOC file
+
+open (TOC, ">$html/${file_base}_toc.html") ||
+ die "Can't open $html/${file_base}_toc.html\n";
+
+print TOC "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">\n";
+print TOC "<html>\n<head>\n<title>$doctitle Contents</title>\n</head>\n" .
+ "<body bgcolor=\"#F8F8F8\" text=\"#00005A\" " .
+ "link=\"#FF6600\" alink=\"#FF9933\" vlink=\"#990000\">\n";
+print TOC "<h1>$doctitle</h1><hr>\n<ul>\n";
+
+# Open the data file if we are not splitting at chapters
+
+&openout("$html/${file_base}.html") if !$chapsplit;
+
+# Loop for handling chapters. At the start of this loop, $_ is either EOF,
+# or contains a .chapter line.
+
+$firstchapter = $thischapter + 1;
+
+while ($_)
+ {
+ print TOC "</ul>\n" if $insection;
+ $insection = 0;
+
+ $thischapter++;
+ $thissection = 0;
+ $lastwasrule = 0;
+
+ # Start a new file if required
+
+ if ($chapsplit)
+ {
+ &closeout("CHAP") if $thischapter != $firstchapter;
+ &openout("$html/${file_base}_$thischapter.html");
+ }
+
+ # Set up the chapter title. Save it for the TOC. Set up the anchor and
+ # link back to the TOC and show the title.
+
+ $_ =~ /^\.chapter\s+(.*)/;
+
+ my($title) = (($thischapter > 0)? "$thischapter. " : "") . &handle_text($1, 0);
+
+ $tocn++;
+ print TOC "<li><a " .
+ "name=\"TOC$tocn\" " .
+ "href=\"$current_file#CHAP$thischapter\">$title</a></li>\n";
+
+ print OUT "<h1>\n";
+ print OUT "<a name=\"CHAP$thischapter\" href=\"${file_base}_toc.html#TOC$tocn\">\n";
+ print OUT "$title\n</a></h1>\n";
+
+ # Scan the contents of the chapter
+
+ $_ = <IN>;
+ while ($_)
+ {
+ last if /^\.chapter/;
+
+ # Handle the start of a new section, starting a new file if required
+
+ if (/^\.section\s+(.*)/)
+ {
+ $thissection++;
+
+ print TOC "<ul>\n" if !$insection;
+ $insection = 1;
+
+ my($title) = (($thischapter > 0)? "$thischapter." : "") .
+ "$thissection. " . &handle_text($1, 0);
+
+ if ($sectsplit)
+ {
+ &closeout("SECT");
+ &openout("$html/${file_base}_$thissection.html");
+ }
+
+ $tocn++;
+ printf TOC ("<li><a " .
+ "name=\"TOC$tocn\" " .
+ "href=\"$current_file#SECT%s$thissection\">%s</a></li>\n",
+ ($thischapter > 0)? "$thischapter." : "", $title);
+
+ &setpar(0);
+ print OUT "<h2>\n";
+ printf OUT ("<a name=\"SECT%s$thissection\" ",
+ ($thischapter > 0)? "$thischapter." : "");
+ print OUT "href=\"${file_base}_toc.html#TOC$tocn\">\n";
+ print OUT "$title\n</a></h2>\n";
+ $_ = <IN>;
+ $lastwasrule = 0;
+ }
+
+ # Blank lines at this level are ignored
+
+ elsif (/^\s*$/)
+ {
+ $_ = <IN>;
+ }
+
+ # Directive and non-directive lines are handled independently, though
+ # in each case further lines may be read. Afterwards, the next line is
+ # in $_. If .em is at the start of a paragraph, treat it with the
+ # paragraph, because the matching .nem will be too. Messy!
+
+ elsif (/^\./)
+ {
+ if (/^\.em\b/)
+ {
+ $_=<IN>;
+ if (/^\./)
+ {
+ print OUT "<font color=green>" if ! $inem;
+ $inem = 1;
+ # Used to handle it here - but that fails if it is .section.
+ # Just let the next iteration of the loop handle it.
+ # &handle_directive();
+ }
+
+ else
+ {
+ $_ = ".em\n" . $_;
+ &handle_paragraph();
+ $lastwasrule = 0;
+ $lastwasitem = 0;
+ }
+ }
+
+ # Not .em
+
+ else
+ {
+ &handle_directive();
+ }
+ }
+
+ # Not a directive
+
+ else
+ {
+ &handle_paragraph();
+ $lastwasrule = 0;
+ $lastwasitem = 0;
+ }
+
+ } # Loop for each line in a chapter
+ } # Loop for each chapter
+
+# Close the last file, end off the TOC, and we are done.
+
+&closeout("");
+
+print TOC "</ul>\n" if $insection;
+
+if (defined %cindex)
+ {
+ $cindex_tocn = ++$tocn;
+ print TOC "<li><a name=\"TOC$tocn\" ".
+ "href=\"${file_base}_cindex.html\">Concept Index</a></li>\n";
+ }
+
+if (defined %oindex)
+ {
+ $oindex_tocn = ++$tocn;
+ print TOC "<li><a name=\"TOC$tocn\" ".
+ "href=\"${file_base}_oindex.html\">Option Index</a></li>\n";
+ }
+
+print TOC "</ul>\n</body>\n</html>\n";
+close(TOC);
+close(IN);
+}
+
+
+
+
+##################################################
+# Adjust index points #
+##################################################
+
+# Because of the way the source is written, there are often index entries
+# that immediately follow the start of chapters and sections and the definition
+# of "items" like "helo = verify". This gets the correct page numbers for the
+# PostScript and PDF formats. However, for HTML we want the index anchor to be
+# before the section heading, because browsers tend to put the index point at
+# the top of the screen. So we re-read all the files we've just created, and
+# move some of the index points about. This is necessary only if indexes exist.
+# The files are small enough to be handled entirely in memory.
+
+sub adjust_index_points {
+print "Adjusting index points to precede headings\n";
+
+$" = "";
+
+opendir(DIR, "$html") || die "Failed to opendir $html\n";
+while ($file = readdir(DIR))
+ {
+ my($i);
+ next unless $file =~ /^${file_base}_\d+\.html$/;
+
+ open(IN, "<$html/$file") ||
+ die "Failed to open $html/$file (read)\n";
+ my(@lines) = <IN>;
+ close(IN);
+
+ for ($i = 0; $i < @lines; $i++)
+ {
+ if ($lines[$i] =~ /^<a name="IX\d+"><\/a>$/)
+ {
+ # Handle an index line that follows a heading definition. Move it back
+ # to just before the <h1> or whatever. This preserves the order of
+ # multiple index lines, not that that matters.
+
+ if ($lines[$i-1] =~ /^<\/a><\/h(\d)>/)
+ {
+ my($j);
+ my($found) = 0;
+ for ($j = $i-2; $j > 0 && $j > $i - 10; $j--)
+ {
+ if ($lines[$j] =~ /<h$1>/)
+ {
+ $found = 1;
+ last;
+ }
+ }
+ if ($found)
+ {
+ splice(@lines, $j, 0, splice(@lines, $i, 1));
+ }
+ }
+
+ # Handle an index line that follows an "item". Move it back one line.
+
+ elsif ($lines[$i-1] =~ /^<b>.*<\/b>\s*$/)
+ {
+ splice(@lines, $i-1, 0, splice(@lines, $i, 1));
+ }
+
+ # Handle an index line that follows a "conf" definition
+
+ elsif ($lines[$i-1] =~ /^<i>Type:<\/i>/ && $lines[$i-2] =~ /^<h3>/)
+ {
+ splice(@lines, $i-2, 0, splice(@lines, $i, 1));
+ }
+
+ # Handle an index line that follows an "option" definition
+
+ elsif ($lines[$i-1] =~ /^<h3>/)
+ {
+ splice(@lines, $i-1, 0, splice(@lines, $i, 1));
+ }
+ }
+ }
+
+ open(OUT, ">$html/$file") ||
+ die "Failed to open $html/$file (write)\n";
+
+ print OUT "@lines";
+ close OUT;
+ undef @lines;
+ }
+}
+
+
+
+
+##################################################
+# Create Index #
+##################################################
+
+sub create_index{
+my($hash) = $_[0];
+my($ifname) = $_[1];
+my($ititle) = $_[2];
+my(%indexindex);
+
+open(INDEX, ">$html/${file_base}_$_[1].html") ||
+ die "Failed to open $html/${file_base}_$ifname\n";
+
+print INDEX "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML//EN\">\n";
+print INDEX "<html>\n<head>\n<title>$doctitle $ititle</title>\n";
+print INDEX "<base target=\"body\">\n</head>\n";
+
+print INDEX "<body bgcolor=\"#FFFFDF\" text=\"#00005A\" " .
+ "link=\"#FF6600\" alink=\"#FF9933\" vlink=\"#990000\">\n";
+
+print INDEX "<h3>$ititle</h3>\n";
+
+# We have to scan the keys in the hash twice; first to build the list
+# of initial letters, and then to do the business. The first time we
+# do not need to sort them.
+
+foreach $key (keys %$hash)
+ {
+ my($initial) = substr($key,0,1);
+ $initial = "\U$initial";
+ $indexindex{$initial} = 1 if $initial ge "A";
+ }
+
+print INDEX "<p>\n";
+foreach $key (sort keys %indexindex)
+ {
+ print INDEX "&nbsp;<a href=\"#$key\" target=\"index\">$key</a>\n";
+ }
+print INDEX "<hr></p>\n";
+
+my($letter) = "";
+print INDEX "<p>\n";
+
+foreach $key (sort
+ { ("\L$a" eq "\L$b")? ("$a" cmp "$b") : ("\L$a" cmp "\L$b") }
+ keys %$hash)
+ {
+ my($initial) = substr($key,0,1);
+ $initial = "\U$initial";
+ if ($initial ne $letter)
+ {
+ if ($initial ge "A")
+ {
+ print INDEX "<br>\n" if $letter ne "";
+ print INDEX "<a name=\"$initial\"></a>\n";
+ print INDEX "<font size=\"+1\">\U$initial\E</font><br>\n";
+ }
+ $letter = $initial;
+ }
+ print INDEX "$$hash{$key}<br>\n";
+ }
+
+print INDEX "</p>\n";
+
+print INDEX "</body>\n</html>\n";
+close(INDEX);
+}
+
+
+
+
+##################################################
+# Show usage and die #
+##################################################
+
+sub usage {
+die "Usage: g2h [-split no|section|chapter] <source> <title>\n";
+}
+
+
+
+##################################################
+# Entry point and main program #
+##################################################
+
+
+# Directory in which to put the new HTML files
+
+$html = "html";
+
+# Global variables.
+
+%cindex = ();
+%oindex = ();
+
+$chapsplit = 0;
+$cindex_tocn = 0;
+$file_base = "";
+$index_count = 0;
+$inem = 0;
+$inpar = 0;
+$lastwasitem = 0;
+$lastwasrule = 0;
+$oindex_tocn = 0;
+$sectsplit = 0;
+$source_file = "";
+$thischapter = 0;
+$thissection = 0;
+
+
+# Handle options
+
+my($splitset) = 0;
+
+while (scalar @ARGV > 0 && $ARGV[0] =~ /^-/)
+ {
+ if ($ARGV[0] eq "-split" && !$splitset)
+ {
+ $splitset = 1;
+ shift @ARGV;
+ my($type) = shift @ARGV;
+ if ($type eq "section") { $sectsplit = 1; }
+ elsif ($type eq "chapter") { $chapsplit = 1; }
+ elsif ($type eq "no" ) { $sectsplit = $chapsplit = 0; }
+ else { &usage(); }
+ }
+ else { &usage(); }
+ }
+
+# Get the source file and its base
+
+&usage() if scalar @ARGV <= 0;
+$source_file = shift @ARGV;
+($file_base) = $source_file =~ /^(.*)\.src$/;
+
+&usage() if scalar @ARGV <= 0;
+$doctitle = shift @ARGV;
+
+print "\nCreate HTML for $doctitle from $source_file\n";
+
+# Remove the old HTML files
+
+print "Removing old HTML files\n";
+system("/bin/rm -rf $html/${file_base}_*.html");
+
+# First pass identifies all the chapters and sections, and collects the
+# values of the cross-referencing variables.
+
+print "Scanning for cross-references\n";
+&pass_one();
+
+$maxchapter = $thischapter; # Used if chapter splitting
+$maxsection = $thissection; # Used if section splitting
+
+# Second pass actually creates the HTML files.
+
+print "Creating the HTML files\n";
+&pass_two();
+
+# Reprocess for moving some of the index points, if indexes were created
+
+&adjust_index_points() if scalar(keys %cindex) > 0 || scalar(keys %oindex) > 0;
+
+# Finally, we must create the option and concept indexes if any data
+# has been collected for them.
+
+if (scalar(keys %cindex) > 0)
+ {
+ print "Creating concept index\n";
+ &create_index(\%cindex, "cindex", "Concepts");
+ }
+
+if (scalar(keys %oindex) > 0)
+ {
+ print "Creating option index\n";
+ &create_index(\%oindex, "oindex", "Options");
+ }
+
+# End of g2h
diff --git a/doc/doc-scripts/g2man b/doc/doc-scripts/g2man
new file mode 100755
index 000000000..e3006b5ec
--- /dev/null
+++ b/doc/doc-scripts/g2man
@@ -0,0 +1,251 @@
+#! /usr/bin/perl -w
+# $Cambridge: exim/doc/doc-scripts/g2man,v 1.1 2004/10/07 15:04:35 ph10 Exp $
+
+# Script to find the command line options in the Exim spec, and turn them
+# into a man page, because people like that.
+
+
+##################################################
+# De-markup one line #
+##################################################
+
+sub process {
+my($x) = $_[0];
+
+# Hide SGCAL escapes
+
+$x =~ s/\@\@/&&a/g; # @@
+$x =~ s/\@\\/&&b/g; # @\
+$x =~ s/\@</&&l/g; # @<
+$x =~ s/\@>/&&g/g; # @>
+$x =~ s/\@\{/&&c/g; # @{
+$x =~ s/\@\}/&&d/g; # @}
+$x =~ s/\@#/&&s/g; # @#
+$x =~ s/\@(.)/$1/g; # all other @s
+
+# Convert SGCAL markup
+
+$x =~ s/#/ /g; # turn # into a space
+$x =~ s/\$~//g; # turn $~ into nothing
+$x =~ s/__/_/g; # turn __ into _
+$x =~ s/\$sc\{([^\}]*?)\}/$1/g; # turn $sc{xxx} into xxx
+$x =~ s/\$st\{([^\}]*?)\}/$1/g; # turn $st{xxx} into xxx
+$x =~ s/\$si\{([^\}]*?)\}/$1/g; # turn $si{xxx} into xxx
+$x =~ s/\$tt\{([^\}]*?)\}/$1/g; # turn $tt{xxx} into xxx
+$x =~ s/\$it\{([^\}]*?)\}/$1/g; # turn $it{xxx} into xxx
+$x =~ s/\$bf\{([^\}]*?)\}/$1/g; # turn $bf{xxx} into xxx
+$x =~ s/\$rm\{([^\}]*?)\}/$1/g; # turn $rm{xxx} into xxx
+$x =~ s/\$cb\{([^\}]*?)\}/$1/g; # turn $cb{xxx} into xxx
+
+
+$x =~ s/\\\\([^\\]*?)\\\\/\U$1/g; # turn \\xxx\\ into XXX
+$x =~ s/\\\(([^)]*?)\)\\/$1/g; # turn \(xxx)\ into xxx
+$x =~ s/\\\"([^\"]*?)\"\\/$1/g; # turn \"xxx"\ into xxx
+$x =~ s/\\\%([^\%]*?)\%\\/"$1"/g; # turn \%xxx%\ into "xxx"
+
+$x =~ s/\\\?([^?]*?)\?\\/$1/g; # turn \?URL?\ into URL
+$x =~ s/<<([^>]*?)>>/<$1>/g; # turn <<xxx>> into <xxx>
+$x =~ s/\\\$([^\$]*?)\$\\/\$$1/g; # turn \$xxx$\ into $xxx
+$x =~ s/\\\-([^\\]*?)\-\\/\-$1/g; # turn \-xxx-\ into -xxx
+$x =~ s/\\\*\*([^*]*?)\*\*\\/$1/g; # turn \**xxx**\ into xxx
+$x =~ s/\[\(([\w\/]*)\)\]//g; # remove inline HTML
+
+$x =~ s/\\\*([^*]*?)\*\\/$1/g; # turn \*xxx*\ into xxx
+$x =~ s/\\([^\\]*?)\\/"$1"/g; # turn \xxx\ into "xxx"
+$x =~ s/\$\*\$/\*/g; # turn $*$ into *
+$x =~ s/\$t\b//g; # turn $t into nothing
+
+$x =~ s/::([^:]+)::/$1:/g; # turn ::xxx:: into xxx:
+
+# Put back escaped SGCAL specials
+
+$x =~ s/&&a/\@/g; # @@ => @
+$x =~ s/&&b/\\/g; # @\ => \
+$x =~ s/&&l/</g; # @< => <
+$x =~ s/&&g/>/g; # @> => >
+$x =~ s/&&c/\@{/g; # @{ => @{
+# $x =~ s/&&rc/{/g; #
+# $x =~ s/&&rd/}/g; #
+$x =~ s/&&d/\@}/g; # @} => @}
+$x =~ s/&&s/#/g; # @#
+
+# Remove any null flags ($$)
+
+$x =~ s/\$\$//g;
+
+$x;
+}
+
+
+##################################################
+# De-reference a paragraph #
+##################################################
+
+# Remove sentences or parenthetical comments that contain references.
+
+sub deref {
+my($t) = $_[0];
+
+$t =~ s/^(\n*)[^.()]+~~[^.]+\.\s*/$1/;
+$t =~ s/\s?\.[^.()]+~~[^.]+\././g;
+$t =~ s/\s?\([^~).]+~~[^)]+\)//g;
+
+$t;
+}
+
+
+##################################################
+# Quote what needs quoting #
+##################################################
+
+# This is for anything that must be quoted in the final output, independent
+# of whether it is in "asis" text or not.
+
+sub mustquote {
+my($t) = $_[0];
+$t =~ s/(?<!\\)-/\\-/g;
+
+$t;
+}
+
+
+
+##################################################
+# Main Program #
+##################################################
+
+open(IN, "spec.src") || die "Can't open spec.src\n";
+open(OUT, ">exim.8" ) || die "Can't open exim.8\n";
+
+print OUT <<End;
+.TH EXIM 8
+.SH NAME
+exim \\- a Mail Transfer Agent
+.SH SYNOPSIS
+.B exim [options] arguments ...
+.br
+.B mailq [options] arguments ...
+.br
+.B rsmtp [options] arguments ...
+.br
+.B rmail [options] arguments ...
+.br
+.B runq [options] arguments ...
+.br
+.B newaliases [options] arguments ...
+
+.SH DESCRIPTION
+Exim is a mail transfer agent (MTA) developed at the University of Cambridge.
+It is a large program with very many facilities. For a full specification, see
+the reference manual. This man page contains only a description of the command
+line options. It has been automatically generated from the reference manual
+source, which is why the formatting is poor in some places.
+
+.SH SETTING OPTIONS BY PROGRAM NAME
+.TP 10
+\\fBmailq\\fR
+Behave as if the option \\-bp were present before any other options. The \\-bp
+option requests a listing of the contents of the mail queue on the standard
+output.
+.TP
+\\fBrsmtp\\fR
+Behaves as if the option \\-bS were present before any other options, for
+compatibility with Smail. The \\-bS option is used for reading in a number of
+messages in batched SMTP format.
+.TP
+\\fBrmail\\fR
+Behave as if the \\-i and \\-oee options were present before any other options,
+for compatibility with Smail. The name \\fBrmail\\fR is used as an interface by
+some UUCP systems. The \\-i option specifies that a dot on a line by itself
+does not terminate a non\\-SMTP message; \\-oee requests that errors detected in
+non\\-SMTP messages be reported by emailing the sender.
+.TP
+\\fBrunq\\fR
+Behave as if the option \\-q were present before any other options, for
+compatibility with Smail. The \\-q option causes a single queue runner process
+to be started. It processes the queue once, then exits.
+.TP
+\\fBnewaliases\\fR
+Behave as if the option \\-bi were present before any other options, for
+compatibility with Sendmail. This option is used for rebuilding Sendmail's
+alias file. Exim does not have the concept of a single alias file, but can be
+configured to run a specified command if called with the \\-bi option.
+
+
+.SH OPTIONS
+.TP 10
+End
+
+while (<IN>) { last if /^\.startoptions/; }
+die "Can't find start of options\n" if ! defined $_;
+
+# Find the start of the first option
+
+while (<IN>) { last if /^\.option/; }
+die "Can't find start of first option\n" if ! defined $_;
+
+# Loop for each individual option
+
+while (/^\.option (.*)/)
+ {
+ $nlpending = 0;
+ $itemtext = "";
+
+ printf OUT ("\\fB\\-%s\\fR\n", &mustquote(&process($1)));
+
+ # Process the data for the option
+
+ while (<IN>)
+ {
+ last if /^\.(?:option|endoptions)/;
+ next if /^\.index/;
+ next if /^\.em\s*$/;
+ next if /^\.nem\s*$/;
+
+ if (/^\.display(?:\s+flow)?(?:\s+rm)?\s*$/)
+ {
+ print OUT &mustquote(&deref($itemtext));
+ $itemtext = "";
+ print OUT "\n";
+ while (($_ = <IN>) !~ /^\.endd/)
+ {
+ print OUT " ", &mustquote(&deref(&process($_))) if ! /^\./;
+ }
+ $nlpending = 1;
+ }
+
+ elsif (/^\.display asis\s*$/)
+ {
+ print OUT &mustquote(&deref($itemtext));
+ $itemtext = "";
+ print OUT "\n";
+ while (($_ = <IN>) !~ /^\.endd/)
+ {
+ print OUT &mustquote(" $_");
+ }
+ $nlpending = 1;
+ }
+
+ elsif (/^\s*$/)
+ {
+ print OUT &mustquote(&deref($itemtext));
+ $itemtext = "";
+ $nlpending++;
+ }
+
+ else
+ {
+ while ($nlpending > 0)
+ {
+ $itemtext .= "\n";
+ $nlpending--;
+ }
+ $itemtext .= &process($_);
+ }
+ }
+
+ print OUT &mustquote(&deref($itemtext));
+ print OUT ".TP\n";
+ }
+
+# End of g2man
diff --git a/doc/doc-scripts/g2t b/doc/doc-scripts/g2t
new file mode 100755
index 000000000..30c713c08
--- /dev/null
+++ b/doc/doc-scripts/g2t
@@ -0,0 +1,1347 @@
+#! /usr/bin/perl -w
+# $Cambridge: exim/doc/doc-scripts/g2t,v 1.1 2004/10/07 15:04:35 ph10 Exp $
+
+# A Perl script to turn the SGCAL source of the Exim documentation into
+# Texinfo input, more or less...
+
+# Supply the source file names as arguments.
+# The output goes to the standard output.
+
+
+##################################################
+# Ensure unique node name #
+##################################################
+
+# Node names must be unique. Occasionally in the Exim spec there are duplicate
+# section names, and it's become too much of a hassle to keep them distinct
+# manually. So it is now automated.
+
+########### Never really got this working. Abandoned ###############
+
+sub unique {
+my($node) = $_[0];
+if (defined $node_names{$node})
+ {
+ $node_names{$node} += 1;
+ $node = "$node ($node_names{$node})";
+
+print STDERR "+++ $node\n";
+
+ }
+else
+ {
+ $node_names{$node} = 0;
+ }
+$node;
+}
+
+
+
+##################################################
+# De-comma a node name #
+##################################################
+
+# Commas, colons, and apostrophes are not permitted in Texinfo
+# node names. I find this incredible, but it is clearly documented.
+# The Exim manual has been re-organized not to have colons or
+# apostrophes in any chapter or section titles, but I can't manage
+# without commas. This function turns "," into " and", which is
+# the best that can be done; we can use some clever Perlery to
+# just take out commas before "and".
+
+# Sigh. The Sendmail option -p<rval>:<sval> now means that there's a colon
+# in the node name for that option. Turn the colon into <colon>. This is also
+# done for menus.
+
+# Another thing that causes problems in node names in some versions of
+# Texinfo is the use of @sc{xxx} for small caps. Just turn these all into
+# real caps. This is also done for menus.
+
+sub decomma {
+$_[0] =~ s/,(?!\sand)/ and/g;
+$_[0] =~ s/,//g;
+$_[0] =~ s/\@sc\{([^}]*)\}/\U$1/g;
+$_[0] =~ s/:/<colon>/g;
+$_[0];
+}
+
+
+
+##################################################
+# De-quote a string #
+##################################################
+
+# @x is turned into x, except when x=@, or when asis is set,
+# in which case single @ must turn into @@. A single substitute
+# doesn't work in the non-asis case, because of the problems of
+# handling things like @@@$, so we do it the hard way.
+
+sub dequote {
+if ($asis) { $_[0] =~ s/@/@@/g; } else
+ {
+ $_[0] =~ s/@@/&at&/g;
+ $_[0] =~ s/@([^@])/$1/g;
+ $_[0] =~ s/&at&/@@/g;
+ }
+$_[0];
+}
+
+
+##################################################
+# Get next line #
+##################################################
+
+# Called from handle_directive, to get the next source line
+# into $_.
+
+sub get_next_line {
+if ($processing_subsection)
+ { return $_ = shift @SUBBUFFER; }
+else
+ { return $_ = <>; }
+}
+
+
+
+##################################################
+# Handle text lines #
+##################################################
+
+# This function is handed whole paragraphs, and we assume that
+# SGCAL font changing markup is always complete within a paragraph.
+# We have to replace escaped versions of significant characters with
+# some magic before performing general transformations, and then
+# put them back afterwards. The character & is not common in the text,
+# and && is unknown, so we use that.
+
+sub handle_text {
+$_ = $_[0];
+
+if ($asis)
+ {
+ $_ = dequote($_);
+ s/(\{|\})/\@$1/g;
+ return $_;
+ }
+
+while (/~~/)
+ {
+ $left = $`;
+ ($name) = $' =~ /^(\w+)/;
+ $right = $';
+
+ $value = $references{$name};
+ $value = "" if !defined($value);
+
+ if ($value =~ /\*\*\*\*/)
+ {
+ $value = ($` eq $current_chapter)? "\"$'\"" :
+ "\"$'\" in chapter \"$`\"";
+ $value = "" if $value eq "\"\"";
+ }
+ elsif ($value !~ /^[0-9]+\.[0-9]+$/) # quote unless version number
+ {
+ $value = "\"$value\"";
+ }
+
+ $_ = "${left}${value}${right}";
+ }
+
+s/\@\@/&&a/g; # @@
+s/\@\\/&&b/g; # @\
+s/\@</&&l/g; # @<
+s/\@>/&&g/g; # @>
+s/\@\{/&&c/g; # @{
+s/\@\}/&&d/g; # @}
+s/\@#/&&s/g; # @#
+
+# Now remove all other @'s
+
+$_ = dequote($_);
+
+# Convert SGCAL markup
+
+s/#/ /g; # turn # into a space
+s/\$~//g; # turn $~ into nothing
+s/__/_/g; # turn __ into _
+s/\$sm\{//g; # turn $sm{ into nothing
+s/\$sc\{([^\}]*?)\}/$1/g; # turn $sc{xxx} into xxx
+s/\$st\{([^\}]*?)\}/$1/g; # turn $st{xxx} into xxx
+s/\$si\{([^\}]*?)\}/$1/g; # turn $si{xxx} into xxx
+s/\$tt\{([^\}]*?)\}/$1/g; # turn $tt{xxx} into xxx
+
+s/\$it\{([^\}]*?)\}/$1/g; # turn $it{xxx} into xxx
+
+s/\$bf\{([^\}]*?)\}/$1/g; # turn $bf{xxx} into xxx
+s/\$rm\{([^\}]*?)\}/$1/g; # turn $rm{xxx} into xxx
+s/\$cb\{([^\}]*?)\}/$1/g; # turn $cb{xxx} into xxx
+
+# This is a fudge for some specific usages of $<; can't just do a global
+# is it occurs in things like $<variable name> as well.
+
+s/\[\$<\]/[]/g; # turn [$<] into []
+s/&&b\$<\./&&b./g; # turn \$<. into \. (\ == &&b by now)
+s/(\d)\$<-/$1-/g; # turn 0$<- into 0-
+
+# There is one case where the terminating } of an escape sequence is
+# in another paragraph - this follows $sm{ - it can be fixed by
+# removing any stray } in a paragraph that contains no { chars.
+
+s/\}//g if !/\{/;
+
+# Any remaining {} must be escaped to prevent Texinfo from complaining
+
+s/(\{|\})/\@$1/g;
+
+# Now to conversions that put {} into the file.
+# Change <<..>> from @var to just <...> as the caps that Texinfo
+# uses look far too shouty.
+
+s/\\\\([^\\]*?)\\\\/\@sc\{\L$1\}/g; # turn \\xxx\\ into @sc{xxx}
+s/\\\(([^)]*?)\)\\/\@file\{$1\}/g; # turn \(xxx)\ into @file{xxx}
+s/\\\"([^\"]*?)\"\\/\@file\{$1\}/g; # turn \"xxx"\ into @file{xxx}
+
+s/\\\?([^?]*?)\?\\/$1/g; # turn \?URL?\ into URL
+s/<<([^>]*?)>>/<$1>/g; # turn <<xxx>> into <xxx>
+s/\\\$([^\$]*?)\$\\/\$$1/g; # turn \$xxx$\ into $xxx
+s/\\\-([^-]*?)\-\\/\-$1/g; # turn \-xxx-\ into -xxx
+s/\\\*\*([^*]*?)\*\*\\/$1/g; # turn \**xxx**\ into xxx
+s/\[\(([\w\/]*)\)\]//g; # remove inline HTML
+
+s/\\\*([^*]*?)\*\\/\@dfn\{$1\}/g; # turn \*xxx*\ into @dfn{xxx}
+s/\\%([^*]*?)%\\/\@dfn\{$1\}/g; # turn \%xxx%\ into @dfn{xxx}
+s/:::([^:]*?)::/\@dfn\{:$1:\}/g; # turn :::xxx:: into @dfn{:xxx:}
+s/::([^:]*?)::/\@dfn\{$1:\}/g; # turn ::xxx:: into @dfn{xxx:}
+s/\\([^\\]*?)\\/\@dfn\{$1\}/g; # turn \xxx\ into @dfn{xxx}
+s/\$\*\$/\*/g; # turn $*$ into *
+
+# Put back escaped SGCAL specials
+
+s/&&a/\@\@/g;
+s/&&b/\\/g;
+s/&&l/</g;
+s/&&g/>/g;
+s/&&c/\@{/g;
+s/&&rc/{/g;
+s/&&rd/}/g;
+s/&&d/\@}/g;
+s/&&s/#/g;
+
+# Remove any null flags ($$)
+
+s/\$\$//g;
+
+# If the paragraph starts with $c\b, change this into @center. Assume
+# we don't ever get two of these in a row.
+
+s/^\$c\b/\@center /;
+
+# If the paragraph starts with $e\b, stuff some tabs in there, as
+# Texinfo can't do this on its own (as far as I can see). They must
+# tabs; Texinfo treats them as different to spaces. Sigh.
+
+s/^\$e\b/\t\t\t\t\t\t\t/;
+
+# Handle $t. The Exim spec only ever has one tab per line. Er, not
+# quite true, but a good enough assumption. $t is always followed
+# by a non-word character.
+
+# The .tabs directive has stashed the value in the $tab variable.
+# Don't count Texinfo font chars.
+
+while (/(^|.+?\n)(.+?)\$t(\W.*\n)/)
+ {
+ $before = $` . $1;
+ $after = $';
+ $left = $2;
+ $right = $3;
+
+ $left =~ s/\s$//;
+ $right =~ s/^\s+//;
+
+ $plainleft = $left;
+ $plainleft =~ s/\@[a-z]+\{([^}]+?)\}/$1/g;
+ $plainleft =~ s/\@//g;
+
+ $_ = $before . $left . (" " x ($tab - length($plainleft))) . $right . $after;
+
+ # Fudge for the one case where there are two tabs
+
+ if ($tab2 != 0)
+ {
+ $temp = $tab;
+ $tab = $tab2;
+ $tab2 = $temp;
+ }
+ }
+
+# Return the new line (paragraph)
+
+$_;
+}
+
+
+
+##################################################
+# Handle directive lines #
+##################################################
+
+# Use get_next_line() instead of <> because this is called to process
+# stacked up subsection lines
+
+sub handle_directive {
+
+my($new_lastwasitem) = 0;
+
+# Chapter directives just require . => @; however, dequoting the
+# line thereafter will remove the first @, so just force it back
+# afterwards. If the chapter is is one describing a driver, set
+# the driver name.
+
+if (/\.chapter/)
+ {
+ tr/./@/;
+ push(@ONESECTION, "@" . &dequote("$_\n"));
+ $driver_name = (/The\s+(\S+)\s+(director|router|transport|authenticator)/)? $1 :
+ (/Generic options common to both directors and routers/)?
+ "director or router" :
+ (/[Gg]eneric\s+options for (\S+)s/)? $1 : "";
+ $driver_name = &dequote($driver_name);
+ }
+
+# Section directives just require . => @; however, dequoting the
+# line thereafter will remove the first @, so just force it back
+# afterwards. Remove any colons in section titles as they cause
+# Texinfo trouble. Also remove any \\ (small caps) markup, which
+# appears in a couple of cases.
+
+elsif (/\.section/)
+ {
+ tr/./@/;
+ s/://;
+ s"\\\\""g;
+ push(@ONESECTION, "@" . &dequote("$_\n"));
+
+ # Horrible magic fudge to cope with the fact that exim_lock has
+ # -v and -q options, just like the main program.
+
+ $driver_name = "exim_lock" if /Mailbox maintenance/;
+
+ # Similar magic for exiqgrep, which also duplicates options
+
+ $driver_name = "exiqgrep" if /Selective queue listing/;
+ }
+
+# .newline must put @* on the end of the previous line, if any, except
+# inside a display, where it causes trouble.
+
+elsif (/\.newline/)
+ {
+ if (@ONESECTION > 0 && ! $indisplay)
+ {
+ $_ = pop(@ONESECTION);
+ s/(\n*)$/\@*$1/;
+ push(@ONESECTION, $_);
+ }
+ }
+
+# .blank turns into @sp, adding 1 if no argument
+
+elsif (/\.blank/)
+ {
+ s/\.blank\s+(\d+)/\@sp $1/;
+ s/\.blank/\@sp 1/;
+ push(@ONESECTION, $_);
+ }
+
+# .rule turns into a line of hyphens
+
+elsif (/\.rule/)
+ {
+ push(@ONESECTION, ("-" x ($in_itemize? 68 : 73)) . "\@*\n");
+ }
+
+# There's one explicit .tabset setting for two tab stops
+
+elsif (/\.tabset\s*/)
+ {
+ $rest = $';
+ ($first,$second) = $rest =~ /(\d+)em\s+(\d+)em/;
+ $tab = ($first * 7)/6;
+ $tab2 = $tab + ($second * 7)/6;
+ }
+
+# .tabs remembers the first (and only) tab setting
+
+elsif (/\.tabs\s*/)
+ {
+ $tab = ($' * 7)/6;
+ $tab2 = 0;
+ }
+
+# .tempindent is used only to align some of the expansion stuff nicely;
+# just ignore it. It is used in conjunction with .push/.pop.
+
+elsif (/\.(tempindent|push|pop)\s*/)
+ {
+ }
+
+# There are some instances of .if ~~sys.fancy in the source. Some of these
+# are two-part things, in which case we just keep the non-fancy. For diagrams,
+# however, they are in three parts:
+#
+# .if ~~sys.fancy
+# <aspic drawing stuff>
+# .elif ~~nothtml
+# <ascii art for txt and Texinfo>
+# .else
+# <HTML instructions for including a gif>
+# .fi
+
+elsif (/\.if \~\~sys\.fancy/)
+ {
+ while (&get_next_line())
+ { last if /\.else\b/ || /\.elif\s+\~\~nothtml/ || /\.fi\b/; }
+
+ if (/\.elif/)
+ {
+ $skip_else = 1;
+ }
+ }
+
+# There are occasional requirements to do things differently for
+# Texinfo/HTML and the PS/txt versions, and there are also some
+# HTML-specific things.
+
+elsif (/\.if\s+~~sgcal/ || /\.if\s+~~html/)
+ {
+ while (&get_next_line()) { last if /\.else\b/ || /\.fi\b/; }
+ }
+
+# We may also have Texinfo-specific bits
+
+elsif (/^\.if\s+~~texinfo/)
+ {
+ $skip_else = 1;
+ }
+
+# Ignore any other .if directives
+
+elsif (/\.if/) {}
+
+# Skip else part if flag set
+
+elsif (/\.else/ && $skip_else)
+ {
+ while (&get_next_line()) { last if /\.fi\b/; }
+ $skip_else = 0;
+ }
+
+# Ignore other .fi and .else as any .if directives are handled specially
+
+elsif (/\.fi/ || /\.else/) {}
+
+# Ignore .indent
+
+elsif (/\.indent/) {}
+
+# Plain .index goes to @cindex - the "concept" index. Also, there
+# are some calls to vindex and findex in the SGCAL source - treated
+# as synonymous with .index - which are split into the equivalent
+# indexes here.
+
+elsif (/\.(.?)index/)
+ {
+ $rest = $';
+ $letter = ($1 eq "")? "c" : $1;
+ tr/./@/; # .index -> @index
+
+ $rest =~ s/\\\(//g; # Remove markup
+ $rest =~ s/\)\\//g;
+ $rest =~ s/\\%//g;
+ $rest =~ s/%\\//g;
+ $rest =~ s/\\\*//g;
+ $rest =~ s/\*\\//g;
+ $rest =~ s/\\"//g;
+ $rest =~ s/"\\//g;
+ $rest =~ s/:://g;
+ $rest =~ s/\\-/-/g;
+ $rest =~ s/-\\//g;
+ $rest =~ s/~~//g;
+
+ $rest =~ tr/\\//d; # Remove \
+
+ $rest =~ s/\@\$/\$/g; # @$ -> $
+ $rest =~ s/\@_/_/g; # @_ -> _
+ $rest =~ s/\@\+/+/g; # @+ -> +
+ $rest =~ s/\$\*\$/\*/g; # $*$ -> *
+ $rest =~ s/\$([^\$]+)\$/\$$1/g; # $x$ -> $x
+
+ $rest =~ s/^\s+//; # Remove leading spaces
+ $rest =~ s/\s+$//; # Remove trailing spaces
+ $rest =~ s/\|\|/:/; # || -> :
+ push(@ONESECTION, "\@${letter}index $rest\n");
+
+ # Duplicate entries for things that were listed as "x see y"
+
+ if (defined $indirections{$rest})
+ {
+ push(@ONESECTION, "\@${letter}index $indirections{$rest}\n");
+ }
+ }
+
+# Various flavours of numberpars map to itemize and enumerate.
+# Haven't found a way of having a blank space 'bullet' yet, so
+# currently using minus.
+
+elsif (/\.numberpars/)
+ {
+ $rest = $';
+ $type = "enumerate";
+ $flag = "";
+
+ if ($rest =~ /\$\./) { $flag = " \@bullet"; $type = "itemize" }
+ elsif ($rest =~ /\" \"/) { $flag = " \@minus"; $type = "itemize"; }
+ elsif ($rest =~ /roman/) { $flag = " a"; $type = "enumerate"; }
+
+ push(@ONESECTION, "\n\@$type$flag\n\n\@item\n");
+ push(@ENDLIST, $type);
+ $in_itemize++;
+ }
+
+elsif (/\.nextp/)
+ {
+ push(@ONESECTION, "\n\@item\n");
+ }
+
+elsif (/\.endp/)
+ {
+ $endname = pop(@ENDLIST);
+ push(@ONESECTION, "\@end $endname\n\n");
+ $in_itemize--;
+ }
+
+# The normal .display (typewriter font) => @example, while the rm
+# form goes to @display (no change of font). For Texinfo we need a
+# blank line after @display.
+
+elsif (/\.display/)
+ {
+ $type = /rm/? "display" : "example";
+ $asis = 1 if /asis/;
+ $indisplay = 1;
+ push(@ONESECTION, "\@$type\n\n");
+ push(@ENDLIST, $type);
+ }
+
+elsif (/\.endd/)
+ {
+ $asis = 0;
+ $indisplay = 0;
+ $endname = pop(@ENDLIST);
+ push(@ONESECTION, "\@end $endname\n\n");
+ }
+
+elsif (/\.conf/)
+ {
+ ($option, $type, $default) =
+ /\.conf\s+(\S+)\s+("(?:[^"]|"")+"|\S+)\s+("(?:[^"]|"")+"|.*)/;
+
+ $option = &dequote($option);
+
+ # If $type ends with $**$ (turned into a dagger for PS version),
+ # replace with ", expanded". Remove any surrounding quotes.
+
+ $type =~ s/^"([^"]+)"/$1/;
+ $type =~ s/\$\*\*\$/, expanded/;
+
+ # Default may be quoted, and it may also have quotes that are required,
+ # if it is a string.
+
+ $default =~ s/^"(.*)"$/$1/;
+ $default =~ s/""/"/g;
+ $default = &handle_text($default);
+
+ push(@ONESECTION, "\nType: $type\@*\nDefault: $default\n\n");
+ }
+
+# Handle .startitems, .enditems, and .item
+
+elsif (/\.startitem/ || /\.enditem/) {}
+
+elsif (/\.item/)
+ {
+ $arg = $';
+ $arg =~ s/^\s*"//;
+ $arg =~ s/"\s*$//;
+ $arg = &dequote($arg);
+ $arg = &handle_text("\\**$arg**\\");
+
+ # If there are two .items in a row, we don't want to put in the
+ # separator line.
+
+# push(@ONESECTION, "\n\@example\n");
+ push(@ONESECTION, "\n");
+ if (! $lastwasitem)
+ {
+ push(@ONESECTION, "_" x 75, "\n\n");
+ }
+# push(@ONESECTION, "$arg\n\@end example\n\n");
+ push(@ONESECTION, "$arg\n\n");
+ $new_lastwasitem = 1;
+ }
+
+elsif (/\.option/)
+ {
+ chomp($arg = $');
+ $arg =~ s/^\s*//;
+ $arg = &dequote("-$arg");
+ $arg = &handle_text($arg);
+ }
+
+# Texinfo has no facility for emphasis bars.
+
+elsif (/\.em/) {}
+elsif (/\.nem/) {}
+
+# Just ignore any .(r)set directives pro tem (or maybe always!)
+
+elsif (/\.r?set/) {}
+
+# Ignore .space, .linelength, and .justify
+
+elsif (/\.space/ || /\.justify/ || /\.linelength/) {}
+
+# Found an SGCAL directive that isn't dealt with. Oh dear.
+# Turn the embarrassing characters into question marks and
+# output it in an emphasized way.
+
+else
+ {
+ tr/@{}/???/;
+ push(@ONESECTION, "\n\>>>>>>> $_\n") if ! /^\.( |$)/;
+ }
+
+$lastwasitem = $new_lastwasitem;
+}
+
+
+
+##################################################
+# Flush a section #
+##################################################
+
+# $section_name is the name of the next section.
+# $current_section is the name of the one we have buffered up.
+# If it is unset, we are at the first section of a chapter.
+# $previous_node is the section we last flushed if it was a node.
+
+sub flush_section {
+
+# If there is no text in the section, omit it entirely. However, it
+# will have had a pointer set up at the start of the previous section.
+# Remember what to replace this with when the chapter gets flushed.
+
+my($skip) = 1;
+foreach $s (@ONESECTION)
+ {
+ if ($s !~ /^(\@cindex|\@section|\s*$)/) { $skip = 0; last }
+ }
+
+if ($skip)
+ {
+ pop @section_list;
+ $rewrite{$current_section} = $section_name;
+ @ONESECTION = ();
+ return;
+ }
+
+# There is data in the section: write it out to the chapter file
+
+if ($current_section)
+ {
+ printf ONECHAPTER ("\@node %s, %s, %s, %s\n",
+ &decomma($current_section), &decomma($section_name),
+ &decomma($previous_node), &decomma($current_up));
+ $previous_node = $current_section;
+ while(scalar(@ONESECTION))
+ { print ONECHAPTER shift(@ONESECTION); }
+ }
+else
+ {
+ while(scalar(@ONESECTION))
+ { push(@TOPSECTION, shift(@ONESECTION)); }
+ }
+}
+
+
+
+##################################################
+# Handle a "subsection" #
+##################################################
+
+# A "subsection" is a set of options that must have their own
+# local menu. Do two passes; the first just collects the names
+# for the menu. This is called for .conf and .option items.
+
+sub handle_subsection{
+my($type) = $_[0];
+my($save_up) = $current_up;
+
+$current_up = $current_section? $current_section : $current_chapter;
+
+@sublist = ();
+@SUBBUFFER = ();
+
+while (<>)
+ {
+ last if /^\.end$type/;
+ push(@SUBBUFFER, $_);
+
+ # .conf takes the first non-space string as the name, but as there are
+ # duplicate confs in various parts of the spec, use the driver name to
+ # de-duplicate; .option takes the entire rest of arg as the name, but
+ # removes any sequence of ... because this disturbs TexInfo. Also, it
+ # turns @- into -.
+
+ if (/^\.$type\s+(\S+)(.*)/)
+ {
+ if ($type eq "conf")
+ {
+ $name = &handle_text($1);
+ $name .= " ($driver_name)" if ($driver_name ne "");
+ }
+ else
+ {
+ chomp($name = &handle_text("-$1$2"));
+ $name =~ s/\s*\.\.\.//g;
+
+ $name .= " ($driver_name)" if ($driver_name ne "");
+
+ # There seems to be a major problem in texinfo with the string "--".
+ # In the text it gets turned into a single hyphen. This happens if it
+ # is used as a menu item, but *not* as a node name. Exim has a command
+ # line option "--". With no special action, this appears in the menu
+ # as "-", but then the info software complains there is no node called
+ # "-". If we triple it in the menu it gets displayed OK, but building
+ # software complains about non-existent cross references etc.
+
+ # I have gone for the horrid kludge of turning it into "-<hyhen>"
+ # in the menus and nodes.
+
+ # Exim 4 has added --help, which has the same problem.
+
+ $name = "-<hyphen>" if ($name eq "--");
+ $name = "-<hyphen>help" if ($name eq "--help");
+ }
+ push(@sublist, $name);
+ }
+ }
+
+push (@ONESECTION, "\n\@sp 2\n\@menu\n");
+for ($i = 0; $i < scalar(@sublist); $i++)
+ {
+ $mitem = $sublist[$i];
+ $mitem =~ s/\@sc\{([^}]*)\}/\U$1/g; # Get rid of small caps
+ $mitem =~ s/:/<colon>/g; # Get rid of colons
+ push (@ONESECTION, "* ${mitem}::\n");
+ }
+push (@ONESECTION, "\@end menu\n\n");
+
+$prevsub = $current_up;
+$processing_subsection = 1;
+while ($_ = shift(@SUBBUFFER))
+ {
+ if (/^\.$type\s+(\S+)/)
+ {
+ $name = shift @sublist;
+ $next = (scalar(@sublist))? $sublist[0] : "";
+ push @ONESECTION, sprintf("\@node %s, %s, %s, %s\n",
+ &decomma($name), &decomma($next), &decomma($prevsub),
+ &decomma($current_up));
+
+ if ($name eq "-<hyphen>") # Fudge for Texinfo
+ {
+ push(@ONESECTION,
+ "\@findex $name\n",
+ "\@unnumberedsubsec --- option\n");
+ push(@ONESECTION,
+ "This option consists of two consecutive hyphens. It appears in\n",
+ "the menu as \"-<hyphen>\" because otherwise Texinfo gets\n",
+ "confused with its cross-referencing.\n");
+ }
+ elsif ($name eq "-<hyphen>help") # Fudge for Texinfo
+ {
+ push(@ONESECTION,
+ "\@findex $name\n",
+ "\@unnumberedsubsec ---help option\n");
+ push(@ONESECTION,
+ "This option consists of \"help\" preceded by two consecutive\n" .
+ "hyphens. It appears in the menu as \"-<hyphen>help\" because\n" .
+ "otherwise Texinfo gets confused with its cross-referencing.\n");
+ }
+ else
+ {
+ push(@ONESECTION,
+ "\@findex $name\n",
+ "\@unnumberedsubsec $name option\n");
+ }
+
+ $prevsub = $name;
+ }
+
+ # Then handle as text or directive
+
+ if (substr($_, 0, 1) eq ".")
+ { handle_directive(); }
+ else
+ {
+ while($nextline = shift(@SUBBUFFER))
+ {
+ last if $nextline =~ /^(\.|\s*$)/;
+ $_ .= $nextline;
+ }
+ push(@ONESECTION, handle_text($_));
+ $_ = $nextline;
+ last if !defined($_);
+ redo;
+ }
+ }
+
+$processing_subsection = 0;
+$section_pending = 1;
+$current_up = $save_up;
+}
+
+
+
+
+##################################################
+# Handle a single chapter #
+##################################################
+
+sub handle_chapter{
+chop;
+($current_chapter) = /^\.chapter (.*)/;
+$current_chapter = &dequote($current_chapter);
+
+$current_chapter = $current_chapter;
+
+my($tmp) = $current_chapter;
+$tmp =~ s/\[\[\[\]\]\]/./;
+print STDERR "processing chapter: $tmp\n";
+
+# Remember the chapter name for the top-level menu
+
+push(@chapter_list, $current_chapter);
+
+# Open a temporary file to hold the chapter's text while collecting
+# all its sections for a chapter-level menu.
+
+$ONECHAPTER = "/tmp/ONECHAPTER.$$";
+open(ONECHAPTER, ">$ONECHAPTER") || die "Can't open $ONECHAPTER for writing";
+
+# Initialize for handling sections
+
+@section_list = ();
+%rewrite = ();
+@ONESECTION = ();
+@TOPSECTION = ();
+undef $current_section;
+undef $next_node;
+
+$processing_subsection = 0;
+
+$previous_node = $current_up = $current_chapter;
+$section_pending = 0;
+
+# Handle the .chapter directive as the first text of a section without
+# a section title.
+
+handle_directive();
+
+# Loop, handling each section. Assume they are sufficiently short that
+# we can buffer the text in store, in an array called ONESECTION, instead
+# of thrashing yet another file.
+
+while (<>)
+ {
+ last if /^\.chapter /;
+
+ # Handle a new section, preserving $_ (handle_text flattens it).
+ # It seems we cannot get a fullstop into a Texinfo node name; use a magic
+ # character string that gets turned back into a dot by the post-processing.
+
+ if (/^\.section\s+/)
+ {
+ $save = $_;
+ $section_name = $';
+ $section_name =~ s/(\s|\n)+$//;
+ $section_name =~ s/://;
+ $section_name = &handle_text($section_name);
+ flush_section();
+ push(@section_list, $section_name);
+ $current_section = $section_name;
+ $next_node = $section_name if !$next_node;
+ $section_pending = 0;
+ $_ = $save;
+ }
+
+ # The .startconf macro introduces a set of .conf's which must have
+ # their own local set of menus. Suspend processing the section while
+ # we sort out the menu and copy their data. This is all done in a
+ # subroutine that is shared with options.
+
+ elsif (/^\.startconf/)
+ {
+ handle_subsection("conf");
+ next;
+ }
+
+ elsif (/^\.startoption/)
+ {
+ handle_subsection("option");
+ next;
+ }
+
+ # Deal with the actual data lines; if there's a section pending
+ # start a new section on hitting some text. We hope this happens
+ # only once per chapter...
+
+ if (substr($_, 0, 1) eq ".")
+ {
+ handle_directive();
+ }
+ else
+ {
+ while($nextline = <>)
+ {
+ last if $nextline =~ /^(\.|\s*$)/;
+ $_ .= $nextline;
+ }
+ if ($section_pending && !/^\s*$/)
+ {
+ $section_name = (defined $current_section)?
+ "$current_section (continued)" :
+ "$current_chapter (continued)" ;
+ flush_section();
+ push(@section_list, $section_name);
+ $current_section = $section_name;
+ $next_node = $section_name if !$next_node;
+ $section_pending = 0;
+ }
+
+ push(@ONESECTION, handle_text($_));
+ $_ = $nextline;
+ last if !defined($_);
+ redo;
+ }
+ }
+
+# Flush any pending text, making its next field null.
+# and fudging section_name for the final section of the previous.
+
+$section_name = "";
+flush_section();
+
+# Set up section name as the start of the next chapter
+
+$section_name = "Concept Index" if (!$doing_filter);
+
+if (defined $_ && /^\.chapter (.*)/)
+ {
+ $section_name = $1;
+ $section_name = &dequote($section_name);
+ }
+$next_node = $section_name;
+
+# Write out the chapter to the CHAPTERS file, sticking the chapter
+# menu after the text that came before the first section heading. This
+# will always at least contain the chapter title.
+
+printf CHAPTERS ("\@node %s, %s, %s, Top\n",
+ &decomma($current_chapter), &decomma($next_node),
+ &decomma($previous_chapter));
+
+# The pre-section stuff; if we hit an @end menu line, it is the menu of
+# a "subsection" before the first section. In that case, we need to put
+# the chapter's menu one the end of it, and then resume with the rest of
+# the TOPSECTION data afterwards. We also need to thread together this
+# "subsection"s nodes because they are all at the same level under the
+# chapter.
+
+$in_menu = 0;
+while(scalar(@TOPSECTION))
+ {
+ $s = shift(@TOPSECTION);
+ if ($s =~ /^\@end menu/)
+ {
+ $in_menu = 1;
+ last;
+ }
+ print CHAPTERS $s;
+ }
+
+# Menu for sections
+
+undef $next_actual_section;
+undef $point_back;
+
+if (scalar(@section_list))
+ {
+ print CHAPTERS "\n\@sp 2\n\@menu\n" if ! $in_menu;
+ $next_actual_section = $section_list[0];
+ for ($i = 0; $i < scalar(@section_list); $i++)
+ {
+ $section_name = $section_list[$i];
+ $section_name =~ s/\@sc\{([^}]*)\}/\U$1/g;
+ print CHAPTERS "* ${section_name}::\n";
+ }
+ $in_menu = 1;
+ }
+print CHAPTERS "\@end menu\n\n" if $in_menu;
+
+# Remainder of topsection; we must arrange that the final @node in
+# it (which will have a blank "next" field) actually points on to
+# the next section, if any. If this happens, then the next section
+# must point back to the final @node.
+
+while(scalar(@TOPSECTION))
+ {
+ $s = shift(@TOPSECTION);
+ if ($next_actual_section && $s =~
+ /^\@node\s+([^,]+),\s*,\s*([^,]*),\s*(.*)/)
+ {
+ my($t1, $t2, $t3) = ($1, $2, $3); # So can be decomma'd
+ printf CHAPTERS ("\@node %s, %s, %s, %s\n", &decomma($t1),
+ &decomma($next_actual_section), &decomma($t2), &decomma($t3));
+ $point_back = $1;
+ }
+ else { print CHAPTERS $s; }
+ }
+
+close(ONECHAPTER);
+open(ONECHAPTER, "$ONECHAPTER") || die "Can't open $ONECHAPTER for reading";
+
+# While copying the chapter data, check for node references to empty
+# sections that got omitted and correct them, and correct the prev pointer
+# in the first node if necessary.
+
+while ($buff = <ONECHAPTER>)
+ {
+ foreach $key (keys %rewrite)
+ {
+ $buff =~ s/$key/$rewrite{$key}/;
+ }
+ if ($point_back && $buff =~ /^\@node\s+([^,]+),\s*([^,]*),\s*([^,]*),\s*(.*)/)
+ {
+ my($t1, $t2, $t4) = ($1, $2, $4); # so can be decomma'd
+ printf CHAPTERS ("\@node %s, %s, %s, %s\n", &decomma($t1),
+ &decomma($t2), &decomma($point_back), &decomma($t4));
+ undef $point_back;
+ }
+ else { print CHAPTERS $buff; }
+ }
+
+$previous_chapter = $current_chapter;
+
+close(ONECHAPTER);
+unlink($ONECHAPTER);
+}
+
+
+
+##################################################
+# Main Program #
+##################################################
+
+# This is a two-pass algorithm. The first pass goes through and gets the
+# variable names for cross references. The second pass does the real work,
+# but we can't just read through doing the translation in one pass. We need
+# to know the list of chapters in order to build a top-level menu, and for
+# each chapter we need to know the sections in order to build a section
+# menu. Consequently, make use of temporary files to buffer things.
+
+# This script is used for the filter document and the overview as well;
+# flags tell it if it is doing one of them.
+
+$doing_filter = 0;
+$skip_else = 0;
+$in_itemize = 0;
+$lastwasitem = 0;
+
+$chapter_number = 0;
+$section_number = 0;
+
+if ($#ARGV >= 0 && $ARGV[0] eq "-filter")
+ {
+ $doing_filter = 1;
+ shift @ARGV;
+ }
+
+# First pass: Just fish out variable settings. Save the arguments so that
+# they can be reinstated for a second pass.
+
+print STDERR "Scanning for references\n";
+@save_argv = @ARGV;
+
+# Pick up any .set directives right at the very start
+
+while (<>)
+ {
+ last if ! /^\.set\s+(\S+)\s+(.+)$/;
+ $name = $1;
+ $value = $2;
+ $value =~ s/^\"?(.*?)\"?\s*$/$1/;
+ $references{$name} = $value;
+ }
+
+# Now skip everything before the first .chapter except for
+# .index lines that set up indirections. Save these so that
+# the relevant index entries can be duplicated.
+
+while (<>)
+ {
+ if (/^\.chapter\s+(.+)$/)
+ {
+ $chapter_number++;
+ $section_number = 0;
+ $current_chapter = $1;
+ $current_chapter = $current_chapter;
+ $current_section = "";
+ last;
+ }
+
+ if (/^\.index\s+([^\$]+)\s+\$it\{see\s+([^}]+)\}\s*$/)
+ {
+ $indirections{"$2"} = $1;
+ }
+ }
+
+# Do the business
+
+while (<>)
+ {
+ if (/^\.chapter\s+(.+)$/)
+ {
+ $current_chapter = $1;
+ $current_chapter = &dequote($current_chapter);
+ $current_section = "";
+ }
+ elsif (/^\.section\s+(.+)$/)
+ {
+ $current_section = $1;
+ $current_section = &dequote($current_section);
+ $current_section =~ s/://;
+ }
+ elsif (/^\.r?set\s+(\S+)\s+(.+)$/ && $1 ne "runningfoot")
+ {
+ $name = $1;
+ $value = $2;
+
+ # Only set the first time. This handles a few special cases in part2
+ # which is included in the filter text as well.
+
+ if (!exists($references{$name}))
+ {
+ $value =~ s/^\"?(.*?)\"?\s*$/$1/;
+ $value =~ s/~~chapter\./~~chapter****/;
+ $value =~ s/~~chapter/$current_chapter/;
+ $value =~ s/~~section/$current_section/;
+ $references{$name} = $value;
+ }
+ }
+ }
+
+$final_chapter = defined($current_chapter)? $current_chapter : "";
+
+# Reinstate ARGV with the list of files and proceed to the main pass
+
+@ARGV = @save_argv;
+
+# $asis is set true when processing .display asis blocks, to stop
+# characters getting interpreted.
+
+$asis = 0;
+
+# $indisplay is set true while processing .display blocks, to stop
+# .newlines being handled therein (adding @* wrecks alignment)
+
+$indisplay = 0;
+
+# $tab is set to the value of the tab stop - only one stop is ever used
+# in the Exim source.
+
+$tab = 0;
+
+# Current driver name, for disambiguating nodes
+
+$driver_name = "";
+
+# $section_pending is set if a new section is to be started on hitting
+# any data lines.
+
+$section_pending = 0;
+
+# Open a file to buffer up the entire set of chapters
+
+$CHAPTERS = "/tmp/CHAPTERS.$$";
+open(CHAPTERS, ">$CHAPTERS") || die "Can't open $CHAPTERS for writing";
+
+# Skip everything before the first .chapter
+
+while (<>) { last if /^\.chapter /; }
+
+# Loop, handling each chapter
+
+$current_up = "";
+$previous_chapter = "Top";
+$previous_node = "Top";
+
+$chapter_number = 0;
+$section_number = 0;
+
+while (defined ($_) && /^\.chapter /)
+ {
+ handle_chapter();
+ }
+
+# Output the stuff at the start of the file
+
+print "\\input texinfo\n";
+
+print "\@set{wmYear} 2003\n";
+print "\@set{wmAuthor} Philip Hazel\n";
+print "\@set{wmAuthor_email} <ph10\@\@cus.cam.ac.uk>\n";
+print "\@set{COPYRIGHT1} Copyright \@copyright{} \@value{wmYear} University of Cambridge\n";
+
+print "\@c %**start of header\n";
+
+if (!$doing_filter)
+ {
+ print "\@setfilename spec.info\n";
+ print "\@settitle Exim Specification\n";
+ }
+else
+ {
+ print "\@setfilename filter.info\n";
+ print "\@settitle Exim Filter Specification\n";
+ }
+
+print "\@paragraphindent 0\n";
+print "\@c %**end of header\n\n";
+
+
+print "\@titlepage\n";
+print "\@title The Exim Mail Transfer Agent\n";
+print "\@author \@value{wmAuthor}\n";
+
+print "\@page\n";
+print "\@vskip 0pt plus 1filll\n";
+
+print "Permission is granted to make and distribute verbatim copies of this manual provided the\n";
+print "copyright notice and this permission notice are preserved on all copies.\n";
+
+print "\@sp2\n";
+print "\@value{COPYRIGHT1}\@*\n";
+
+print "\@end titlepage\n\n";
+
+# Output the top-level node and its introductory blurb
+
+print "\@node Top, $chapter_list[0], (dir), (dir)\n";
+print "\@top\n";
+
+if (!$doing_filter)
+{
+print <<End;
+The Exim Mail Transfer Agent\@*
+****************************
+
+The specification of the Exim Mail Transfer Agent is converted mechanically
+into Texinfo format from its original marked-up source. Some typographic
+representations are changed, chapters and sections cannot be numbered, and
+Texinfo lacks the ability to mark updated parts of the specification with
+change bars.
+
+Because the chapters and sections are unnumbered, cross references are set to
+their names. This makes the English a bit odd, with phrases like \`see chapter
+\"Retry configuration\"\' but it seemed very cumbersome to change this to \`see
+the chapter entitled \"Retry configuration\"\' each time.
+
+Each chapter, section, and configuration option has been placed in a separate
+Texinfo node. Texinfo doesn\'t allow commas, colons, or apostrophes in node
+names, which is a rather nasty restriction. I have arranged not to use colons
+or apostrophes in section titles, but cannot bring myself to omit them from
+titles such as \"The foo, bar and baz commands\". For the corresponding node
+names I have just used multiple occurrences of \"and\", though it looks very
+ugly.
+
+If a chapter or section continues after a list of configuration options that is
+not in a new section, a new node is started, using the chapter\'s or section\'s
+name plus \`(continued)\'. The \`Up\' operation from a section or configuration
+option returns to the start of the current chapter; the \`Up\' operation at a
+chapter start returns to the top of the document; the \`Up\' in a list of
+configuration options within a section returns to the top of that section.
+
+A number of drivers have options with the same name, so they have been
+disambiguated by adding the name of the driver to its option names in order to
+create node names. Thus, for example, the specification of the \`command\'
+options of the \`lmtp\' and \`pipe\' transports are in nodes called \`command
+(lmtp)\' and \`command (pipe)\', respectively.
+
+End
+}
+
+else
+{
+print <<End;
+Filtering with the Exim Mail Transfer Agent\@*
+*******************************************
+
+The specifications of the Exim Mail Transfer Agent\'s filtering facility is
+converted mechanically into Texinfo format from its original marked-up source.
+Some typographic representations are changed, chapters and sections cannot be
+numbered, and Texinfo lacks the ability to mark updated parts of the
+specification with change bars.
+
+Because the chapters and sections are unnumbered, cross references are set to
+their names. This makes the English a bit odd, with phrases like \`see section
+\"Multiple personal mailboxes\"\' but it seemed very cumbersome to change this to
+\`see the section entitled \"Multiple personal mailboxes\"\' each time.
+
+End
+}
+
+# Output the top-level menu
+
+print "\@menu\n";
+
+while (scalar(@chapter_list))
+ {
+ $name = &decomma(shift(@chapter_list));
+ print "* ${name}::\n";
+ }
+print "* Concept Index::\n" if (!$doing_filter);
+print "\@end menu\n\n";
+
+# Copy the chapters, then delete the temporary file
+
+close(CHAPTERS);
+open(CHAPTERS, "$CHAPTERS") || die "Can't open $CHAPTERS for reading";
+print $buff while($buff = <CHAPTERS>);
+close(CHAPTERS);
+unlink($CHAPTERS);
+
+# Output the finishing off stuff
+
+if (!$doing_filter)
+ {
+ print "\@node Concept Index, , $final_chapter, Top\n";
+ print "\@chapter Concept Index\n\@printindex cp\n";
+ print "\@chapter Function Index\n\@printindex fn\n";
+ }
+print "\@contents\n";
+print "\@bye\n";
+
+# End
diff --git a/doc/doc-src/FAQ.src b/doc/doc-src/FAQ.src
new file mode 100644
index 000000000..9ad5cf94d
--- /dev/null
+++ b/doc/doc-src/FAQ.src
@@ -0,0 +1,7015 @@
+## $Cambridge: exim/doc/doc-src/FAQ.src,v 1.1 2004/10/07 15:04:35 ph10 Exp $
+##
+## This file is processed by Perl scripts to produce an ASCII and an HTML
+## version. Lines starting with ## are omitted. The markup used with paragraphs
+## is as follows:
+##
+## Markup User for HTML Text
+## ------------------------------------------------------
+## \...\ option fixed-pitch "quoted"
+## \$...$\ variable $italic $plain
+## \*...*\ titles, quotes italic "quoted"
+## \(...)\ file name italic plain
+## \[...]\ replaceable <italic> <plain>
+## \?...?\ URL URL plain
+## \^...^\ Unix command italic plain
+## \%...%\ Exim driver bold "quoted"
+## \^^.^^\ C function bold plain
+## ::...:: header name italic: plain:
+## //...// domain italic plain
+## \/.../\ local part italic plain
+## \"..."\ literal fixed-pitch "quoted"
+## \\...\\ SMTP, build small caps caps
+## \**...**\ warn, item bold plain
+## \-...-\ cmd option -italic -plain
+## \# hard space &nbsp; space
+##
+## ``...'' quoted string &#147;...&#148; "..."
+##
+## @\ is used when a real backslash is required
+##
+## In addition, sequences of not blank lines that start with ==> are displayed
+## in fixed-pitch with no further interpretation. A line containing only [[br]]
+## is removed from the text version, but turned into <br> in the HTML version.
+##
+## The starts of sections and of questions and answers are automatically
+## detected by the scripts.
+##
+##
+THE EXIM FAQ
+------------
+
+This is the FAQ for the Exim Mail Transfer Agent. Many thanks to the many
+people who provided the original information. This file would be amazingly
+cluttered if I tried to list them all. Suggestions for corrections,
+improvements, and additions are always welcome.
+
+This version of the FAQ applies to Exim 4.00 and later releases. It has been
+extensively revised, and material that was relevant only to earlier releases
+has been removed. As this caused some whole sections to disappear, I've taken
+the opportunity to re-arrange the sections and renumber everything except the
+configuration samples.
+
+References of the form Cnnn, Fnnn, Lnnn, and Snnn are to the sample
+configuration, filter, \^^local_scan()^^\, and ``useful script'' files. These
+are hyperlinked from the HTML version of this FAQ. They can also be found in
+the separately distributed directory called \(config.samples)\. The primary
+location is
+
+\?ftp://ftp.csx.cam.ac.uk/pub/software/email/exim/exim4/config.samples.tar.gz?\
+\?ftp://ftp.csx.cam.ac.uk/pub/software/email/exim/exim4/config.samples.tar.bz2?\
+
+There are brief descriptions of these files at the end of this document.
+
+Philip Hazel
+Last update: 31-March-2004
+
+
+The FAQ is divided into the following sections:
+
+ 0. General Debugging
+ 1. Building and Installing
+ 2. Routing in general
+ 3. Routing to remote hosts
+ 4. Routing for local delivery
+ 5. Filtering
+ 6. Delivery
+ 7. Policy controls
+ 8. Rewriting addresses
+ 9. Headers
+ 10. Performance
+ 11. Majordomo
+ 12. Fetchmail
+ 13. Perl
+ 14. Dial-up and ISDN
+ 15. UUCP
+ 16. Modifying message bodies
+ 17. Encryption (TLS/SSL)
+ 20. Millennium
+ 50. Miscellaneous
+ 91. Mac OS X
+ 92. FreeBSD
+ 93. HP-UX
+ 94. BSDI
+ 95. IRIX
+ 96. Linux
+ 97. Sun sytems
+ 98. Configuration cookbook
+ 99. List of sample configurations
+
+
+
+0. GENERAL DEBUGGING
+
+Q0001: Exim is crashing. What is wrong?
+
+A0001: Exim should never crash. The author is always keen to know about
+ crashes, so that they can be diagnosed and fixed. However, before you
+ start sending me email, please check that you are running the latest
+ release of Exim, in case the problem has already been fixed. The
+ techniques described below can also be useful in trying to pin down
+ exactly which circumstances caused the crash and what Exim was trying to
+ do at the time. If the crash is reproducable (by a particular message,
+ say) keep a copy of that message.
+
+
+Q0002: Exim is not working. What is wrong? How can I check what it is doing?
+
+A0002: Exactly how is it not working? Check the more specific questions in the
+ other sections of this FAQ. Some general techniques for debugging are:
+
+ (1) Look for information in Exim's log files. These are in the \(log)\
+ directory in Exim's spool directory, unless you have configured a
+ different path for them. Serious operational problems are reported
+ in paniclog.
+
+ (2) If the problem involves the delivery of one or more messages, try
+ forcing a delivery with the \-M-\ option and also set the \-d-\
+ option, to cause Exim to output debugging information. For example:
+
+==> exim -d -M 0z6CXU-0005RR-00
+
+ The output is written to the standard error stream. You need to have
+ admin privileges to use \-M-\ and \-d-\.
+
+ (3) If the problem involves incoming SMTP mail, try using the \-bh-\
+ option to simulate an incoming connection from a specific host,
+ for example:
+
+==> exim -bh 10.9.8.7
+
+ This goes through the motions of an SMTP session, without actually
+ accepting a message. Information about various policy checks is
+ output. You will need to know how to pretend to be an SMTP client.
+
+ (4) If the problem involves lack of recognition or incorrect handling
+ of local addresses, try using the \-bt-\ option with debugging turned
+ on, to see how Exim is handling the address. For example,
+
+==> exim -d -bt z6abc
+
+ shows you how it would handle the local part \"z6abc"\.
+
+
+Q0003: What does the error \*Child process of address_pipe transport returned
+ 69 from command xxx*\ mean?
+
+A0003: It means that when a transport called \%address_pipe%\ was run to pass an
+ email message by means of a pipe to another process running the command
+ xxx, the return code from that command was 69, which indicates some kind
+ of error (the success return code is 0).
+
+ The most common meaning of exit code 69 is ``unavailable'', and this often
+ means that when Exim tried to run the command \(xxx)\, it failed. One
+ cause of this might be incorrect permissions on the file containing the
+ command. See also Q0026.
+
+
+Q0004: My virtual domain setup isn't working. How can I debug it?
+
+A0004: You can use an exim command with \-d-\ to get it to show you how it is
+ processing addresses. You don't actually need to send a message; use the
+ \-bt-\ option like this:
+
+==> exim -d -bt localpart@virtualhost
+
+ This will show you which routers it is using. If the problem appears
+ to be with the expansion of an option setting, you can use the
+ \debug_print\ option on a router to get Exim to output the expanded
+ string values as it goes along.
+
+
+Q0005: Why is Exim not rejecting incoming messages addressed to non-existent
+ users at SMTP time?
+
+A0005: This is controlled by the ACL that is run for each incoming RCPT
+ command. It is defined by the \acl_smtp_rcpt\ option. You can check this
+ part of your configuration by using the \-bh-\ option to run a simulated
+ SMTP session, during which Exim will tell you what things it is
+ checking.
+
+
+Q0006: I've put an entry for \"*.my.domain"\ in a DBM lookup file, but it isn't
+ getting recognized.
+
+A0006: You need to request ``partial matching'' by setting the search type to
+ \partial-dbm\ in order for this to work.
+
+
+Q0007: I've put the entry \"*@domain.com"\ in a lookup database, but it isn't
+ working. The expansion I'm using is:
+
+==> ${lookup{${lc:$sender_address}}dbm{/the/file} ...
+
+A0007: As no sender address will ever be //*@domain.com// this will indeed have
+ no effect as it stands. You need to tell Exim that you want it to look
+ for defaults after the normal lookup has failed. In this case, change the
+ search type from \"dbm"\ to \"dbm*@"\. See the section on \*Default values in
+ single-key lookups*\ in the chapter entitled \*File and database
+ lookups*\ in the Exim manual.
+
+
+Q0008: If I run \"./exim -d -bt user@domain"\ all seems well, but when I send
+ a message from my User Agent, it does not arrive at its destination.
+
+A0008: Try sending a message directly to Exim by typing this:
+
+==> exim -v user@domain
+ <some message, could be empty>
+ .
+
+ If the message gets delivered to a remote host, but never arrives at its
+ final destination, then the problem is at the remote host. If, however,
+ the message gets through correctly, then the problem may be between your
+ User Agent and Exim. Try setting Exim's \log_selector\ option to include
+ \"+arguments"\, to see with which arguments the UA is calling Exim.
+
+
+Q0009: What does \*no immediate delivery: too many messages received in one SMTP
+ connection*\ mean?
+
+A0009: An SMTP client may send any number of messages down a single SMTP
+ connection to a server. Initially, an Exim server starts up a delivery
+ process as soon as a message is received. However, in order not to start
+ up too many processes when lots of messages are arriving (typically
+ after a period of downtime), it stops doing immediate delivery after a
+ certain number of messages have arrived down the same connection. The
+ threshold is set by \smtp_accept_queue_per_connection\, and the default
+ value is 10. On large systems, the value should be increased. If you are
+ running a dial-in host and expecting to get all your mail down a single
+ SMTP connection, then you can disable the limit altogether by setting
+ the value to zero.
+
+
+Q0010: Exim puts \*for \[address]\*\ in the ::Received:: headers of some, but not all,
+ messages. Is this a bug?
+
+A0010: No. It is deliberate. Exim inserts a ``for'' phrase only if the incoming
+ message has precisely one recipient. If there is more than one
+ recipient, nothing is inserted. The reason for this is that not all
+ recipients appear in the ::To:: or ::Cc:: headers, and it is considered a
+ breach of privacy to expose such recipients to the others. A common
+ case is when a message has come from a mailing list.
+
+
+Q0011: Instead of \^exim_dbmbuild^\, I'm using a homegrown program to build DBM
+ (or cdb) files, but Exim doesn't seem to be able to use them.
+
+A0011: Exim expects there to be a binary zero value on the end of each key used
+ in a DBM file if you use the \"dbm"\ lookup type, but not for the \"dbmnz"\
+ lookup type or for the keys of a cdb file. Check that you haven't
+ slipped up in this regard.
+
+
+Q0012: Exim is unable to route to any remote domains. It doesn't seen to be
+ able to access the DNS.
+
+A0012: Try running \"exim -d+resolver -bt \[remote address]\"\. The \-d-\
+ options turns on debugging output, and the addition of \"+resolver"\
+ will make it show the resolver queries it is building and the results of
+ its DNS queries. If it appears unable to contact any name servers, check
+ the contents and permissions of \(/etc/resolv.conf)\.
+
+
+Q0013: What does the error message \*transport system_aliases: cannot find
+ transport driver "redirect" in line 92*\ mean?
+
+A0013: \%redirect%\ is a router, not a transport. You have put a configuration
+ for a router into the transports section of the configuration file.
+
+
+Q0014: Exim is timing out after receiving and responding to the DATA command
+ from one particular host, and yet the client host also claims to be
+ timing out. This seems to affect only certain messages.
+
+A0014: This kind of problem can have many different causes.
+
+ (1) This problem has been seen with a network that was dropping all
+ packets over a certain size, which mean that the first part of the SMTP
+ transaction worked, but when the body of a large message started
+ flowing, the main data bits never got through the network. See also
+ Q0017.
+
+ (2) This can also happen if a host has a broken TCP stack and won't
+ reassemble fragmented datagrams.
+
+ (3) A very few ISDN lines have been seen which failed when certain data
+ patterns were sent through them, and replacing the routers at both end
+ of the link did not fix things. One of them was triggered by more than 4
+ X's in a row in the data.
+
+
+Q0015: What does the message \*Socket bind() to port 25 for address (any)
+ failed: address already in use*\ mean?
+
+A0015: You are trying to run an Exim daemon when there is one already running -
+ or maybe some other MTA is running, or perhaps you have an SMTP line in
+ \(/etc/inetd.conf)\ which is causing \(inetd)\ to listen on port 25.
+
+
+Q0016: I've set \"verify = header_syntax"\ in my ACL, but this causes Exim to
+ complain about header lines like \"To: Work: Jim <jims@email>,
+ Home: Bob <bobs@email>"\ which look all right to me. Is this a bug?
+
+A0016: No. Header lines such as ::From::, ::To::, etc., which contain addresses, are
+ structured, and have to be in a specific format which is defined in RFC
+ 2822. Unquoted colons are not allowed in the ``phrase'' part of an email
+ address (they are OK in other headers such as ::Subject::). The correct
+ form for that header is
+
+==> To: "Work: Jim" <jims@email>, "Home: Bob" <bobs@email>
+
+ You will sometimes see unquoted colons in ::To:: and ::Cc:: headers, but only
+ in connection with name lists (called ``groups''), for example:
+
+==> To: My friends: X <x@y.x>, Y <y@w.z>;,
+ My enemies: A <a@b.c>, B <b@c.d>;
+
+ Each list must be terminated by a semicolon, as shown.
+
+
+Q0017: Whenever Exim tries to deliver a specific message to a particular
+ server, it fails, giving the error \*Remote end closed connection after
+ data*\ or \*Broken pipe*\ or a timeout. What's going on?
+
+A0017: \*Broken pipe*\ is the error you get on some OS when the remote host just
+ drops the connection. The alternative is \*connection reset by peer*\.
+ There are many potential causes. Here are some of them (see also Q0068):
+
+ (1) There are some firewalls that fall over on binary zero characters
+ in email. Have a look, e.g. with \"hexdump -c mymail | tail"\ to see if
+ your mail contains any binary zero characters.
+
+ (2) There are broken SMTP servers around that just drop the connection
+ after the data has been sent if they don't like the message for some
+ reason (e.g. it is too big) instead of sending a 5xx error code. Have
+ you tried sending a small message to the same address?
+
+ It has been reported that some releases of Novell servers running NIMS
+ are unable to handle lines longer than 1024 characters, and just close
+ the connection. This is an example of this behaviour.
+
+ (3) If the problem occurs right at the start of the mail, then it could
+ be a network problem with mishandling of large packets. Many emails are
+ small and thus appear to propagate correctly, but big emails will
+ generate big IP datagrams.
+
+ There have been problems when something in the middle of the network
+ mishandles large packets due to IP tunnelling. In a tunnelled link, your
+ IP datagrams gets wrapped in a larger datagram and sent over a network.
+ This is how virtual private networks (VPNs), and some ISP transit
+ circuits work. Since the datagrams going over the tunnel require a
+ larger packet size, the tunnel needs a bigger maximum transfer unit
+ (MTU) in the network handling the tunnelled packets. However, MTUs
+ are often fixed, so the tunnel will try to fragment the packets.
+
+ If the systems outside the tunnel are using path MTU discovery, (most
+ Sun Sparc Solaris machines do by default), and set the DF (don't
+ fragment) bit because they don't send packets larger than their \(local)\
+ MTU, then ICMP control messages will be sent by the routers at the
+ ends of the tunnel to tell them to reduce their MTU, since the tunnel
+ can't fragment the data, and has to throw it away. If this mechanism
+ stops working, e.g. a firewall blocks ICMP, then your host never
+ knows it has hit the maximum path MTU, but it has received no ACK on
+ the packet either, so it continues to resend the same packet and the
+ connection stalls, eventually timing out.
+
+ You can test the link using pings of large packets and see what works:
+
+==> ping -s host 2048
+
+ Try reducing the MTU on the sending host:
+
+==> ifconfig le0 mtu 1300
+
+ Alternatively, you can reduce the size of the buffer Exim uses for SMTP
+ output by putting something like
+
+==> DELIVER_OUT_BUFFER_SIZE=512
+
+ in your \(Local/Makefile)\ and rebuilding Exim (the default is 8192).
+ While this should not in principle have any effect on the size of
+ packets sent, in practice it does seem to have an effect on some OS.
+
+ You can also try disabling path MTU discovery on the sending host. On
+ Linux, try:
+
+==> echo 1 >/proc/sys/net/ipv4/ip_no_pmtu_disc
+
+ For a general discussion and information about other operating systems, see
+ \?http://www.netheaven.com/pmtu.html?\. If disabling path MTU discovery
+ fixes the problem, try to find the broken or misconfigured
+ router/firewall that swallows the ICMP-unreachable packets. Increasing
+ timeouts on the receiving host will not work around the problem.
+
+
+Q0018: Why do messages not get delivered down the same connection when I do
+ something like: \"exim -v -R @aol.com"\? For other domains, I do this and
+ I see the appropriate \*waiting for passed connections to get used*\
+ messages.
+
+A0018: Recall that Exim does not keep separate queues for each domain, but
+ operates in a distributed fashion. Messages get into its `waiting for
+ host x' hints database only when a delivery has been tried, and has had
+ a temporary error. Here are some possibilities:
+
+ (1) The messages to \(aol.com)\ got put in your queue, but no previous
+ delivery attempt occured before you did the \-R-\. This might have been
+ because of your settings of \queue_only_load\, \smtp_accept_queue\, or any
+ other option that caused no immediate delivery attempt on arrival. If
+ this is the case, you can try using \-qqR-\ instead of \-R-\.
+
+ (2) You have set \connection_max_messages\ on the smtp transport, and
+ that limit was reached. This would show as a sequence of messages
+ down one connection, then another sequence down a new connection, etc.
+
+ (3) Exim tried to pass on the SMTP connection to another message, but
+ that message was in the process of being delivered to \(aol.com)\ by some
+ other process (typically, a normal queue runner). This will break the
+ sequence, though the other delivery should pass its connection on to
+ other messages if there are any.
+
+ (4) The folk at \(aol.com)\ changed the MX records so the host names have
+ changed - or a new host has been added. I don't know how likely this is.
+
+ (5) Exim is not performing as it should in this regard, for some reason.
+ Next time you have mail queued up for \(aol.com)\, try running
+
+==> exim_dumpdb /var/spool/exim wait-remote_smtp
+
+ to see if those messages are listed among those waiting for the relevant
+ \(aol.com)\ hosts.
+
+
+Q0019: There seems to be a problem in the string expansion code: it doesn't
+ recognize references to headers such as \"${h_to}"\.
+
+A0019: The only valid syntax for header references is (for example) \"$h_to:"\
+ because header names are permitted by RFC 2822 to contain a very wide
+ range of characters. A colon (or white space) is required as the
+ terminator.
+
+
+Q0020: Why do connections to my machine's SMTP port take a long time to respond
+ with the banner, when connections to other ports respond instantly? The
+ delay is sometimes as long as 30 seconds.
+
+A0020: These kinds of delay are usually caused by some kind of network problem
+ that affects outgoing calls made by Exim at the start of an incoming
+ connection. Configuration options that cause outgoing calls are:
+
+ (1) \rfc1413_hosts\ and \rfc1413_query_timeout\ (for \*ident*\ calls).
+ Firewalls sometimes block ident connections so that they time out,
+ instead of refusing them immediately. This can cause this problem.
+ See Q5023 for a discussion of the usefulness of \*ident*\.
+
+ (2) The \host_lookup\ option, the \host_reject_connection\ option, or a
+ condition in the ACL that runs at connection time requires the
+ remote host's name to be looked up from its IP address. Sometimes
+ these DNS lookups time out. You can get this effect with ACL
+ statements like this:
+
+==> deny hosts = *.x.example
+
+ If at all possible, you should use IP addresses instead of host
+ names in blocking lists in order to to avoid this problem.
+
+ You can use the \-bh-\ option to get more information about what is
+ happening at the start of a connection. However, note that the \-bh-\
+ option does not provide a complete simulation. In particular, no
+ \*ident*\ checks are done, so it won't show up a delay problem that is
+ related to (1) above.
+
+
+Q0021: What does \*failed to create child process to send failure message*\ mean?
+ This is a busy mail server with \smtp_accept_max\ set to 500, but this
+ problem started to occur at about 300 incoming connections.
+
+A0021: Some message delivery failed, and when Exim wanted to send a bounce
+ message, it was unable to create a process in which to do so. Probably
+ the limit on the maximum number of simultaneously active processes has
+ been reached. Most OS have some means of increasing this limit, and in
+ some operating systems there is also a limit per uid which can be
+ varied.
+
+
+Q0022: What does \*No transport set by system filter*\ in a log line mean?
+
+A0022: Your system filter contains a \"pipe"\ or \"save"\ or \"mail"\ command,
+ but you have not set the corresponding option which specifies which
+ transport is to be used. You need to set whichever of
+ \system_filter_pipe_transport\, \system_filter_file_transport\ or
+ \system_filter_reply_transport\ is relevant.
+
+
+Q0023: Why is Exim refusing to relay, saying \*failed to find host name from IP
+ address*\ when I have the sender's IP address in an ACL condition? My
+ configuration contains this ACL statement:
+
+==> accept hosts = lsearch;/etc/mail/relaydomains:192.168.96.0/24
+
+A0023: When checking a host list, the items are tested in left-to-right
+ order. The first item in your list is a lookup on the incoming host's
+ name, so Exim has to determine the name from the incoming IP address in
+ order to perform the test. If it can't find the host name, it can't do
+ the check, so it gives up. You would have discovered what was going
+ on if you had run a test such as
+
+==> exim -bh 192.168.96.131
+
+ The solution is to put all explicit IP addresses first in the list.
+ Alternatively, you can split the ACL statement into two like this:
+
+==> accept hosts = lsearch;/etc/mail/relaydomains
+ accept hosts = 192.168.96.0/24
+
+ If the host lookup fails, the first \"accept"\ fails, but then the
+ second one is considered.
+
+
+Q0024: When I run \"exim -bd -q10m"\ I get \*PANIC LOG: exec of exim -q failed*\.
+
+A0024: This probably means that Exim doesn't know its own path so it can't
+ re-exec itself to do the first queue run. Check the output of
+
+==> exim -bP exim_path
+
+
+Q0025: I can't seem to get a pipe command to run when I include a \"${if"\
+ expansion in it. This fails:
+
+==> command = perl -T /usr/local/rt/bin/rtmux.pl \
+ rt-mailgate helpdesk \
+ ${if eq {$local_part}{rt} {correspond}{action}}
+
+A0025: You need some internal quoting in there. Exim expands each individual
+ argument separately. Because you have (necessarily) got spaces in your
+ \"${if"\ item, you have to quote that argument. Try
+
+==> command = perl -T /usr/local/rt/bin/rtmux.pl \
+ rt-mailgate helpdesk \
+ "${if eq {$local_part}{rt} {correspond}{action}}"
+
+ \**Warning:**\ If command starts with an item that requires quoting,
+ you cannot just put it in quotes, because a leading quote means that the
+ entire option setting is being quoted. What you have to do is to quote
+ the entire value, and use internally escaped quotes for the ones you
+ really want. For example:
+
+==> command = "\"${if ....}\" arg1 arg2"
+
+ Any backslashes in the expansion items will have to be doubled to stop
+ them being interpreted by the string reader.
+
+
+Q0026: I'm trying to get Exim to connect an alias to a pipe, but it always
+ gives error code 69, with the comment \*(could mean service or program
+ unavailable)*\.
+
+A0026: If your alias entry looks like this:
+
+==> alias: |"/some/command some parameters"
+
+ change it to look like this:
+
+==> alias: "|/some/command some parameters"
+
+
+Q0027: What does the error \*Spool file is locked*\ mean?
+
+A0027: This is not an error. All it means is that when an Exim delivery
+ process (probably started by a queue runner process) looked at a message
+ in order to start delivering it, it found that another Exim process was
+ already busy delivering it. On a busy system this is quite a common
+ occurrence. If you set \"-skip_delivery"\ in the \log_selector\ option,
+ these messages are omitted from the log.
+
+ The only time when this message might indicate a problem is if it is
+ repeated for the same message for a very long time. That would suggest
+ that the process that is delivering the message has somehow got stuck.
+
+
+Q0028: Exim is reporting IP addresses as 0.0.0.0 or 255.255.255.255 instead of
+ their correct values. What's going on?
+
+A0028: You are using a version of Exim built with gcc on an IRIX box.
+ See Q9502.
+
+
+Q0029: I can't seem to figure out why PAM support doesn't work correctly.
+
+A0029: There is a problem using PAM with shadow passwords when the calling
+ program is not running as \/root/\. Exim is normally running as the
+ Exim user when authenticating a remote host. See this posting for one
+ way round the problem:
+
+ \?http://www.exim.org/mailman/htdig/exim-users/Week-of-Mon-20010917/030371.html?\
+
+ Another solution can be found at \?http://www.e-admin.de/pam_exim/?\.
+
+ PAM 0.72 allows authorization as non-\/root/\, using setuid helper programs.
+ Furthermore, in \(/etc/pam.d/exim)\ you can explicitelly specify that
+ this authorization (using setuid helpers) is only permitted for certain
+ users and groups.
+
+
+Q0030: I'm trying to use a query-style lookup for hosts that are allowed to
+ relay, but it is giving really weird errors.
+
+A0030: Does your query contain a colon character? Remember that host lists are
+ colon-separated, so you need to double any colons in the query. This
+ applies even if the query is defined as a macro.
+
+
+Q0031: Exim is rejecting connections from hosts that have more than one IP
+ address, for no apparent reason.
+
+A0031: You are using Solaris 7 or earlier, and have \"nis dns files"\ in
+ \(/etc/nsswitch.conf)\. Change this to \"dns nis files"\ to avoid hitting Sun
+ bug 1154236 (a bad interaction between NIS and the DNS).
+
+
+Q0032: Exim is failing to find the MySQL library, even though is it present
+ within \\LD_LIBRARY_PATH\\. I'm getting this error:
+
+==> /usr/local/bin/exim: fatal: libmysqlclient.so.6: open failed:
+ No such file or directory
+
+A0032: Exim is suid, and \\LD_LIBRARY_PATH\\ is ignored for suid binaries on a
+ Solaris (and other?) systems. What you should be doing is adding
+ \"-R/local/lib/mysql"\ to the same place in the compilation that you added
+ \"-L/local/lib/mysql"\. This tells the binary where to look without
+ needing a path variable.
+
+
+Q0033: What does the error \*lookup of host "xx.xx.xx" failed in yyy router*\
+ mean?
+
+A0033: You configured a \%manualroute%\ router to send the message to xx.xx.xx. When
+ it tried to look up the IP address for that host, the lookup failed
+ with a permanent error. As this is a manual routing, this is a
+ considered to be a serious error which the postmaster needs to know
+ about (maybe you have a typo in your file), and there is little point
+ in keeping on trying. So it freezes the message.
+
+ (1) Don't set up routes to non-existent hosts.
+
+ (2) If you must set up routes to non-existent hosts, and don't want
+ freezing, set the \host_find_failed\ option on the router to do something
+ other than freeze.
+
+
+Q0034: Exim works fine on one host, but when I copied the binary to another
+ identical host, it stopped working (it could not resolve DNS names).
+
+A0034: Is the new host running exactly the same operating system? Most
+ importantly, are the versions of the dynamically loaded libraries
+ (files with names like \(libsocket.so.1)\) the same on both systems? If not,
+ that is probably the cause of the problem. Either arrange for the
+ libraries to be the same, or rebuild Exim from source on the new host.
+
+
+Q0035: I set a \"hosts"\ condition in an ACL to do a lookup in a file of IP
+ addresses, but it doesn't work.
+
+A0035: Did you remember to put \"net-"\ at the start of the the search type? If
+ you set something like this:
+
+==> accept hosts = lsearch;/some/file
+
+ Exim searches the file for the host name, not the IP address. You need
+ to set
+
+==> accept hosts = net-lsearch;/some/file
+
+ to make it use the IP address as the key to the lookup.
+
+
+Q0036: Why do I get the error \*Permission denied: creating lock file hitching
+ post*\ when Exim tries to do a local delivery?
+
+A0036: Your configuration specifies that local mailboxes are all held in
+ single directory, via configuration lines like these (taken from the
+ default configuration):
+
+==> local_delivery:
+ driver = appendfile
+ file = /var/mail/$local_part
+
+ and the permissions on the directory probably look like this:
+
+==> drwxrwxr-x 3 root mail 512 Jul 9 13:48 /var/mail/
+
+ Using the default configuration, Exim runs as the local user when doing
+ a local delivery, and it uses a lock file to prevent any other process
+ from updating the mailbox while it is writing to it. With those
+ permissions the delivery process, running as the user, is unable to
+ create a lock file in the \(/var/mail(\ directory. There are two solutions
+ to this problem:
+
+ (1) Set the \"write"\ and \"sticky bit"\ permissions on the directory, so
+ that it looks like this:
+
+==> drwxrwxrwt 3 root mail 512 Jul 9 13:48 /var/mail/
+
+ The \"w"\ allows any user to create new files in the directory, but
+ the \"t"\ bit means that only the creator of a file is able to remove
+ it. This is the same setting as is normally used with the \(/tmp)\
+ directory.
+
+ (2) Arrange to run the local_delivery transport under a specific group
+ by changing the configuration to read
+
+==> local_delivery:
+ driver = appendfile
+ file = /var/mail/${local_part}
+ group = mail
+
+ The delivery process still runs under the user's uid, but with the
+ group set to \"mail"\. The group permission on the directory allows
+ the process to create and remove the lock file.
+
+ The choice between (1) and (2) is up to the administrator. If the
+ second solution is used, users can empty their mailboxes by updating
+ them, but cannot delete them.
+
+ If your problem involves mail to \/root/\, see also Q0507.
+
+
+Q0037: I am experiencing mailbox locking problems with Sun's \"mailtool"\ used
+ over a network.
+
+A0037: See Q9705 in the Sun-specific section below.
+
+
+Q0038: What does the error message \*error in forward file (filtering not
+ enabled): missing or malformed local part*\ mean?
+
+A0038: If you are trying to use an Exim filter, you have forgotten to enable
+ the facility, which is disabled by default. In the \%redirect%\ router
+ (in the Exim run time configuration file) you need to set
+
+==> allow_filter = true
+
+ to allow a \(.forward)\ file to be used as an Exim filter. If you are not
+ trying to use an Exim filter, then you have put a malformed address in
+ the \(.forward)\ file.
+
+
+Q0039: I have installed Exim, but now I can't mail to \/root/\ any more. Why is
+ this?
+
+A0039: Most people set up \/root/\ as an alias for the manager of the host. If
+ you haven't done this, Exim will attempt to deliver to \/root/\ as if it
+ were a normal user. This isn't really a good idea because the delivery
+ process would run as \/root/\. Exim has a trigger guard in the option
+
+==> never_users = root
+
+ in the default configuration file. This prevents it from running as \/root/\
+ when doing any deliveries. If you really want to run local deliveries as
+ \/root/\, remove this line, but it would be better to create an alias for
+ \/root/\ instead.
+
+
+Q0040: How can I stop undeliverable bounce messages (e.g. to routeable, but
+ undeliverable, spammer senders) from clogging up the queue for days?
+
+A0040: If at all possible, you should try to avoid getting into this situation
+ in the first place, for example, by verifying recipients so that you
+ do not accept undeliverable messages that lead to these bounces.
+ You can, however, configure Exim to discard failing bounce messages
+ early. Just set \ignore_bounce_errors_after\ to specify a (short) time
+ to keep them for.
+
+
+Q0041: What does the message \*unable to set gid=ddd or uid=ddd (euid=ddd):
+ local delivery to ... transport=ttt*\ mean?
+
+A0041: Have you remembered to make Exim setuid \/root/\? It needs root privilege if
+ it is to do any local deliveries, because it does them ``as the user''.
+ Note also that the partition from which Exim is running (where the
+ binary is installed) must not have the \nosuid\ mount option set. You
+ can check this by looking at its \(/etc/fstab)\ entry (or \(/etc/vfstab)\,
+ depending on your OS).
+
+
+Q0042: My ISP's mail server is rejecting bounce messages from Exim, complaining
+ that they have no sender. The SMTP trace does indeed show that the
+ sender address is \"<>"\. Why is the Sender on the bounce message empty?
+
+A0042: Because the RFCs say it must be. Your ISP is at fault. Send them this
+ extract from RFC 2821 section 6.1 (\*Reliable Delivery and Replies by
+ Email*\):
+
+ If there is a delivery failure after acceptance of a message, the
+ receiver-SMTP MUST formulate and mail a notification message. This
+ notification MUST be sent using a null (\"<>"\) reverse path in the
+ envelope. The recipient of this notification MUST be the address
+ from the envelope return path (or the ::Return-Path:: header line).
+ However, if this address is null (\"<>"\), the receiver-SMTP MUST NOT
+ send a notification.
+
+ The reason that bounce messages have no sender is so that they
+ themselves cannot provoke further bounces, as this could lead to a
+ unending exchange of undeliverable messages.
+
+
+Q0043: What does the error \*Unable to get interface configuration: 22 Invalid
+ argument*\ mean?
+
+A0043: This is an error that occurs when Exim is trying to find out the all the
+ IP addresses on all of the local host's interfaces. If you have lots of
+ virtual interfaces, this can occur if there are more than around 250 of
+ them. The solution is to set the option \local_interfaces\ to list just
+ those IP addresses that you want to use for making and receiving SMTP
+ connections.
+
+
+Q0044: What does the error \*Failed to create spool file*\ mean?
+
+A0044: Exim has been unable to create a file in its spool area in which to
+ store an incoming message. This is most likely to be either a
+ permissions problem in the file hierarchy, or a problem with the uid
+ under which Exim is running, though it could be something more drastic
+ such as your disk being full.
+
+ If you are running Exim with an alternate configuration file using a
+ command such as \"exim -C altconfig..."\, remember that the use of -C
+ takes away Exim's root privilege.
+
+ Check that you have defined the spool directory correctly by running
+
+==> exim -bP spool_directory
+
+ and examining the output. Check the mode of this directory. It should
+ look like this, assuming you are running Exim as user \/exim/\:
+
+==> drwxr-x--- 6 exim exim 512 Jul 16 12:29 /var/spool/exim
+
+ If there are any subdirectories already in existence, they should have
+ the same permissions, owner, and group. Check also that you haven't got
+ incorrect permissions on superior directories (for example, \(/var/spool)\).
+ Check that you have set up the Exim binary to be setuid \/root/\. It should
+ look like this:
+
+==> -rwsr-xr-x 1 root xxx 502780 Jul 16 14:16 exim
+
+ Note that it is not just the owner that must be \/root/\, but also the third
+ permission must be \"s"\ rather than \"x"\.
+
+
+Q0045: I see entries in the log that mention two different IP addresses for the
+ same connection. Why is this? For example:
+
+==> H=tip-mp8-ncs-13.stanford.edu ([36.173.0.189]) [36.173.0.156]
+
+A0045: The actual IP address from which the call came is the final one.
+ Whenever there's something in parentheses in a host name, it is what the
+ host quoted as the domain part of an SMTP HELO or EHLO command. So in
+ this case, the client, despite being 36.173.0.156, issued the command
+
+==> EHLO [36.173.0.189]
+
+ when it sent your server the message. This is, of course, very
+ misleading.
+
+
+Q0046: A short time after I start Exim I see a defunct zombie process. What
+ is causing this?
+
+A0046: Your system must be lightly loaded as far as mail is concerned. The
+ daemon sets off a queue runner process when it is started, but it only
+ tidies up completed child processes when it wakes up for some other
+ reason. When there's nothing much going on, you occasionally see
+ defunct processes like this waiting to be dealt with. This is
+ perfectly normal.
+
+
+Q0047: On a reboot, or a restart of the mail system, I see the message \*Mailer
+ daemons: exim abandoned: unknown, malformed, or incomplete option
+ -bz sendmail*\. What does this mean?
+
+A0047: \-bz-\ is a Sendmail option requesting it to create a `configuration freeze
+ file'. Exim has no such concept and so does not support the option. You
+ probably have a line like
+
+==> /usr/lib/sendmail -bz
+
+ in some start-up script (e.g. \(/etc/init.d/mail)\) immedately before
+
+==> /usr/lib/sendmail -bd -q15m
+
+ The first of these lines should be commented out.
+
+
+Q0048: Whenever exim restarts it takes up to 3-5 minutes to start responding on
+ the SMTP port. Why is this?
+
+A0048: Something else is hanging onto port 25 and not releasing it. One place
+ to look is \(/etc/inetd.conf)\ in case for any reason an SMTP stream is
+ configured there.
+
+
+Q0049: What does the log message \*no immediate delivery: more than 10 messages
+ received in one connection*\ mean?
+
+A0049: A remote MTA sent a number of messages in a single SMTP session. Exim
+ limits the number of immediate delivery processes it creates as a
+ result of a single SMTP connection, in order to avoid creating a zillion
+ processes on systems that can have many incoming connections. If you are
+ dialing in to collect mail from your ISP, you should probably set
+ \smtp_accept_queue_per_connection\ to some number larger than 10, or
+ arrange to start a queue runner for local delivery (using \-ql-\)
+ immediately after collecting the mail.
+
+
+Q0050: I am getting complaints from a customer who uses my Exim server for
+ relaying that they are being blocked with a \*Too many connections*\
+ error.
+
+A0050: See \smtp_accept_max\, \smep_accept_max_per_host\ and \smtp_accept_reserve\.
+
+
+Q0051: When I try \"exim -bf"\ to test a system filter, I received the following
+ error message: \*Filter error: unavailable filtering command "fail" near
+ line 8 of filter file*\.
+
+A0051: Use the \-bF-\ option to test system filters. This gives you access to the
+ freeze and fail actions.
+
+
+Q0052: What does \*ridiculously long message header*\ in an error report mean?
+
+A0052: There has to be some limit to the length of a message's header lines,
+ because otherwise a malefactor could open an SMTP channel to your host,
+ start a message, and then just send characters continuously until your
+ host ran out of memory. (Exim stores all the header lines in main
+ memory while processing a message). For this reason a limit is imposed
+ on the total amount of memory that can be used for header lines. The
+ default is 1MB, but this can be changed by setting \\HEADER_MAXSIZE\\ in
+ \(Local/Makefile)\ before building Exim. Exceeding the limit provokes
+ the ``ridiculous'' error message.
+
+
+Q0053: Exim on my host responds to a connection with \"220 *****..."\ and
+ won't understand \\EHLO\\ commands.
+
+A0053: This is the sign of a Cisco Pix ``Mailguard'' sitting in front of your
+ MTA. Pix breaks ESMTP and only does SMTP. It is a nuisance when you have
+ a secure MTA running on your box. Something like ``no fixup protocol
+ smtp 25'' in the Pix configuration is needed. It may be possible to do
+ this by logging into the Pix (using \^telnet^\ or \^ssh^\) and typing
+ \"no fixup smtp"\ to its console. (You may need to use other commands
+ before or after to set up configuration mode and to activate a changed
+ configuration. Consult your Pix documentation or expert.) See also
+ Q0078.
+
+
+Q0054: I'm getting an Exim configuration error \*unknown rewrite flag
+ character (m) in line 386*\ but I haven't used any flags on my rewriting
+ rules.
+
+A0054: You have probably forgotten to quote a replacement string that contains
+ white space.
+
+
+Q0055: What does the error \*Failed to open wait-remote_smtp database: Invalid
+ argument*\ mean?
+
+A0055: This is something that happens if you have existing DBM hints files when
+ you install a new version of Exim that is compiled to use a different or
+ upgraded DBM library. The simplest thing to try is
+
+==> rm /var/spool/exim/db/*
+
+ This removes all the hints files. Exim will start afresh and build new
+ ones. If the symptom recurs, it suggests there is some problem with your
+ DBM library.
+
+
+Q0056: We are using Exim to send mail from our web server. However, whenever a
+ user sends an email it gets sent with the return path (envelope sender)
+ //apache@server_name.com// because the PHP script is running as
+ \/apache/\.
+
+A0056: You need to include \/apache/\ in the \trusted_users\ configuration option.
+ Only trusted users are permitted to specify senders when mail is passed
+ to Exim via the command line.
+
+
+Q0057: We've got people complaining about attachments that don't show up
+ as attachments, but are included in the body of the message.
+
+A0057: These symptoms can be seen when some software passes a CRLF line
+ terminated message via the command line to an MTA that expects lines to
+ be terminated by LF only, and so preserves the CRs as data. If you can
+ identify the software that is doing this, try setting the \-dropcr-\
+ option on the command it uses to call Exim. Alternatively, you can set
+ \drop_cr\ in the configuration file, but then that will apply to all
+ input.
+
+
+Q0058: What does the error \*failed to open DB file \(/var/spool/exim/db/retry)\:
+ File exists*\ mean?
+
+A0058: This error is most often caused when a hints file that was written with
+ one version of the Berkeley DB library is read by another version.
+ Sometimes this can happen if you change from a binary version of Exim to
+ a locally compiled version. Or it can happen if you compile and install
+ a new version of Exim after changing Berkeley DB versions. You can find
+ out which version your Exim is using by running:
+
+==> ldd /usr/sbin/exim
+
+ The solution to the problem is to delete all the files in the
+ \(/var/spool/exim/db)\ directory, and let Exim recreate them.
+
+
+Q0059: When my Outlook Express 6.0 client sends a STARTTLS command to begin a
+ TLS session, Exim doesn't seem to receive it. The Outlook log shows
+ this:
+
+==> SMTP: 14:19:27 [tx] STARTTLS
+ SMTP: 14:19:27 [rx] 500 Unsupported command.
+
+ but the Exim debugging output shows this:
+
+==> SMTP<< EHLO xxxx
+ SMTP>> 250-yyyy Hello xxxx [nnn.nnn.nnn.nnn]
+ 250-SIZE 52428800
+ 250-PIPELINING
+ 250-AUTH CRAM-MD5 PLAIN LOGIN
+ 250-STARTTLS
+ 250 HELP
+ SMTP<< QUIT
+
+A0059: Turn off scanning of outgoing email in Norton Antivirus. If you aren't
+ running Norton Antivirus, see if you are running some other kind of SMTP
+ proxying, either on the client or on a firewall between the client and
+ server. ``Unsupported command'' is not an Exim message.
+
+
+Q0060: Why am I getting the error \*failed to expand \"/data/lists/lists/${lc"\
+ for require_files: \"${lc"\ is not a known operator*\ for this setting:
+
+==> require_files = MAILMAN_HOME/lists/${lc:$local_part}/config.db
+
+A0060: The value of \"require_files"\ is a \*list*\ in which each item is
+ separately expanded. You need either to double the colon, or switch to
+ a different list separator.
+
+
+Q0061: What does the error \*Too many ``Received'' headers - suspected mail
+ loop*\ mean?
+
+A0061: Whenever a message passes through an MTA, a ::Received:: header gets
+ added. Exim counts the number of these headers in incoming messages. If
+ there are more than the value of \received_headers_max\ (default 30),
+ Exim assumes there is some kind of mail routing loop occurring. For
+ example, host A passes the message to host B, which immediately passes
+ it back to host A. Check the ::Received:: headers and the mail logs to
+ determine exactly what is going on.
+
+ One common cause of this problem is users with accounts on both systems
+ who set up each one to forward to the other, thinking that will cause
+ copies of all messages to be delivered on both of them.
+
+
+Q0062: When I try to start an Exim daemon it crashes. I ran a debugger and
+ discovered that the crash is happening in the function \^^getservbyname()^^\.
+ What's going on?
+
+A0062: What have you got in the file \(/etc/nsswitch.conf)\? If it contains this
+ line:
+
+==> services: db files
+
+ try removing the \"db"\. (Your system is trying to look in some kind of
+ database before searching the file \(/etc/services)\.)
+
+
+Q0063: When I try to start an Exim daemon, nothing happens. There is no
+ process, and nothing is written to the Exim log.
+
+A0063: Check to see if anything is written to \(syslog)\. This problem can be
+ caused by a permission problem that stops Exim from writing to its log
+ files, especially if you've specified that they should be written
+ somewhere other than under Exim's spool directory. You could also try
+ running the daemon with debugging turned on.
+
+
+Q0064: When I run \"exim -d test@domain"\ it delivers fine, but when I send a
+ message from the \^mail^\ command, I get \*User unknown*\ and the mail
+ is saved in \(dead.letter)\.
+
+A0064: It looks as if Exim isn't being called by \^mail^\; instead it is
+ calling some other program (probably Sendmail). Try running the command
+
+==> /usr/sbin/sendmail -bV
+
+ (If you get \*No such file or directory*\ or \*Command not found*\ you
+ are running Solaris or IRIX. Try again with \(/usr/lib/sendmail)\.) The
+ output should be something like this:
+
+==> Exim version 4.05 #1 built 13-Jun-2002 10:27:15
+ Copyright (c) University of Cambridge 2002
+
+ If you don't see this, your Exim installation isn't fully operational.
+ If you are running FreeBSD, see Q9201. For other systems, see Q0114.
+
+
+Q0065: When (as \/root/\) I use -C to run Exim with an alternate configuration
+ file, it gives an error about being unable to create a spool file when
+ trying to run an \%autoreply%\ transport. Why is this?
+
+A0065: When Exim is called with -C, it passes on -C to any instances of itself
+ that it calls (so that the whole sequence uses the same config file). If
+ it's running as \/exim/\ when it does this, all is well. However, if it
+ happens as a consequence of a non-privileged user running \%autoreply%\,
+ the called Exim gives up its root privilege. Then it can't write to the
+ spool.
+
+ This means that you can't use -C (even as \/root/\) to run an instance of
+ Exim that is going to try to run \%autoreply%\ from a process that is
+ neither \/root/\ nor \/exim/\. Because of the architecture of Exim (using
+ re-execs to regain privilege), there isn't any way round this
+ restriction. Therefore, the only way you can make this scenario work is
+ to run the \%autoreply%\ transport as \/exim/\ (that is, the user that
+ owns the Exim spool files). This may be satisfactory for autoreplies
+ that are essentially system-generated, but of course is no good for
+ autoreplies from unprivileged users, where you want the \%autoreply%\
+ transport to be run as the user. To get that to work with an alternate
+ configuration, you'll have to use two Exim binaries, with different
+ configuration file names in each. See S001 for a script that patches
+ the configuration name in an Exim binary.
+
+
+Q0066: What does the message \*unable to set gid=xxx or uid=xxx*\ mean?
+
+A0066: This message is given when an Exim process is unable to change uid or
+ gid when it needs to, because it does not have root privilege. This is a
+ serious problem that prevents Exim from carrying on with what it is
+ doing. The two most common situations where Exim needs to change uid/gid
+ are doing local deliveries and processing users' filter files. There are
+ two common causes of this error:
+
+ (1) You have forgotten to make the exim binary setuid to \/root/\. This
+ means that it can never change uid/gid in any situation. Also, the
+ setuid binary must reside on a disk partition that does not have the
+ \"nosuid"\ mount option set.
+
+ (2) The exim binary is setuid, but you have configured Exim so that,
+ while trying to verify an address at SMTP time, it runs a router
+ that needs to change uid/gid. Because Exim runs as \/exim/\ and not
+ \/root/\ while receiving messages, the router is unable to change
+ uid and therefore it cannot operate. The usual example of this is a
+ \%redirect%\ router for users' filter files.
+
+ Setting the \user\ or \check_local_user\ options on a \redirect\
+ router causes this to happen (except in the special case when the
+ redirection list is provided by the \data\ option and does not
+ contain \":include:"\).
+
+ The solution is to set \no_verify\ on the router that is causing the
+ problem. This means that it is skipped when an address is being
+ verified. In ``normal'' configurations where the router is indeed
+ handling users' filter files, this is quite acceptable, because you
+ do not usually need to process a filter file in order to verify that
+ the local part is valid. See, for example, the \%userforward%\
+ router in the default configuration.
+
+
+Q0067: What does the error \*too many unrecognized commands*\ mean?
+
+A0067: There have been instances of network abuse involving mail sent out by
+ web servers. In most cases, unrecognizable commands are sent as part of
+ the SMTP session. A real MTA never sends out such invalid commands. Exim
+ allows a few unrecognized commands in a session to permit humans who are
+ testing to make a few typos (it responds with a 5xx error). However, if
+ Exim receives too many such commands, it assumes that it is dealing with
+ an abuse of some kind, and so it drops the connection.
+
+
+Q0068: Exim times out when trying to connect to some hosts, though those hosts
+ are known to be up and running. What's the problem?
+
+A0068: There could be a number of reasons for this (see also Q0017). The
+ obvious one is that there is a networking problem between the hosts.
+ If you can ping between the hosts or connect in other ways, the problem
+ might be caused by ECN (Explicit Congestion Notification) being enabled
+ in your kernel. ECN uses TCP flags originally assigned to TOS - it's a
+ "new" invention, and some hosts and routers are known to be confused if
+ a client uses it. If you are running Linux, you can turn ECN off by
+ running this command:
+
+==> /bin/echo "0" > /proc/sys/net/ipv4/tcp_ecn
+
+ This has also been reported to cure web connection problems from Mozilla
+ and Netscape browsers in Linux when there were no problems with Windows
+ Netscape browsers.
+
+
+Q0069: What does the error \*SMTP data timeout (message abandoned) on connection
+ from...*\ mean?
+
+A0069: It means that there was a timeout while Exim was reading the contents of
+ a message on an incoming SMTP connection. That is, it had successfully
+ accepted a MAIL command, one or more RCPT commands, and a DATA command,
+ and was in the process of reading the data itself. The length of timeout
+ is controlled by the \smtp_receive_timeout\ option.
+
+ If you get this error regularly, the cause may be incorrect handling of
+ large packets by a router or firewall. The maximum size of a packet is
+ restricted on some links; routers should split packets that are larger.
+ There is a feature called ``path MTU discovery'' that enables a sender
+ to discover the maximum packet size over an entire path (multiple
+ Internet links). This can be broken by misconfigured firewalls and
+ routers. There is a good explanation at \?http://www.netheaven.com/pmtu.html?\.
+ Reducing the MTU on your local network can sometimes work round this
+ problem. See Q0017 (3) for further discussion.
+
+
+Q0070: What does the error \*SMTP command timeout on connection from...*\ mean?
+
+A0070: Exim was expecting to read an SMTP command from the client, but no
+ command was read within the \smtp_receive_timeout\ time limit.
+
+
+Q0071: What does the error \*failed to open DB file \(/var/spool/exim//db/retry)\:
+ Illegal argument*\ mean?
+
+A0071: See Q0058. The cause of this error is usually the same.
+
+
+Q0072: Exim will deliver to normal aliases, and aliases that are pipes or
+ files, but it objects to aliases that involve \":include:"\ items,
+ complaining that it can't change gid or uid. Why is this?
+
+A0072: See Q0066 for a general answer. The problem happens during verification
+ of an incoming SMTP message, not during delivery itself. In this
+ particular case, you must have set up your aliasing router with a \user\
+ setting. This causes Exim to change uid/gid when reading \":include:"\
+ files. If you do not need the detailed verification provided by the
+ router, the easy solution is to set \no_verify\ so that the router isn't
+ used during verification.
+
+ Otherwise, if you set \user\ on the router in order to provide a user
+ for delivery to pipes or files, one solution is to put the \user\
+ setting on the transports instead of on the router. You may need to
+ create some special transports just for this router. The alternative is
+ to supply two different routers, one with \user\ and \no_verify\, and
+ the with \verify_only\ but no \user\ setting.
+
+
+Q0073: I'm seeing log file corruption, with parts of log lines getting mangled
+ by other log entries.
+
+A0073: The only time this has been seen is when several servers were writing to
+ the same log files over NFS. Exim assumes that its log file is on local
+ disk, and using NFS, especially for more than one server, will not work.
+
+
+Q0074: What does the error message \*remote delivery process count got out of
+ step*\ mean?
+
+A0074: Exim uses subprocesses for remote deliveries; this error means that the
+ master process expected to have a child process running, but found there
+ were none. Prior to release 4.11, this error could be caused by running
+ Exim under \^strace^\ on a Linux system, because stracing causes
+ children to be ``stolen'' such that a parent that tries to wait for
+ ``any of my children'' is told that it has none. Current releases of
+ Exim have code to get round this problem.
+
+
+Q0075: I'm using LDAP, and some email addresses that contain special characters
+ are causing parsing errors in my LDAP lookups.
+
+A0075: You should be using \"${quote_ldap:$local_part}"\ instead of just
+ \"$local_part"\ in your lookups.
+
+
+Q0076: I've configured Exim to use \^syslog^\ for its logs, with the main and
+ reject logs sent to different files, but whenever a message is rejected,
+ I get one message on the reject log and two messages on the main log.
+
+A0076: You are probably putting your reject items into the main log as well;
+ remember \^syslog^\ levels are inclusive (for example, \"mail.info"\
+ includes all higher levels, so a \"mail.notice"\ message will be caught
+ by a \"mail.info"\ descriptor).
+ Test this by running the command:
+
+==> logger -p mail.notice test
+
+ and seeing which logs it goes into.
+
+
+Q0077: I've installed Exim and it is delivering mail just fine. However, when I
+ try to read mail from my PC I get \*connection rejected*\ or \*unable to
+ connect*\.
+
+A0077: See Q5021.
+
+
+Q0078: Exim is logging the unknown SMTP command \"XXXX"\ from my client hosts,
+ and they are unable to authenticate.
+
+A0078: This is a sign of a Cisco PIX firewall getting in the way. It does not
+ support ESMTP, and turns EHLO commands into XXXX. You should configure
+ the Pix to leave SMTP alone; see Q0053 for how to do this.
+
+
+Q0079: Our new PIX firewall is causing problems with incoming mail. How can
+ this be fixed?
+
+A0079: See Q0053 and Q0078. If some messages get through and others do not,
+ see also Q0017.
+
+
+Q0080: Am I to understand that the database lookups must only return one value?
+ They can not return a list of values? The documentation seems to
+ indicate that it's possible to return a list.
+
+A0080: Lookups can be used in two different situations, and what they return is
+ different in the two cases. (Be thankful Exim 3 is gone; there was yet
+ another case!)
+
+ (1) You can use a lookup in any expanded string. The syntax is
+
+==> ${lookup ..... }
+
+ In this case, whatever is looked up replaces the expansion item. It
+ may be one value or a list of values. Whether a single value or a
+ list is acceptable or not depends on where you are using the string
+ expansion. If it is for an option that expects just one value, then
+ only one value is allowed (for example).
+
+ (2) You can make use of the lookup mechanism to test whether something
+ (typically a host name or IP address) is in a list. For example,
+
+==> hosts = a : b : c
+
+ in an ACL tests whether the calling host's name matches ``a'', or
+ ``b'', or ``c''. Now, suppose you want to keep the list of names in
+ a database, or cdb file, or NIS map, or... By writing
+
+==> hosts = pgsql;select ....
+
+ you are saying to Exim: ``Run this lookup; if it succeeds, behave as
+ if the host is in the list; if it fails, the host is not in the
+ list.'' You are using the indexing mechanism of the database as a
+ fast way of checking a list. A simpler example is
+
+==> hosts = lsearch;/some/file
+
+ where the file contains the list of hosts to be searched.
+
+ The complication happens when a list is first expanded before being
+ interpreted as a list. This happens in a lot of cases. You can therefore
+ write either of these:
+
+==> hosts = cdb;/some/file
+ hosts = ${lookup{something}cdb{/some/file}}
+
+ but they have different meanings. The first means ``see if the host name
+ is in the list in this file''. The second means ``run this lookup and
+ use the result of the lookup as a list of host items to check''. In the
+ second case, the list could contain multiple values (colon separated),
+ and one of those values could even be ``cdb;/some/file''.
+
+ Flexibility does lead to complexity, I'm afraid.
+
+
+Q0081: What does \*error in redirect data: included file xxxx is too big*\
+ mean?
+
+A0081: You are trying to include a very large file in a redirection list, using
+ the \":include:"\ feature. Exim has a built-in limit on the size, as a
+ safety precaution. The default is 1 megabyte. If you want to increase
+ this, you have to rebuild Exim. In your \(Local/Makefile)\, put
+
+==> MAX_INCLUDE_SIZE = whatever
+
+ and then rebuild Exim. The value is a number of bytes, but you can give
+ it as a parenthesized arithmetic expression such as \"(3*1024*1024)"\.
+ However, an included file of more than a megabyte is likely to be quite
+ inefficient. How many addresses does yours contain? You get the best
+ performance out of Exim if you arrange to send mailing list messages
+ with no more than about 100 recipients (in order to get parallelism in
+ the routing).
+
+
+Q0082: What does \*relocation error: /lib/libnss_dns.so.2: symbol
+ __libc_res_nquery, version GLIBC_PRIVATE not defined in file
+ libresolv.so.2 with link time reference*\ mean?
+
+A0082: You have updated \^glibc^\ while an Exim daemon is running. Stop and
+ restart the daemon.
+
+
+Q0083: Netscape on Unix is sending messages containing an unqualified user name
+ in the ::Sender:: header line, which Exim is rejecting because I have
+ set \"verify = header_syntax"\. How can I fix this?
+
+A0083: The only thing you can do in Exim is to set the
+ \sender_unqualified_hosts\ option to allow unqualified sender addresses
+ form the relevant hosts; of course, this applies to all sender
+ addresses, not just the ::Sender:: header line.
+
+ Alternatively, you can configure Netscape not to include the header line
+ in the first place. Add the following line to the
+ \($HOME/.netscape/preferences.js)\ and \($HOME/.netscape/liprefs.js)\
+ files:
+
+==> user_pref("mail.suppress_sender_header", true);
+
+ Netscape \*must*\ be shutdown while doing this.
+
+
+Q0084: I want to set up an alias that pipes a message to \^gpg^\ and then pipes
+ the result to \^mailx^\ to resubmit the message, but when I use my
+ tested command in an alias file, I get an error from \^gpg^\.
+
+A0084: Probably you are using a shell command with two pipe symbols in it. An
+ alias like this:
+
+==> gpg-xxx: "|gpg <options> | mailx <options"
+
+ does not work, because Exim does not run pipes under a shell by default.
+ You must call a shell explicitly if you want to make use of the shell's
+ features for double-piping, either by piping to \"/bin/sh"\ with a
+ suitable \"-c"\ option, or by piping to a shell script.
+
+
+Q0085: I see a lot of \*rejected EHLO ... syntactically invalid argument(s)*\.
+ I know it's because of the underscore in the host name, but is there a
+ switch to allow Exim to accept mail from such hosts?
+
+A0085: Yes. Add this to your configuration:
+
+==> helo_allow_chars = _
+
+ For more seriously malformed host names, see \helo_accept_junk_hosts\.
+ See also Q0732.
+
+
+Q0086: What does \*SMTP protocol violation: synchronization error (next input
+ sent too soon)*\ mean?
+
+A0086: SMTP is a ``lock-step'' protocol, which means that, at certain points in
+ the protocol, the client must wait for the server to respond before
+ sending more data. Exim checks for correct behaviour, and issues this
+ error if the client sends data too soon. This protects against
+ malefactious clients who send a bunch of SMTP commands (usually to
+ transmit spam) without waiting for any replies.
+
+ This error is also provoked if the client is trying to start up a TLS
+ session immediately on connection, without using the STARTTLS command.
+ See Q1707 for a discussion of this case.
+
+
+Q0087: What does \*rejected after DATA: malformed address: xx@yy may not follow
+ <xx@yy> : failing address in "from" header*\ mean? (I've obscured the
+ real email addresses.)
+
+A0087: Your DATA ACL contains
+
+==> verify = header_syntax
+
+ and an incoming message contained the line
+
+==> From: xx@yy <xx@yy>
+
+ This is syntactically invalid. The contents of an address in a header
+ line are either just the address, or a ``phrase'' followed by an address
+ in angle brackets. In the latter case, the ``phrase'' must be quoted if
+ it contains special characters such as @. The following are valid
+ versions of the bad header:
+
+==> From: xx@yy
+ From: "xx@yy" <xx@yy>
+
+ though why on earth anything generates this kind of redundant nonsense I
+ can't think.
+
+
+Q0088: The Windows mailer SENDFILE.EXE sometimes hangs while trying to send a
+ message to Exim 4, and eventually times out. It worked flawlessly with
+ Exim 3. What has changed?
+
+A0088: Exim 4 sets an obscure TCP/IP parameter called TCP_NODELAY. This
+ disables the "Nagle algorithm" for the TCP/IP transmission. The Nagle
+ algorithm can improve network performance in interactive situations such
+ as a human typing at a keyboard, by buffering up outgoing data until the
+ previous packet has been acknowledged, and thereby reducing the number
+ of packets used. This is not relevant for mail transmission, which
+ mostly consists of quite large blocks of data; setting TCP_NODELAY
+ should improve performance. However, it seems that some Windows clients
+ do not function correctly if the server turns off the Nagle algorithm.
+ If you are using Exim 4.23 or later, you can set
+
+==> tcp_nodelay = false
+
+ This stops Exim setting TCP_NODELAY on the sockets created by the
+ listening daemon.
+
+
+Q0089: What does the error \*kernel: application bug: exim(12099) has SIGCHLD
+ set to SIG_IGN but calls wait()*\ mean?
+
+A0089: This was a bad interaction between a relatively recent change to the
+ Linux kernel and some ``belt and braces'' programming in Exim. The
+ following explanation is taken from Exim's change log:
+
+ When Exim is receiving multiple messages on a single connection, and
+ spinning off delivery processess, it sets the SIGCHLD signal handling to
+ SIG_IGN, because it doesn't want to wait for these processes. However,
+ because on some OS this didn't work, it also has a paranoid call to
+ \^waitpid()^\ in the loop to reap any children that have finished. Some
+ versions of Linux now complain (to the system log) about this
+ ``illogical'' call to \^waitpid()^\. I have therefore put it inside a
+ conditional compilation, and arranged for it to be omitted for Linux.
+
+ I am pretty sure I caught all the places in Exim where this happened.
+ However, there are still occasional reports of this error. I have not
+ heard of any resolutions, but my current belief is that they are caused
+ by something that Exim calls falling foul of the same check. There was
+ at one time a suspicion that the IPv6 stack was involved.
+
+
+Q0090: I can't seem to get a pipe command to run when I include a \"${lookup"\
+ expansion in it.
+
+A0090: See Q0025.
+
+
+Q0091: Why is Exim giving the error \*Failed to send message from address_reply
+ transport*\ when I run it using -C to specify an alternate
+ configuration?
+
+A0091: See Q0065.
+
+
+
+1. BUILDING AND INSTALLING
+
+Q0101: I'm having a problem with an Exim RPM.
+
+A0101: Normally the thing to do if you have a problem with an RPM package is
+ to contact the person who built the package first, not the person who
+ made the software that's in the package. You can usually find out who
+ made a package using the following command:
+
+==> rpm --query --package --queryformat '%{PACKAGER}\n' <rpm-package-file>
+
+ where \[rpm-package-file]\ is the actual file, e.g. \(exim-3.03-2.i386.rpm)\.
+ Or, if the package is installed on your system:
+
+==> rpm --query --queryformat '%{PACKAGER}\n' <package-name>
+
+ where \[package-name]\ is the name component of the package, e.g. \"exim"\.
+ If the packager is unable or unwilling to help, only then should you
+ contact the actual author or associated mailing list of the software.
+
+ If you discover through the querying process that you can't tell who
+ the person (or company or group) is who built the package, or that they
+ no longer exist at the given address, then you should reconsider
+ whether you want a package from an unknown source on your system.
+
+ If you discover through the querying process that you yourself are the
+ person who built the package, then you should either (a) contact the
+ author or associated mailing list, or (b) reconsider whether you ought
+ to be building and distributing RPM packages of software you don't
+ understand.
+
+ Similar rules of thumb govern other binary package formats, including
+ debs, tarballs, and POSIX packages.
+
+
+Q0102: I can't get Exim to compile with Berkeley DB version 2.x or 3.x.
+
+A0102: Have you set \"USE_DB=yes\" in \(Local/Makefile)\? This causes Exim to use the
+ native interface to the DBM library instead of the compatibility
+ interface, which needs a header called \(ndbm.h)\ that may not exist on your
+ system.
+
+
+Q0103: I'm getting an \*undefined symbol*\ error for \"hosts_ctl"\ when I try to
+ build Exim. (On some systems this error is \*undefined reference to
+ 'hosts_ctl'*\.)
+
+A0103: You should either remove the definition of \\USE_TCP_WRAPPERS\\ or add
+ \"-lwrap"\ to your \\EXTRALIBS\\ setting in Local/Makefile.
+
+
+Q0104: I'm about to upgrade to a new Exim release. Do I need to ensure the
+ spool is empty, or take any other special action?
+
+A0104: It depends on where you are coming from.
+
+ (1) If you are changing to release 4.00 or later from a release prior to
+ 4.00, you will need to make changes to the run time configuration file.
+ See the file \(doc/Exim4.upgrade)\ for details. If you are coming from
+ before release 3.00, you should also see \(doc/Exim3.upgrade)\.
+
+ (2) If you are upgrading from an Exim 4 release to a later release, you
+ do not need to take special action. New releases are made backwards
+ compatible with old spool files and hints databases, so that upgrading
+ can be done on a running system. All that should be necessary is to
+ install a new binary and then HUP the daemon.
+
+
+Q0105: What does the error \*install-info: command not found*\ mean?
+
+A0105: You have set \\INFO_DIRECTORY\\ in your \(Local/Makefile)\, and Exim is trying
+ to install the Texinfo documentation, but cannot find the command called
+ \(install-info)\. If you have a version of Texinfo prior to 3.9, you
+ should upgrade. Otherwise, check your installation of Texinfo to see why
+ the \(install-info)\ command is not available.
+
+
+Q0106: Exim doesn't seem to be recognizing my operating system type correctly,
+ and so is failing to build.
+
+A0106: Run the command \"scripts/os-type -generic"\. The output should be one of
+ the known OS types, and should correspond to your operating system. You
+ can see which OS are supported by obeying \"ls OS/Makefile-*"\ and looking
+ at the file name suffixes.
+
+ If there is a discrepancy, it means that the script is failing to
+ interpret the output from the \"uname"\ command correctly, or that the
+ output is wrong. Meanwhile, you can build Exim by obeying
+
+==> EXIM_OSTYPE=xxxx make
+
+ instead of just \"make"\, provided you are running a Bourne-compatible
+ shell, or otherwise by setting \\EXIM_OSTYPE\\ correctly in your
+ environment. It is probably best to start again from a clean
+ distribution, to avoid any wreckage left over from the failed attempt.
+
+
+Q0107: Exim fails to build, complaining about the absence of the \"killpg"\
+ function.
+
+A0107: This function should be present in all modern flavours of Unix. If you
+ are using an older version, you should be able to get round the problem
+ by inserting
+
+==> #define killpg(pgid,sig) kill(-(pgid),sig)
+
+ into the file called \(OS/os.h-xxx)\, where xxx identifies your operating
+ system, and is the output of the command \"scripts/os-type -generic"\.
+
+
+Q0108: I'm getting an unresolved symbol \"ldap_is_ldap_url"\ when trying to build
+ Exim.
+
+A0108: You must have specified \"LOOKUP_LDAP=yes"\ in the configuration. Have you
+ remembered to set \"-lldap"\ somewhere (e.g. in \\LOOKUP_LIBS\\)? You need that
+ in order to get the LDAP library scanned when linking.
+
+
+Q0109: I'm getting an unresolved symbol \"mysql_close"\ when trying to build Exim.
+
+A0109: You must have specified \"LOOKUP_MYSQL=yes"\ in the configuration. Have you
+ remembered to set \"-lmysqlclient"\ somewhere (e.g. in \\LOOKUP_LIBS\\)? You
+ need that in order to get the MySQL library scanned when linking.
+
+
+Q0110: I'm trying to build Exim with PAM support. I have included \"-lpam"\ in
+ \\EXTRALIBS\\, but I'm still getting a linking error:
+
+==> /lib/libpam.so: undefined reference to `dlerror'
+ /lib/libpam.so: undefined reference to `dlclose'
+ /lib/libpam.so: undefined reference to `dlopen'
+ /lib/libpam.so: undefined reference to `dlsym'
+
+A0110: Add \"-ldl"\ to \\EXTRALIBS\\. In some systems these dynamic loading functions
+ are in their own library.
+
+
+Q0111: I'm getting the error \*db.h: No such file or directory*\ when I try to
+ build Exim.
+
+A0111: This problem has been seen with RedHat 7.0, but could also happen in
+ other environments. If your system is using the DB library, you
+ need to install the DB development package in order to build Exim.
+ The package is called something like \"db3-devel-3.1.14-16.i386.rpm"\ for
+ Linux systems, but you should check which version of DB you have
+ installed (current releases are DB 4).
+
+
+Q0112: I'm getting the error \*/usr/bin/ld: cannot find -ldb*\ when I try to
+ build Exim.
+
+A0112: This is probably the same problem as Q0111.
+
+
+Q0113: I've compiled Exim and I've managed to start it but there was one
+ problem - it always complained that \(libmsqlclient.so.10)\ was not found,
+ even though this file is in \(/usr/local/lib/mysql/)\.
+
+A0113: Solaris: ensure you have this in your \(Local/Makefile)\:
+
+==> LOOKUP_LIBS=-L/usr/local/lib/mysql -R/usr/local/lib/mysql
+
+ Net/Open/FreeBSD: Run this command (or ensure it gets run automatically
+ at boot time):
+
+==> ldconfig -m /usr/local/lib/mysql
+
+ Linux: add \(/usr/local/lib/mysql)\ to \(/etc/ld.so.conf)\ and re-run \(ldconfig)\.
+ Alternatively, add
+
+==> -Wl,-rpath -Wl,/usr/local/lib/mysql
+
+ to EXTRA_LIBS and then re-link (this is similar to the Solaris solution
+ above). This will probably also work on other systems that use GNU
+ Binutils.
+
+
+Q0114: How can I remove Sendmail from my system? I've built Exim and run \"make
+ install"\, but it still doesn't seem to be fully operational.
+
+A0114: If you are running FreeBSD, see Q9201. Otherwise, you need to arrange
+ that whichever of the paths \(/usr/sbin/sendmail)\ or \(/usr/lib/sendmail)\
+ exists on your system is changed to refer to Exim. For example, you
+ could use these commands (as \/root/\):
+
+==> mv /usr/sbin/sendmail /usr/sbin/sendmail.original
+ chmod u-s /usr/sbin/sendmail.original
+ ln -s /path/to/exim /usr/sbin/sendmail
+
+ The second command removes the setuid privilege from the old MTA, as a
+ general safety precaution. In the third command, substitute the actual
+ path to the Exim binary for \(/path/to/exim)\.
+
+
+Q0115: What does \*Can't open \(../scripts/newer)\: No such file or directory*\
+ mean? I got it while trying to build Exim.
+
+A0115: You are using FreeBSD, or another OS that has a \^make^\ command which
+ tries to optimize the running of commands. Exim's \(Makefile)\ contains
+ targets with sequential commands like this:
+
+==> buildpcre:
+ @cd pcre; $(MAKE) SHELL=$(SHELL) AR="$(AR)" $(MFLAGS) CC="$(CC)" \
+ CFLAGS="$(CFLAGS) $(PCRE_CFLAGS)" \
+ RANLIB="$(RANLIB)" HDRS="$(PHDRS)" \
+ INCLUDE="$(INCLUDE) $(IPV6_INCLUDE) $(TLS_INCLUDE)"
+ @if $(SHELL) $(SCRIPTS)/newer pcre/libpcre.a exim; then \
+ /bin/rm -f exim eximon.bin; fi
+
+ The second command assumes that the \"cd pcre"\ in the first command is
+ no longer in effect. If you have \"-j3"\ in your default set of
+ \"MAKEFLAGS"\, FreeBSD \^make^\ tries to optimize, and ends up up with both
+ commands in the same shell process. The result is that \"$(SCRIPTS)"\
+ (which has a value of \"../scripts"\) is not found.
+
+ The simplest solution is to force \^make^\ to use backwards compatibility
+ mode with each command in its own shell, by using the \-B\ flag. To
+ ensure that this happens throughout the build, it's best to export it in
+ your environment:
+
+==> MAKEFLAGS='-B'
+ export MAKEFLAGS
+ make
+
+
+Q0116: I have tried to build Exim with Berkeley DB 3 and 4, but I always get
+ errors.
+
+A0116: One common problem, especially when you have several different versions
+ of BDB installed on the same host, is that the header files and library
+ files for BDB are not in a standard place. You therefore need to tell
+ Exim where they are, by setting INCLUDE and DBMLIB in your
+ \(Local/Makefile)\. For example, I use this on my workstation when
+ I want to build with DB 4.1:
+
+==> INCLUDE=-I/opt/local/include/db-4.1
+ DBMLIB=/opt/local/lib/db-4.1/libdb.a
+
+ Specifying the complete library file like this will cause it to be
+ statically linked with Exim. You'll have to check to see where these
+ files are on your system. For example, on FreeBSD 5, the header is in
+ \(/usr/local/include/db4)\ and the library is in \(/usr/local/lib)\ and
+ called \(libdb4)\. In that environment, you could use:
+
+==> INCLUDE=-I/usr/local/include/db4
+ DBMLIB=-L/usr/local/lib -ldb4
+
+ This time, DBMLIB is specifying the library directory (\(/usr/local/lib)\)
+ and the name of the library (\(db4)\) separately. The name of the actual
+ library file is \(/usr/local/lib/libdb4.something)\. If the library was
+ compiled for dynamic linking, that will be used.
+
+
+Q0117: Is there a quick walk-through of an Exim install from source anywhere?
+
+A0117: Here! This is a contribution from a RedHat user, somewhat edited. On
+ other operating systems things may be slightly different, but the
+ general approach is the same.
+
+ (1) Install the db needed for Exim. This needs to be done first if you
+ don't have a DBM library installed. Go to \?http://www.sleepycat.com?\
+ and download \(db-4.1.25.tar.gz)\, or whatever the current release is.
+ Then:
+
+==> gunzip db-4.1.25.tar.gz
+ tar -xvf db-4.1.25.tar
+ cd db-4.1.25
+ cd build_unix
+ ../dist/configure
+ make
+ make install
+
+ (2) Add a user for use by Exim, unless you want to use an existing user
+ such as \/mail/\:
+
+==> adduser exim
+
+ (3) Now you can prepare to build Exim. Go to \?http://www.exim.org?\ or
+ one of its mirrors, or the master ftp site
+ \?ftp://ftp.csx.cam.ac.uk/pub/software/email/exim/exim4?\, and download
+ \(exim-4.20.tar.gz)\ or whatever the current release is. Then:
+
+==> gunzip exim-4.20.tar.gz
+ tar -xvf exim-4.20.tar
+ cd exim-4.20
+ cp src/EDITME Local/Makefile
+ cp exim_monitor/EDITME Local/eximon.conf
+
+ (4) Edit \(Local/Makefile)\:
+
+ Comment out EXIM_MONITOR= unless you want to install the Exim
+ monitor (it requires X-windows).
+
+ Set the user you want Exim to use for itself:
+
+==> EXIM_USER=exim
+
+ If your DBM library is Berkeley DB, set up to use its native interface:
+
+==> USE_DB=yes
+
+ Make sure Exim's build can find the DBM library and its headers. If
+ you've installed Berkeley DB 4 you'll need to have settings like this
+ in \(Local/Makefile)\:
+
+==> INCLUDE=-I/usr/local/BerkeleyDB.4.1/include
+ DBMLIB=/usr/local/BerkeleyDB.4.1/lib/libdb.a
+
+ (Check that the first directory contains the db.h file and that the
+ second library exists.)
+
+ You don't need to change anything else, but you might want to review
+ the default settings in the ``must specify'' section.
+
+ (4) Build Exim by running the \/make/\ command.
+
+ (5) Install Exim by running, as \/root/\:
+
+==> make install
+
+ You \*must*\ be \/root/\ to do this. You do not have to be root for any of
+ the previous building activity.
+
+ (6) Run some tests on Exim; see if it will do local and remote
+ deliveries. Change the configuration if necessary (for example,
+ uncommenting \group\ on the \%local_delivery%\ transport if you don't
+ use a ``sticky bit'' directory).
+
+ (7) Change Sendmail to Exim (of course you need to have had Sendmail
+ installed to do this).
+
+==> /etc/init.d/sendmail stop
+ mv /usr/sbin/sendmail /usr/sbin/sendmail.org
+ ln -s /usr/exim/bin/exim /usr/sbin/sendmail
+ /etc/init.d/sendmail start
+
+ (8) Check the Exim log. Either use the Exim monitor, or:
+
+==> tail -f /var/spool/exim/log/mainlog
+
+
+Q0118: I've set \"LOOKUP_INCLUDE=-I/client/include"\ in Local/Makefile, but the
+ compilation of \^exim_dumpdb^\ is ignoring this option and failing. Why?
+
+A0118: LOOKUP_INCLUDE is the special include file for lookup modules in Exim
+ (e.g. mysql, LDAP). Confusingly, it doesn't apply to basic DBM code
+ which is used also for other things. Try setting INCLUDE and DBMLIB
+ instead. For example:
+
+==> USE_DB=yes
+ INCLUDE=-I/client/include
+ DBMLIB=/client/lib/libdb.a
+
+
+Q0119: I know there are some 3rd-party patches for Exim, for exiscan and
+ other things. Where are they?
+
+A0119: Exiscan is at \?http://duncanthrax.net/exiscan-acl/?\.
+[[br]]
+ Scanexi is at \?http://w1.231.telia.com/~u23107873/scanexi.html?\
+[[br]]
+ A sample \^^local_scan()^^\ function for interfacing to \^uvscan^\ is
+ at \?http://www.dcs.qmul.ac.uk/~mb/local_scan/?\.
+[[br]]
+ An interface to SpamAssassin at SMTP time is at
+ \?http://marc.merlins.org/linux/exim/sa.html?\.
+[[br]]
+ A mini-HOWTO (PDF file) about scanning and virus scanning, and some RPMs
+ can be found at \?http://www.timj.co.uk/linux/exim.php?\.
+
+
+
+2. ROUTING IN GENERAL
+
+Q0201: How can I arrange that messages larger than some limit are handled by
+ a special router?
+
+A0201: You can use a \condition\ option on the router line this:
+
+==> condition = ${if >{$message_size}{100K}{yes}{no}}
+
+
+Q0202: Can I specify a list of domains to explicitly reject?
+
+A0202: Set up a named domain list containing the domains in the first section
+ of the configuration, for example:
+
+==> domainlist reject_domains = list:of:domains:to:reject
+
+ You can use this list in an ACL to reject any SMTP recipients in those
+ domains. You can also give a customized error message, like this:
+
+==> deny message = The domain $domain is no longer supported
+ domains = +reject_domains
+
+ If you also want to reject these domains in messages that are submitted
+ from the command line (not using SMTP), you need to set up a router to
+ do it, like this:
+
+==> reject_domains:
+ driver = redirect
+ domains = +reject_domains
+ allow_fail
+ data = :fail: The domain $domain is no longer supported
+
+
+Q0203: How can I arrange to do my own qualification of non-fully-qualified
+ domains, and then pass them on to the next router?
+
+A0203: If you have some list of domains that you want to qualify, you can do
+ this using a redirect router. For example,
+
+==> qualify:
+ driver = redirect
+ domains = *.a.b
+ data = ${quote:$local_part}@$domain.c.com
+
+ This adds \".c.com"\ to any domain that matches \"*.a.b"\.
+ If you want to do this in conjunction with a \%dnslookup%\ router, the
+ \widen_domains\ option of that router may be another way of achieving
+ what you want.
+
+
+Q0204: Every system has a \"nobody"\ account under which httpd etc run. I would
+ like to know how to restrict mail which comes from that account to users
+ on that host only.
+
+A0204: Set up a first router like this:
+
+==> fail_nobody:
+ driver = redirect
+ senders = nobody@your.domain
+ domains = ! +local_domains
+ allow_fail
+ data = :fail: Nobody may not mail off-site
+
+ This assumes you have defined \+local_domains\ as in the default
+ configuration.
+
+
+Q0205: How can I get Exim to deliver to me locally and everyone else at the same
+ domain via SMTP to the MX record specified host?
+
+A0205: Create an \%accept%\ router to pick off the one address and pass it to
+ an appropriate transport. Put this router before the one that does MX
+ routing:
+
+==> me:
+ driver = accept
+ domains = dom.com
+ local_parts = me
+ transport = local_delivery
+
+ In the transport you will have to specify the \user\ option. An
+ alternative way of doing this is to add a condition to the router that
+ does MX lookups to make it skip your address. Subsequent routers can then
+ deliver your address locally. You'll need a condition like this:
+
+==> condition = \
+ ${if and {{eq{$domain}{dom.com}}{eq{$local_part}{me}}}{no}{yes}}
+
+
+Q0206: How can I get Exim to deliver certain domains to a different SMTP port
+ on my local host?
+
+A0206: You must set up a special \%smtp%\ transport, where you can specify the
+ \port\ option, and then set up a router to route the domains to that
+ transport. There are two possibilities for specifying the host:
+
+ (1) If you use a \%manualroute%\ router, you can specify the local host
+ in the router options. You must also set
+
+==> self = send
+
+ so that it does not object to sending to the local host.
+
+ (2) If you use a router that cannot specify hosts (for example, an
+ \%accept%\ router with appropriate conditions), you have to specify
+ the host using the \hosts\ option of the transport. In this case,
+ you must also set \allow_localhost\ on the transport.
+
+
+Q0207: Why does Exim lower-case the local-part of a non-local domain when
+ routing?
+
+A0207: Because \caseful_local_part\ is not set (in the default configuration)
+ for the \%dnslookup%\ router. This does not matter because the local
+ part takes no part in the routing, and the actual local part that is
+ sent out in the RCPT command is always the original local part.
+
+
+
+3. ROUTING TO REMOTE HOSTS
+
+Q0301: What do \*lowest numbered MX record points to local host*\ and \*remote
+ host address is the local host*\ mean?
+
+A0301: They mean exactly what they say. Exim expected to route an address to a
+ remote host, but the IP address it obtained from a router was for the
+ local host. If you really do want to send over TCP/IP to the local host
+ (to a different version of Exim or another MTA, for example), see Q0206.
+
+ More commonly, these errors arise when Exim thinks it is routing some
+ foreign domain. For example, the router configuration causes Exim to
+ look up the domain in the DNS, but when Exim examines the DNS output,
+ either the lowest numbered MX record points at the local host, or there
+ are no MX records, and the address record for the domain contains an
+ IP address that belongs to the local host.
+
+ There has been a rash of instances of domains being deliberately set up
+ with MX records pointing to \"localhost"\ (or other names with A records
+ that specify 127.0.0.1), which causes this behaviour. You can use the
+ \ignore_target_hosts\ option to get Exim to ignore these records. The
+ default contiguration does this. For more discussion, see Q0319. For
+ other cases:
+
+ (1) If the domain is meant to be handled as a local domain, there
+ is a problem with the configuration, because it should not then have
+ been looked up in the DNS. Check the \domains\ settings on your
+ routers.
+
+ (2) If the domain is one for which the local host is providing a
+ relaying service (called ``mail hubbing''), possibly as part of a
+ firewall, you need to set up a router to tell Exim where to send
+ messages addressed to this domain, because the DNS directs them to
+ the local host. You should put a router like this one before the one
+ that does DNS lookups:
+
+==> hubbed_hosts:
+ driver = manualroute
+ transport = remote_smtp
+ route_list = see discussion below
+
+ The contents of the \route_list\ option depend on how many hosts you
+ are hubbing for, and how their names are related to the domain name.
+ Suppose the local host is a firewall, and all the domains in
+ \(*.foo.bar)\ have MX records pointing to it, and each domain
+ corresponds to a host of the same name. Then the setting could be
+
+==> route_list = *.foo.bar $domain
+
+ If there isn't a convenient relationship between the domain names
+ and the host names, you either have to list each domain separately,
+ or use a lookup expansion to look up the host from the domain, or
+ put the routing information in a file and use the \route_data\
+ option with a lookup expansion.
+
+ (3) If neither (1) nor (2) is the case, the lowest numbered MX record or
+ the address record for the domain should not be pointing to your
+ host. You should arrange to get the DNS mended.
+
+
+Q0302: Why does Exim say \*all relevant MX records point to non-existent hosts*\
+ when MX records point to IP addresses?
+
+A0302: MX records cannot point to IP addresses. They are defined to point to
+ host names, so Exim always interprets them that way. (An IP address is a
+ syntactically valid host name.) The DNS for the domain you are having
+ problems with is misconfigured.
+
+ However, it appears that more and more DNS zones are breaking the rules
+ and putting IP addresses on the RHS of MX records. Exim follows the
+ rules and rejects this, but other MTAs do support it, so the
+ \allow_mx_to_ip\ was regretfully added at release 3.14 to permit this
+ heinous activity.
+
+
+Q0303: How do I configure Exim to send all messages to a central server? I
+ don't want to do any local deliveries at all on this host.
+
+A0303: Use this as your first and only router:
+
+==> send_to_gateway:
+ driver = manualroute
+ transport = remote_smtp
+ route_list = * central.server.host
+
+
+Q0304: How do I configure Exim to send all non-local mail to a gateway host?
+
+A0304: Replace the \%dnslookup%\ router in the default configuration with the
+ following:
+
+==> send_to_gateway:
+ driver = manualroute
+ domains = !+local_domains
+ transport = remote_smtp
+ route_list = * gate.way.host
+
+ If there are several hosts you can send to, you can specify them as a
+ colon-separated list.
+
+
+Q0305: How can I arrange for mail on my local network to be delivered directly
+ to the relevant hosts, but all other mail to be sent to my ISP's mail
+ server? The local hosts are all DNS-registered and behave like normal
+ Internet hosts.
+
+A0305: Set up a first router to pick off all the domains for your local
+ network. There are several ways you might do this. For example
+
+==> local_network:
+ driver = dnslookup
+ transport = remote_smtp
+ domains = *.mydomain.com
+
+ This does a perfectly conventional DNS routing operation, but only for
+ the domains that match \(*.mydomain.com)\. Follow this with a `smart
+ host' router:
+
+==> internet:
+ driver = manualroute
+ domains = !+local_domains
+ transport = remote_smtp
+ route_list = * mail.isp.net
+
+ This routes any other non-local domains to the smart host.
+
+
+Q0306: How do I configure Exim to send all non-local mail to a central server
+ if it cannot be immediately delivered by my host? I don't want to have
+ queued mail waiting on my host.
+
+A0306: Add to the \%remote_smtp%\ transport the following:
+
+==> fallback_hosts = central.server.name(s)
+
+ If there are several names, they must be separated by colons.
+
+
+Q0307: The \route_list\ setting \"^foo$:^bar$ $domain"\ in a \%manualroute%\
+ router does not work.
+
+A0307: The first thing in a \route_list\ item is a single pattern, not a list of
+ patterns. You need to write that as \"^(foo|bar)$ $domain"\.
+ Alternatively, you could use several items and write
+
+==> route_list = foo $domain; bar $domain
+
+ Note the semicolon separator. This is because the second thing in each
+ item can itself be a list - of hosts.
+
+
+Q0308: I have a domain for which some local parts must be delivered locally,
+ but the remainder are to be treated like any other remote addresses.
+
+A0308: One possible way of doing this is as follows: Assuming you are using a
+ configuration that is similar to the default one, first exclude your
+ domain from the first router by changing it to look like this:
+
+==> non_special_remote:
+ driver = dnslookup
+ domains = ! +local_domains : ! special.domain
+ transport = remote_smtp
+ ignore_target_hosts = 127.0.0.0/8
+ no_more
+
+ Then add a second router which handles the local parts that are not to
+ be delivered locally:
+
+==> special_remote:
+ driver = dnslookup
+ domains = special.domain
+ local_parts = ! lsearch;/list/of/special/localparts
+ transport = remote_smtp
+ ignore_target_hosts = 127.0.0.0/8
+ no_more
+
+ The remaining local parts will fall through to the remaining routers,
+ which can delivery them locally.
+
+
+Q0309: How can I configure Exim on a firewall machine so that if mail arrives
+ addressed to a domain whose MX points to the firewall, it is forwarded
+ to the internal mail server, without having to have a list of all the
+ domains involved?
+
+A0309: As your first router, have the standard \%dnslookup%\ router from the
+ default configuration, with the added option
+
+==> self = pass
+
+ This will handle all domains whose lowest numbered MX records do not
+ point to your host. Because of the \no_more\ setting, if it encounters
+ an unknown domain, routing will fail. However, if it hits a domain whose
+ lowest numbered MX points to your host, the \self\ option comes into
+ play, and overrides \no_more\. The \"pass"\ setting causes it to pass
+ the address on to the next router. (The default causes it to generate an
+ error.)
+
+ The only non-local domains that reach the second router are those with
+ MX records pointing to the local host. Set it up to send them to the
+ internal mail server like this:
+
+==> internal:
+ driver = manualroute
+ domains = ! +local_domains
+ transport = remote_smtp
+ route_list = * internal.server
+
+
+Q0310: If a DNS lookup returns no MX records why doesn't Exim just bin the
+ message?
+
+A0310: If a DNS lookup returns no MXs, Exim looks for an address record, in
+ accordance with the rules that are defined in the RFCs. If you want to
+ break the rules, you can set \mx_domains\ in the \%dnslookup%\ router, but
+ you will cut yourself off from those sites (and there still seem to be
+ plenty) who do not set up MX records.
+
+
+Q0311: When a DNS lookup for MX records fails to complete, why doesn't Exim
+ send the messsage to the host defined by the A record?
+
+A0311: The RFCs are quite clear on this. Only if it is known that there are no
+ MX records is an MTA allowed to make use of the A record. When an MX
+ lookup fails to complete, Exim does not know whether there are any MX
+ records or not. There seem to be some name servers (or some
+ configurations of some name servers) that give a ``server fail'' error when
+ asked for a non-existent MX record. Exim uses standard resolver calls,
+ which unfortunately do not distinguish between this case and a timeout,
+ so all Exim can do is try again later.
+
+
+Q0312: Is it possible to use a conditional expression for the host item in a
+ \route_list\ for \%manualroute%\ router? I tried the following, but it
+ doesn't work:
+
+==> route_list = * ${if match{$header_from:}{\N.*\.usa\.net$\N} \
+ {<smarthost1>}{<smarthost2>}
+
+A0312: The problem is that the second item in \route_list\ contains white
+ space, which means that it gets terminated prematurely. To avoid this,
+ you must put the second item in quotes:
+
+==> route_list = * "${if match{$header_from:}{\N.*\.usa\.net$\N} \
+ {<smarthost1>}{<smarthost2>}}"
+
+
+Q0313: I send all external mail to a smart host, but this means that bad
+ addresses also get passed to the smart host. Can I avoid this?
+
+A0313: Assuming you have DNS availability, set up a conventional \%dnslookup%\
+ router to do the routing, but in the \%remote_smtp%\ transport set this:
+
+==> hosts = your.smart.host
+ hosts_override
+
+ This will override the hosts that the router finds so that everything
+ goes to the smart host, but any non-existent domains will be failed by
+ the router.
+
+
+Q0314: I have a really annoying intermittent problem where attempts to mail to
+ valid sites are rejected with \*unknown mail domain*\. This only happens a
+ few times a day and there is no particular pattern to the sites it
+ rejects. If I try to lookup the same domain a few minutes later then it
+ is OK.
+
+A0314: This is almost certainly a problem with the DNS resolver or the the
+ domain's name servers.
+
+ (1) Have you linked Exim against the newest DNS resolver library that
+ comes with Bind? If you are using SunOS4 that may be your problem, as
+ the resolver that comes with that OS is known to be buggy and to give
+ intermittent false negatives.
+
+ (2) Effects like this are sometimes seen if a domain's name servers get
+ out of step with each other.
+
+
+Q0315: I'd like route all mail with addresses that can't be resolved (the DNS
+ lookup times out) to a relay machine.
+
+A0315: Set \pass_on_timeout\ on your \%dnslookup%\ router, and add below it a
+ \%manualroute%\ router that routes all relevant domains to the relay.
+
+
+Q0316: I would like to forward all incoming email for a particular domain to
+ another host via SMTP. Whereabouts would I configure that?
+
+A0316: Use this as your first router:
+
+==> special:
+ driver = manualroute
+ transport = remote_smtp
+ route_list = the.particular.domain the.other.host
+
+ You will also need to adjust the ACL for incoming SMTP so that this
+ domain is accepted for relaying. If you are using the default
+ configuration, there is a domain list called \relay_domains\ that is
+ set up for this.
+
+
+Q0317: What I'd like to do is have alternative smart hosts, where the one to be
+ used is determined by which ISP I'm connected to.
+
+A0317: The simplest way to do this is to arrange for the name of the smart host
+ du jour to be placed in a file when you connect, say \(/etc/smarthost)\.
+ Then you can read this file from a \%manualroute%\ router like this:
+
+==> smarthost:
+ driver = manualroute
+ transport = remote_smtp
+ route_list = * ${readfile{/etc/smarthost}{}}
+
+ The second argument of the \"readfile"\ item is a string that replaces
+ any newline characters in the file (in this case, with nothing).
+ By keeping the data out of the main configuration file, you avoid having
+ to HUP the daemon when it changes.
+
+
+Q0318: Exim won't route to a host with no MX record.
+
+A0318: More than one thing may cause this.
+
+ (1) Are you sure there really is no MX record? Sometimes a typo results
+ in a malformed MX record in the zone file, in which case some name
+ servers give a SERVFAIL error rather than NXDOMAIN. Exim has to treat
+ this as a temporary error, so it can't go on to look for address records.
+ You can check for this state using one of the DNS interrogation commands,
+ such as \(nslookup)\, \(host)\, or \(dig)\.
+
+ (2) Is there a wildcard MX record for \(your)\ domain? Is the
+ \search_parents\ option on in your \%dnslookup%\ router? If the answer to
+ both these questions is ``yes'', that is the cause of the problem. When
+ the DNS resolver fails to find the MX record, it tries adding on your
+ domain if \search_parents\ is true, and thereby finds your wildcard MX
+ record. For example:
+
+ . There is a wildcard MX record for \(*.a.b.c)\.
+
+ . There is a host called \(x.y.z)\ that has an A record and no MX record.
+
+ . Somebody on the host \(m.a.b.c)\ domain tries to mail to \(user@x.y.z)\.
+
+ . Exim calls the DNS to look for an MX record for \(x.y.z)\.
+
+ . The DNS doesn't find any MX record. Because \search_parents\ is true,
+ it then tries searching the current host's parent domain, so it
+ looks for \(x.y.z.a.b.c)\ and picks up the wildcard MX record.
+
+ Setting \search_parents\ false makes this case work while retaining the
+ wildcard MX record. However, anybody on the host \(m.a.b.c)\ who mails to
+ \(user@n.a)\ (expecting it to go to \(user@n.a.b.c)\) now has a problem. The
+ \widen_domains\ option of the \%dnslookup%\ router may be helpful in this
+ circumstance.
+
+
+Q0319: I have some mails on my queues that are sticking around longer than
+ the retry time indicates they should. They are all getting frozen
+ because some remote admin has set their MX record to 127.0.0.1.
+
+A0319: The admin in question is an idiot. Exim will always freeze such messages
+ because they are apparently routed to the local host. To bounce these
+ messages immediately, set
+
+==> ignore_target_hosts = 127.0.0.1
+
+ on the \%dnslookup%\ router. This causes Exim to completely ignore any hosts
+ with that IP address. In fact, there are quite a number of IP addresses
+ that should never be used. Here is a suggested configuration list for
+ the IPv4 ones:
+
+==> # Don't allow domains whose single MX (or A) record is a
+ # "special-use IPv4 address", as listed in RFC 3330.
+ ignore_target_hosts = \
+ # Hosts on "this network"; RFC 1700 (page 4) states that these
+ # are only allowed as source addresses
+ 0.0.0.0/8 : \
+ # Private networks, RFC 1918
+ 10.0.0.0/8 : 172.16.0.0/12 : 192.168.0.0/16 : \
+ # Internet host loopback address, RFC 1700 (page 5)
+ 127.0.0.0/8 : \
+ # "Link local" block
+ 169.254.0.0/16 : \
+ # "TEST-NET" - should not appear on the public Internet
+ 192.0.2.0/24 : \
+ # 6to4 relay anycast addresses, RFC 3068
+ 192.88.99.0/24 : \
+ # Network interconnect device benchmark testing, RFC 2544
+ 198.18.0.0/15 : \
+ # Multicast addresses, RFC 3171
+ 224.0.0.0/4 : \
+ # Reserved for future use, RFC 1700 (page 4)
+ 240.0.0.0/4
+
+
+Q0320: How can I arrange for all mail to \*user@some.domain*\ to be forwarded
+ to \*user@other.domain*\?
+
+A0320: Put this as your first router:
+
+==> forward:
+ driver = redirect
+ domains = some.domain
+ data = ${quote:$local_part}@other.domain
+
+
+Q0321: How can I tell an Exim router to use only IPv4 or only IPv6 addresses
+ when it finds both types in the DNS?
+
+A0321: You can do this by making it ignore the addresses you don't want. This
+ example ignores all IPv6 addresses and all IPv4 addresses in the 127
+ network:
+
+==> ignore_target_hosts = <; 0000::0000/0 ; 127.0.0.0/8
+
+ To ignore all IPv4 addresses, use
+
+==> ignore_target_hosts = 0.0.0.0/0
+
+ See Q0319 for a general discussion of \ignore_target_hosts\.
+
+
+Q0322: How can I reroute all messages bound for 192.168.10.0 and 10.0.0.0 to
+ a specific mail server?
+
+A0322: That is an odd requirement. However, there is an obscure feature in
+ Exim, originally implemented for packet radio people, that perhaps can
+ help. Check out the \translate_ip_address\ generic router option.
+
+
+
+4. ROUTING FOR LOCAL DELIVERY
+
+Q0401: I need to have any mail for \(virt.dom.ain)\ that doesn't match one of the
+ aliases in \(/usr/lib/aliases.virt)\ delivered to a particular address, for
+ example, \(postmaster@virt.dom.ain)\.
+
+A0401: Adding an asterisk to a search type causes Exim to look up ``*'' when the
+ normal lookup fails. So if your aliasing router is something like this:
+
+==> virtual:
+ driver = redirect
+ domains = virt.dom.ain
+ data = ${lookup{$local_part}lsearch{/usr/lib/aliases.virt}}
+ no_more
+
+ you should change \"lsearch"\ to \"lsearch*"\, and put this in the alias
+ file:
+
+==> *: postmaster@virt.dom.ain
+
+ This solution has the feature that if there are several unknown
+ addresses in the same message, only one copy gets sent to the
+ postmaster, because of Exim's normal de-duplication rules.
+
+ NOTE: This solution works only if there is also an entry for \(postmaster)\
+ in the alias file, ultimately resolving to an address that is not in
+ \(virt.dom.ain)\. See also Q0434.
+
+
+Q0402: How do I arrange for all incoming email for \(*@some.domain)\ to go into one
+ pop3 mail account? The customer doesn't want to add a list of specific
+ local parts to the system.
+
+A0402: Set up a special transport that writes to the mailbox like this:
+
+==> special_transport:
+ driver = appendfile
+ file = /pop/mailbox
+ envelope_to_add
+ return_path_add
+ delivery_date_add
+ user = exim
+
+ The file will be written as the user \"exim"\. Then arrange to route all
+ mail for that domain to that transport, with a router like this:
+
+==> special_router:
+ driver = accept
+ domains = some.domain
+ transport = special_transport
+
+
+Q0403: How do I configure Exim to send messages for unknown local users to a
+ central server?
+
+A0403: Assuming you are using something like the default configuration, where
+ local users are processed by the later routers, you should add the
+ following router at the end:
+
+==> unknown:
+ driver = manualroute
+ transport = remote_smtp
+ route_list = * server.host.name
+ no_verify
+
+ However, you should if possible try to verify that the user is known on
+ the central server before accepting the message in the first place. This
+ can be done by making use of Exim's ``call forward'' facility.
+
+
+Q0404: How can I arrange for messages submitted by (for example) Majordomo to
+ be handled specially?
+
+A0404: You can use the \condition\ option on a router, with a setting such as
+
+==> condition = ${if and {{eq {$sender_host_address}{}} \
+ {eq {$sender_ident}{majordom}}} {yes}{no}}
+
+ This first tests for a locally-submitted message, by ensuring there is
+ no sending host address, and then it checks the identity of the user
+ that ran the submitting process.
+
+
+Q0405: On a host that accepts mail for several domains, do I have to use fully
+ qualified addresses in \(/etc/aliases)\ or do I have to set up an alias
+ file for each domain?
+
+A0405: You can do it either way. The default aliasing router contains this line:
+
+==> data = ${lookup{$local_part}lsearch{/etc/aliases}}
+
+ which is what does the actual lookup. To make it look up the complete
+ address instead of just the local part, use
+
+==> data = ${lookup{$local_part@$domain}lsearch{/etc/aliases}}
+
+ If you want to use a separate file for each domain, use
+
+==> data = ${lookup{$local_part}lsearch{/etc/aliases/$domain}}
+
+
+Q0406: Some of my users are using the \(.forward)\ to pipe to a shell command which
+ appends to the user's INBOX. How can I forbid this?
+
+A0406: If you allow your users to run shells in pipes, you cannot control which
+ commands they run or which files they write to. However, you should point
+ out to them that writing to an INBOX by arbitrary commands is not
+ interlocked with the MTA and MUAs, and is liable to mess up the contents
+ of the file.
+
+ If a user simply wants to choose a specific file for the delivery of
+ messages, this can be done by putting a file name in a \(.forward)\ file
+ rather than using a pipe, or by using the \"save"\ command in an Exim
+ filter file.
+
+ You can set \forbid_pipe\ on the router, but that will prevent them from
+ running any pipe commands at all. Alternatively, you can restrict which
+ commands they may run in their pipes by setting the \allow_commands\
+ and/or \restrict_to_path\ options in the \%address_pipe%\ transport.
+
+
+Q0407: How can I arrange for a default value when using a query-style lookup
+ such as LDAP or NIS+ to handle aliases?
+
+A0407: Use a second query in the failure part of the original lookup, like
+ this:
+
+==> data = ${lookup ldap\
+ {ldap://x.y.z/l=yvr?aliasaddress?sub?(&(mail=$local_part@$domain))}\
+ {$value}\
+ {\
+ ${lookup ldap \
+ {ldap://x.y.z/l=yvr?aliasaddress?sub?(&(mail=default@$domain))}}\
+ }}
+
+ Of course, if the default is a fixed value you can just include it
+ directly.
+
+
+Q0408: If I don't fully qualify the addresses in a virtual domain's alias file
+ then mail to aliases which also match the local domain get delivered to
+ the local domain.
+
+A0408: Set the \qualify_preserve_domain\ option on the \%redirect%\ router.
+
+
+Q0409: I want mail for any local part at certain virtual domains to go
+ to a single address for each domain.
+
+A0409: One way to to this is
+
+==> virtual:
+ driver = redirect
+ data = ${lookup{$domain}lsearch{/etc/virtual}}
+
+ The \(/etc/virtual)\ file contains a list of domains and the addresses to
+ which their mail should be sent. For example:
+
+==> domain1: postmaster@some.where.else
+ domain2: joe@xyz.plc
+
+ If the number of domains is large, using a DBM or cdb file would be more
+ efficient. If the lookup fails to find the domain in the file, the value
+ of the \data\ option is empty, causing the router to decline.
+
+
+Q0410: How can I make Exim look in the alias NIS map instead of \(/etc/aliases)\?
+
+A0410: The default configuration does not use NIS (many hosts don't run it).
+ You need to change this line in the \%system_aliases%\ router:
+
+==> data = ${lookup{$local_part}lsearch{/etc/aliases}}
+
+ Change it to
+
+==> data = ${lookup{$local_part}nis{mail.aliases}}
+
+ If you want to use \(/etc/aliases)\ as well as NIS, put this router (with
+ a different name) before or after the default one, depending on which
+ data source you want to take precedence.
+
+
+Q0411: Why will Exim deliver a message locally to any username that is longer
+ than 8 characters as long as the first 8 characters match one of the
+ local usernames?
+
+A0411: The problem is in your operating system. Exim just calls the \^^getpwnam()^^\
+ function to test a local part for being a local login name. It does not
+ presume to guess the maximum length of user name for the underlying
+ operating system. Many operating systems correctly reject names that are
+ longer than the maximum length; yours is apparently deficient in this
+ regard. To cope with such systems, Exim has an option called
+ \max_user_name_length\ which you can set to the maximum allowed length.
+
+
+Q0412: Why am I seeing the error \*bad mode (100664) for /home/test/.forward*\?
+ I've looked through the documentation but can't see anything to suggest
+ that Exim has to do anything other than read the \(.forward)\ file.
+
+A0412: For security, Exim checks for mode bits that shouldn't be set, by
+ default 022. You can change this by setting the \modemask\ option of the
+ \%redirect%\ router that is handling \(.forward)\ files.
+
+
+Q0413: When a user's \(.forward)\ file is syntactially invalid, Exim defers
+ delivery of all messages to that user, which sometimes include the
+ user's own test messages. Can it be told to ignore the \(.forward)\ file
+ and/or inform the user of the error?
+
+A0413: Setting \skip_syntax_errors\ on the redirect router causes syntax
+ errors to be skipped. When dealing with users' \(.forward)\ files it is best
+ to combine this with a setting of \syntax_errors_to\ in order to send
+ a message about the error to the user. However, to avoid an infinite
+ cascade of messages, you have to be able to send to an address that
+ bypasses \(.forward)\ file processing. This can be done by including a
+ router like this one
+
+==> real_localuser:
+ driver = accept
+ check_local_user
+ transport = local_delivery
+ prefix = real-
+
+ before the \%redirect%\ router that handles \(.forward)\ files. This will
+ do an ordinary local delivery without \(.forward)\ processing, if the
+ local part is prefixed by \"real-"\. You can then set something like
+ the following options on the \%redirect%\ router:
+
+==> skip_syntax_errors
+ syntax_errors_to = real-$local_part@$domain
+ syntax_errors_text = "\
+ This is an automatically generated message. An error has been \
+ found\nin your .forward file. Details of the error are reported \
+ below. While\nthis error persists, messages addressed to you will \
+ get delivered into\nyour normal mailbox and you will receive a \
+ copy of this message for\neach one."
+
+ A final tidying setting to go with this is a rewriting rule that changes
+ \"real-username"\ into just \"username"\ in the headers of the message:
+
+==> \N^real-([^@]+)@your\.dom\.ain$\N $1@your.dom.ain h
+
+ This means that users won't ever see the \"real-"\ prefix, unless they
+ look at the ::Envelope-To:: header.
+
+
+Q0414: I have set \caseful_local_part\ on the routers that handle my local
+ domain because my users have upper case letters in their login names,
+ but incoming mail now has to use the correct case. Can I relax this
+ somehow?
+
+A0414: If you really have to live with caseful user names but want incoming
+ local parts to be caseless, then you have to maintain a file, indexed by
+ the lower case forms, that gives the correct case for each login, like
+ this:
+
+==> admin: Admin
+ steven: Steven
+ mcdonald: McDonald
+ lamanch: LaManche
+ ...
+
+ and at the start of the routers that handle your local domain, put one
+ like this:
+
+==> set_case_router:
+ driver = redirect
+ data = ${lookup{${lc:$local_part}}lsearch{/the/file}}
+ qualify_preserve_domain
+
+ For efficiency, you should also set the \redirect_router\ option to cause
+ processing of the changed address to begin at the next router. If you
+ are otherwise using the default configuration, the setting would be
+
+==> redirect_router = system_aliases
+
+ If there are lots of users, then a DBM or cdb file would be more
+ efficient than a linear search. If you are handling several domains,
+ you will have to extend this configuration to cope appropriately.
+
+
+Q0415: Can I use my existing alias files and forward files as well as procmail
+ and effectively drop in Exim in place of Sendmail ?
+
+A0415: Yes, as long as your alias and forward files don't assume that pipes are
+ going to run under a shell. If they do, you either have to change them,
+ or configure Exim to use a shell (which it doesn't by default).
+
+
+Q0416: What is quickest way to set up Exim so any message sent to a
+ non-existing user would bounce back with a different message, based
+ on the name of non-existing user?
+
+A0416: Place this router last, so that it catches any local addresses that
+ are not otherwise handled:
+
+==> non_exist:
+ driver = accept
+ transport = non_exist_reply
+ no_verify
+
+ Then add the following transport to the transports section:
+
+==> non_exist_reply:
+ driver = autoreply
+ user = exim
+ to = $sender_address
+ subject = User does not exist
+ text = You sent mail to $local_part. That's not a valid user here. \
+ The subject was: $subject.
+
+ If you want to pick up a message from a file, you can use the \file\
+ option (use \file_expand\ if you want its contents expanded).
+
+
+Q0417: What do I need to do to make Exim handle \(/usr/ucb/vacation)\ processing
+ automatically, so that people could just create a \(.vacation.msg)\ file in
+ their home directory and not have to edit their \(.forward)\ file?
+
+A0417: Add a new router like this, immediately before the normal \%localuser%\
+ router:
+
+==> vacation:
+ driver = accept
+ check_local_user
+ require_files = $home/.vacation.msg
+ transport = vacation_transport
+ unseen
+
+ and a matching new transport like this:
+
+==> vacation_transport:
+ driver = pipe
+ command = /usr/ucb/vacation $local_part
+
+ However, some versions of \(/usr/ucb/vacation)\ do not work properly unless
+ the DBM file(s) it uses are created in advance - it won't create them
+ itself. You also need a way of removing them when the vacation is over.
+
+ Another possibility is to use a fixed filter file which is run whenever
+ \(.vacation.msg)\ exists, for example:
+
+==> vacation:
+ driver = redirect
+ check_local_user
+ require_files = $home/.vacation.msg
+ file = /some/central/filter
+ allow_filter
+
+ The filter file should use the \"if personal"\ check before sending mail,
+ to avoid generating automatic responses to mailing lists. If sending a
+ message is all that it does, this doesn't count as a ``significant''
+ delivery, so the original message goes on to be delivered as normal.
+
+ Yet another possibility is to make use of Exim's \%autoreply%\ transport,
+ and not use \(/usr/ucb/vacation)\ at all.
+
+
+Q0418: I want to use a default entry in my alias file to handle unknown local
+ parts, but it picks up the local parts that the aliases generate. For
+ example, if the alias file is
+
+==> luke.skywalker: luke
+ ls: luke
+ *: postmaster
+
+ then messages addressed to \/luke.skywalker/\ end up at \/postmaster/\.
+
+A0418: The default mechanism works best with virtual domains, where the
+ generated address is not in the same domain. If you just want to pick up
+ all unknown local parts and send them to postmaster, an easier way to do
+ it is to put this as your last router:
+
+==> unknown:
+ driver = redirect
+ data = postmaster
+ no_verify
+
+ Another possibility is to put the redirect router for these aliases
+ after all the other routers, so that local parts which are user names
+ get picked off first. You will need to have two aliasing routers if
+ there are some local parts (e.g. \/root/\) which are login names, but which
+ you want to handle as aliases.
+
+
+Q0419: I have some obsolete domains which people have been warned not to use
+ any more. How can I arrange to delete any mail that is sent to them?
+
+A0419: To reject them at SMTP time, with a customized error message, place
+ statments like this in the ACL:
+
+==> deny message = The domain $domain is obsolete
+ domains = lsearch;/etc/exim/obsolete.domains
+
+ For messages that don't arrive over SMTP, you can use a router like
+ this to bounce them:
+
+==> obsolete:
+ driver = redirect
+ domains = lsearch;/etc/exim/obsolete.domains
+ allow_fail
+ data = :fail: the domain $domain is obsolete
+
+ If you just want to throw away mail to those domains, accept them at
+ SMTP time, and use a router like this:
+
+==> obsolete:
+ domains = lsearch;/etc/exim/obsolete.domains
+ data = :blackhole:
+
+
+Q0420: How can I arrange that mail addressed to \(anything@something.mydomain.com)\
+ gets delivered to \(something@mydomain.com)\?
+
+A0420: Set up a router like this:
+
+==> user_from_domain:
+ driver = redirect
+ data = ${if match{$domain}{\N^(.+)\.mydomain\.com$\N}\
+ {$1@mydomain.com}}
+
+
+Q0421: I can't get a regular expression to work in a \local_parts\ option on
+ one of my routers.
+
+A0421: Have you remembered to protect any backslash and dollar characters in
+ your regex from unwanted expansion? The easiest way is to use the
+ \"@\N"\ facility, like this:
+
+==> local_parts = \N^0740\d{6}\N
+
+
+Q0422: How can I arrange for all addresses in a group of domains \(*.example.com)\
+ to share the same alias file? I have a number of such groups.
+
+A0422: For a single group you could just hard wire the file name into a router
+ that had
+
+==> domains = *.example.com
+
+ set, to restrict it to the relevant domains. For a number of such groups
+ you can create a file containing the domains, like this:
+
+==> *.example1.com example1.com
+ *.example2.com example2.com
+ ...
+
+ Then create a router like this
+
+==> domain_aliases:
+ driver = redirect
+ domains = partial-lsearch;/that/file
+ data = ${lookup{$local_part}lsearch*{/etc/aliases.d/$domain_data}}
+
+ The variable \$domain_data$\ contains the data that was looked up when the
+ \domains\ option was matched, i.e. \"example1.com"\, \"example2.com"\, etc.
+ in this case.
+
+
+Q0423: Some of our users have no home directories; the field in the password
+ file contains \(/no/home/dir)\. This causes the error \*failed to stat
+ /no/home/dir (No such file or directory)*\ when Exim tries to look for a
+ \(.forward file)\, and the delivery is deferred.
+
+A0423: There are two issues involved here:
+
+ (1) With the default configuration, you are asking Exim to check for a
+ \(.forward)\ file in the user's home directory. If no file is found,
+ Exim tries to \^^stat()^^\ the home directory. This is so that it will
+ notice a missing NFS home directory, and not treat it as if the
+ \(.forward)\ file did not exist. This \^^stat()^^\ is failing when the
+ home directory really doesn't exist. You should arrange for the
+ \%userforward%\ router not to run for these special users, by adding
+ this line:
+
+==> condition = ${if eq {$home}{/no/home/dir}{no}{yes}}
+
+ (2) If you use \check_local_user\ on another router to route to a local
+ transport (again, this is what is in the default configuration), you
+ will also have to specify a current directory for the transport, because
+ by default it makes the home directory current. This is easily done by
+ adding
+
+==> current_directory = /
+
+ to the transport or
+
+==> transport_current_directory = /
+
+ to the router. Or you can add \home_directory\ to the transport, because
+ the current directory defaults to the home directory.
+
+
+Q0424: How can I disable Exim's de-duplication features? I want it to do two
+ deliveries if two different aliases expand to the same address.
+
+A0424: This is not possible. Duplication has other ramifications other than
+ just (in)convenience. Consider:
+
+ . Message is addressed to A and to B.
+
+ . Both A and B are aliased to C.
+
+ . Without de-duplication, two deliveries to C are scheduled.
+
+ . One delivery happens, Exim records that it has delivered the message
+ to C.
+
+ . The next delivery fails (C's mailbox is over quota, say).
+
+ Next time round, Exim wants to know if it has already delivered to C or
+ not, before scheduling a new delivery. Has it? Obviously, if duplicate
+ deliveries are supported, it has to remember not only that it has
+ delivered to C but also the ``history'' of how that delivery happened - in
+ effect an ancestry list back to the original envelope address. This it
+ does not do, and changing it to work in that way would be a lot of work
+ and a big upheaval.
+
+ The best way to get duplicate deliveries if you want them is not to use
+ aliases, but to route the addresses directly to a transport, e.g.
+
+==> duplicates:
+ driver = accept
+ local_parts = lsearch;/etc/list/of/special/local/parts
+ transport = local_delivery
+ user = exim
+
+
+Q0425: My users' mailboxes are distributed between several servers according to
+ the first letter of the user name. All the servers receive incoming mail
+ at random. I would like to have the same configuration file for all the
+ servers, which does local delivery for the mailboxes it holds, and sends
+ other addresses to the correct other server. Is this possible?
+
+A0425: It is easiest if you arrange for all the users to have password entries
+ on all the servers. This means that non-existent users can be detected
+ at the first server they reach. Set up a file containing a mapping from
+ the first letter of the user names to the servers where their mailboxes
+ are held. For example:
+
+==> a: server1
+ b: server1
+ c: server2
+ ...
+
+ Before the normal \%localuser%\ router, place the following router:
+
+==> mailbox_host:
+ driver = manualroute
+ check_local_user
+ transport = remote_smtp
+ route_list = * ${lookup{${substr_0_1:$local_part}}lsearch{/etc/mapfile}}
+ self = pass
+
+ This router checks for a local account, then looks up the host from the
+ first character of the local part. If the host is not the local host,
+ the address is routed to the \%remote_smtp%\ transport, and sent to the
+ correct host. If the host is the local host, the \self\ option causes
+ the router to pass the address to the next router, which does a local
+ delivery.
+
+ The router is skipped for local parts that are not the names of local
+ users, and so these addresses fail.
+
+
+Q0426: One of the things I want to set up is for \(anything@onedomain)\ to forward
+ to \(anything@anotherdomain)\. I tried adding \($local_part@anotherdomain)\ to
+ my aliases but it did not expand - it sent it to that literal address.
+
+A0426: If you want to do it that way, you can use the \"expand"\ operator on
+ the lookup used in the data option of the redirect router. For example:
+
+==> data = ${expand:${lookup{$local_part}lsearch*{/etc/aliases}}}
+
+ Another approach is to use a router like this:
+
+==> forwarddomain:
+ driver = redirect
+ domains = onedomain
+ data = $local_part@anotherdomain
+
+ The value of \data\ can, of course, be more complicated, involving
+ lookups etc. if you have lots of different cases.
+
+
+Q0427: How can I have an address looked up in two different alias files, and
+ delivered to all the addresses that are found?
+
+A0427: Use a router like this:
+
+==> multi_aliases:
+ driver = redirect
+ data = ${lookup{$local_part}lsearch{/etc/aliases1}\
+ {$value${lookup{$local_part}lsearch{/etc/aliases2}{,$value}}}\
+ {${lookup{$local_part}lsearch{/etc/aliases2}{$value}fail}}}\
+
+ If the first lookup succeeds, the result is its data, followed by the
+ data from the second lookup, if any, separated by a comma. If the first
+ lookup fails, the result is the data from the third lookup (which also
+ looks in the second file), but if this also fails, the entire expansion
+ is forced to fail, thereby causing the router to decline.
+
+ Another approach is to use two routers, with the first re-generating the
+ original local part when it succeeds. This won't get processed by the
+ same router again. For example:
+
+==> multi_aliases1:
+ driver = redirect
+ data = ${lookup{$local_part}lsearch{/etc/aliases1}{$value,$local_part}}
+
+==> multi_aliases2:
+ data = ${lookup{$local_part}lsearch{/etc/aliases2}}
+
+ This scales more easily to three or more alias files.
+
+
+Q0428: I've converted from Sendmail, and I notice that Exim doesn't make use
+ of the \"owner-"\ entries in my alias file to change the sender address in
+ outgoing messages to a mailing list.
+
+A0428: If you have an alias file with entries like this:
+
+==> somelist: a@b, c@d, ...
+ owner-somelist: postmaster
+
+ Sendmail assumes that the second entry specifies a new sender address
+ for the first. Exim does not make this assumption. However, you can make
+ it take the same action, by adding
+
+==> errors_to = owner-$local_part@whatever.domain
+
+ to the configuration for your aliasing router. This is fail-safe,
+ because Exim verifies a new sender address before using it. Thus, the
+ change of sender address occurs only when the owner entry exists.
+
+
+Q0429: I would like to deliver mail addressed to a given domain to local
+ mailboxes, but also to generate messages to the envelope senders.
+
+A0429: You can do this with an ``unseen'' router and an \%autoreply%\ transport,
+ along the following lines:
+
+==> # Router
+ auto_warning_r:
+ driver = accept
+ check_local_user
+ domains = <domains you want to do this for>
+ condition = ${if eq{$sender_address}{}{no}{yes}}
+ transport = warning_t
+ no_verify
+ unseen
+
+ Place this router immediately before the normal \%localuser%\ router. The
+ \unseen\ option means that the address is still passed on to the next
+ router. The transport is configured like this:
+
+==> # Transport
+ warning_t:
+ driver = autoreply
+ file = /usr/local/mail/warning.txt
+ file_expand
+ from = postmaster@your.domain
+ to = $sender_address
+ user = exim
+ subject = Re: Your mail to $local_part@$domain
+
+ Note the use of the \condition\ option to avoid attempting to send a
+ message when there is no sender (that is, when the incoming message is a
+ bounce message). You can of course extend this to include other
+ conditions. If you want to log the sending of messages, you can add
+
+==> log = /some/file
+
+ to the transport and also make use of the \once\ option if you want to
+ send only one message to each sender.
+
+
+Q0430: Whenever Exim tries to route a local address, it gives a permission
+ denied error for the \(.forward)\ file, like this:
+
+==> 1998-08-10 16:55:32 0z5y2W-0000B8-00 == xxxx@yyy.zzz <xxxx@yyy.zz>
+ D=userforward defer (-1): failed to open /home/xxxx/.forward
+ (userforward router): Permission denied (euid=1234 egid=101)
+
+A0430: Have you remembered to make Exim setuid \/root/\?
+
+
+Q0431: How do I configure Exim to allow arbitrary extensions in local parts, of
+ the form \/+extension/\?
+
+A0431: Add this pre-condition to the relevant router:
+
+==> local_part_suffix = +*
+
+ If you want the extensions to be optional, also add the option
+
+==> local_part_suffix_optional
+
+ When the router runs, \$local_part$\ contains the local part with the
+ extension removed, and the extension (if any) is in \$local_part_suffix$\.
+ If you have set \check_local_user\, the test is carried out after the
+ extension is removed.
+
+
+Q0432: I use NIS for my user data. How can I stop Exim rejecting mail when my
+ NIS servers are being restarted?
+
+A0432: Exim doesn't know that you are using NIS; it just calls the \^^getpwnam()^^\
+ function, which is routed by nsswitch. Unfortunately, \^^getpwnam()^^\
+ was never designed to be routed through NIS, and it returns NULL if the
+ entry is not found or if the connection to the NIS server fails. This
+ means that Exim cannot tell the difference between ``no such user'' and
+ ``NIS is down''.
+
+ Crutches to help with this problem are \finduser_retries\ in Exim, and
+ \^nscd^\ on the Unix side, but they are not perfect, and mail can still
+ be lost. However, Nico Erfurth pointed out that you can create a router
+ for Exim that tests for the availability of NIS, and force a defer if
+ NIS is not running:
+
+==> check_nis:
+ driver = redirect
+ data = ${lookup {$local_part} nis {passwd}{}}
+
+ This should be placed before any router that makes any use of NIS,
+ typically at the start of your local routers. How does it work? If
+ your NIS server is reachable, the lookup will take place, and whether it
+ succeeds or fails, the result is an empty strting. This causes the
+ router to decline, and the address is passed to the following routers.
+ If your NIS server is down, the lookup defers, and this causes the
+ router to defer. A verification of an incoming address gets a temporary
+ rejection, and a delivery is deferred till later.
+
+
+Q0433: How can I arrange for a single address to be processed by \*both*\
+ \%redirect%\ \*and*\ \%accept%\?
+
+A0433: Check out the \unseen\ option.
+
+
+Q0434: How can I redirect all local parts that are not in my system aliases to
+ a single address? I tried using an asterisk in the system alias file
+ with an \"lsearch*"\ lookup, but that send \*all*\ messages to the
+ default address.
+
+A0434: If your alias file generates addresses in the local domain, they are
+ also processed as a potential aliases. For example, suppose this is your
+ alias file:
+
+==> caesar: jc
+ anthony: ma
+ *: brutus
+
+ The local part \/caesar/\ is aliased to \/jc/\, but that address is then
+ reprocessed by the routers. As the address is in the local domain, the
+ alias file is again consulted, and this time the default matches. In
+ fact after the second aliasing, \/brutus/\ is also processed again from
+ the start, and is aliased to itself. However, this happens only once,
+ because the next time, Exim notices that the aliasing router has already
+ processed \/brutus/\, so the router is skipped in order to avoid
+ looping.
+
+ There are several ways of solving this problem; which one you use
+ depends on your aliasing data.
+
+ (1) If the result of aliasing is always a local user name, that is,
+ aliasing never generates another alias, you can use the
+ \redirect_router\ option on the router to specify that processing
+ the generated addresses must start at the next router. For example:
+
+==> redirect_router = userforward
+
+ assuming that the next router is called \%userforward%\. This
+ ensures that there is at most one pass through the aliasing router.
+
+ (2) If you cannot rely on aliases generating non-aliases, it is often
+ easier not to use a default alias, but instead to place a router
+ such as the one below after all the other local routers (for the
+ relevant domains):
+
+==> catch_unknown:
+ driver = redirect
+ domains = ...
+ data = brutus@$domain
+
+ Note that the default aliasing technique works more successfully for
+ virtual domains (see Q0401) because the generated address for the
+ default is not usually in the same virtual domain as the incoming
+ address.
+
+
+Q0435: My alias file contains fully qualified addresses as keys, and some
+ wildcard domains in the form @foo.bar. Can Exim handle these?
+
+A0435: You can handle fully qualified addresses with this router:
+
+==> qualified_aliases:
+ driver = redirect
+ data = ${lookup{$local_part@$domain}lsearch{/etc/aliases}}
+
+ (Add any other options you need for the \%redirect%\ router.) Place this
+ router either before or after the default aliases router that looks up
+ the local part only. (Or, if you have no unqualified aliases, replace
+ the default router.)
+
+ To handle wildcards in the form @foo.bar you will need yet another
+ router. (Wildcards of the form *@foo.bar can be handled by an lsearch*@
+ lookup.) Something like this:
+
+==> wildcard_aliases:
+ driver = redirect
+ data = ${lookup{@$domain}lsearch{/etc/aliases}}
+
+ Place this after the routers that handle the more specific aliases.
+
+
+
+5. FILTERING
+
+Q0501: My filter isn't working. How can I test it?
+
+A0501: Use the \-bf-\ option (\-bF-\ for a system filter) to test the basic operation
+ of your filter. You can request debugging information for filtering only
+ by adding \"-d-all+filter"\ to the command.
+
+
+Q0502: What I really need is the ability to obtain the result of a pipe
+ command so that I can filter externally and redirect internally. Is
+ this possible?
+
+A0502: The result of a pipe command is not available to a filter, because Exim
+ does not run any actual deliveries while filtering. It just sets up
+ deliveries at this time. They all actually happen later. If you want to
+ run pipes and examine their results, you need to set up a single
+ delivery to a delivery agent such as \^procmail^\ which provides this kind
+ of facility.
+
+ An possible alternative is to use the \"${run"\ expansion item to run an
+ external command while filtering. In this case, you can make use of some
+ of the results of the command.
+
+
+Q0503: I received a message with a ::Subject:: line that contained a non-printing
+ character (a carriage return). This messed up my filter file. Is there a
+ way to get round it?
+
+A0503: Instead of \"$h_subject:"\ use \"${escape:$h_subject:}"\
+
+
+Q0504: I want to search for \"$"\ in the subject line, but I can't seem to get
+ the syntax.
+
+A0504: Try one of these:
+
+==> if $h_subject: contains \$ then ...
+ if $h_subject: contains "\\$" then ...
+
+
+Q0505: My problem is that Exim replaces \$local_part$\ with an empty string in the
+ system filtering. What's wrong or what did I miss?
+
+A0505: A message may have many recipients. The system filter is run just once
+ at the start of a delivery attempt. Consequently, it does not make sense
+ to set \$local_part$\. Which recipient should it be set to? However, you
+ can access all the recipients from a system filter via the variable
+ called \$recipients$\.
+
+
+Q0506: Using \$recipients$\ in a system filter gives me another problem: how can
+ I do a string lookup if \$recipients$\ is a list of addresses?
+
+A0506: Check out the section of the filter specification called \*Testing a list of
+ addresses*\. If that doesn't help, you may have to resort to calling an
+ embedded Perl interpreter - but that is expensive.
+
+
+Q0507: What are the main differences between using an Exim filter and using
+ \^procmail^\?
+
+A0507: Exim filters and \^procmail^\ provide different facilities. Exim filters run
+ at routing time, before any deliveries are done. A filter is like a
+ ``\(.forward)\ file with conditions''. One of the benefits is de-duplication.
+ Another is that if you forward, you are forwarding the original message.
+
+ However, this does mean that pipes etc. are not run at filtering time,
+ nor can you change the headers, because the message may have other
+ recipients and Exim keeps only a single set of headers.
+
+ \^procmail^\ runs at delivery time. This is for one recipient only, and so
+ it can change headers, run pipes and check the results, etc. However, if
+ it wants to forward, it has to create a new message containing a copy
+ of the original message.
+
+ It's your choice as to which of these you use. You can of course use
+ both.
+
+
+Q0508: How can I allow the use of relative paths in users' filter files when
+ the directories concerned are not available from the password data?
+
+A0508: You need to be running Exim 4.11 or later. You can then specify a value
+ for \$home$\ by setting the router_home_directory option on the
+ \%redirect%\ router.
+
+ For earlier releases, there is no way to specify the value of \$home$\
+ for a \%redirect%\ router; it either comes from the password data as a
+ result of \check_local_user\, or is unset.
+
+
+Q0509: How can I set up a filter file to detect and block virus attachments?
+
+A0509: Exim's filter facilities aren't powerful enough to do much more than
+ very crude testing. Most people that want virus checking are nowadays
+ using one of the separate scanning programs such as \^exiscan^\ (see
+ \?http://duncanthrax.net/exiscan/?\). There is some further information
+ about scanning with Exim via \?http://www.timj.co.uk/linux/exim.php?\.
+
+
+Q0510: Is it possible to write code for scanning messages in Python?
+
+A0510: \^elspy^\ is a layer of glue code that enables you to write Python code
+ to scan email messages at SMTP time. \^elspy^\ also includes a small
+ Python library with common mail-scanning tools, including an interface
+ to SpamAssassin and a simple but effective virus detector. You can
+ optain \^elspy^\ from \?http://elspy.sourceforge.net/?\.
+
+
+Q0511: Whenever my system filter uses a \mail\ command to send a message, I get
+ the error \*User 0 set for address_reply transport is on the never_users
+ list*\. What does this mean?
+
+A0511: The system filter runs as \/root/\ in Exim 4, unless you set
+ \system_filter_user\ to specify otherwise. When you set up a delivery
+ direct from a system filter (an autoreply is a special kind of
+ ``delivery'') the transport runs as the same user, unless it has a
+ \user\ setting of its own. Normally, deliveries are not allowed to run
+ as \/root/\ as a security precaution; this is implemented by the
+ \never_users\ option.
+
+ The easiest solution is to add this to your configuration:
+
+==> system_filter_user = exim
+
+ The system filter then runs as \/exim/\ instead of \/root/\.
+ Alternatively, you can arrange for autoreplies from the system filter to
+ use a special transport of their own, and set the \user\ option on that
+ transport.
+
+
+Q0512: I'm trying to reference the ::Envelope-To:: header in my filter, but
+ \$h_envelope-to:$\ is always empty.
+
+A0512: ::Envelope-To:: is added at delivery time, by the transport. Therefore,
+ the header doesn't exist at filter time. In a user filter, the values
+ you probably want are in \$original_local_part$\ and
+ \$original_domain$\. In a system filter, the complete list of all
+ envelope recipients is in \$recipients$\.
+
+
+Q0513: I want my system filter to freeze all mails greater than 500K in size,
+ but to exclude those to a specific domain. However, I don't seem to be
+ able to use \$domain$\ in a system filter.
+
+A0513: You cannot do this in a system filter, because a single message may have
+ multiple recipients, some in the special domain, and some not. That is
+ also the reason why \$domain$\ is not set in a system filter.
+
+ If you want to take actions on a per-recipient basis, you have to do it
+ in a router. However, freezing is not appropriate, because freezing
+ stops all deliveries. You could, however, delay delivery to all but the
+ special domains by using something like this:
+
+==> delay_if_too_big:
+ driver = redirect
+ domains = !the.special.domain
+ condition = ${if >{$message_size}{500K}{yes}{no}}
+ allow_defer
+ data = :defer: message too big.
+
+ However, there isn't an easy way of ``releasing'' such messages at
+ present.
+
+
+Q0514: When I try to send to two addresses I get an error in the filter
+ file \*malformed address: , e@fgh.com may not follow a@bcd.com*\. What
+ is going on?
+
+A0514: Have you got
+
+==> deliver "a@bcd.com, e@fgh.com"
+
+ in your filter? If so, that is your problem. You should have
+
+==> deliver a@bcd.com
+ deliver e@fgh.com
+
+ Each \deliver\ command expects just one address.
+
+
+
+6. DELIVERY
+
+Q0601: What does the error \*Neither the xxx router nor the yyy transport set
+ a uid for local delivery of...*\ mean?
+
+A0601: Whenever Exim does a local delivery, it runs a process under a specific
+ user and group id (uid and gid). For deliveries into mailboxes, and to
+ pipes and files set up by forwarding, it normally picks up the uid/gid
+ of the receiving user. However, if an address is directed to a pipe or a
+ file by some other means, such an entry in the system alias file of the
+ form
+
+==> majordomo: |/local/mail/majordomo ...
+
+ then Exim has to be told what uid/gid to use for the delivery. This can
+ be done either on the routerr that handles the address, or on the
+ transport that actually does the delivery. If a pipe is going to run a
+ setuid program, then it doesn't matter what uid Exim starts it out with,
+ and so the most straightforward thing is to put
+
+==> user = exim
+
+ on either the router or the transport. A setting on the transport
+ overrides a setting on the router, so if the same transport is being
+ used with several routers, you should set the user on it only if you
+ want the same uid to be used in all cases.
+
+ In the default configuration, the transports used for file and pipe
+ deliveries are the ones called \address_file\ and \address_pipe\. You
+ can specify different transports by setting, for example,
+
+==> pipe_transport = special_pipe_transport
+
+ on the \%system_aliases%\ router. Then you can set up \%special_pipe_transport%\
+
+==> special_pipe_transport:
+ driver = pipe
+ user = ????
+
+ which will be used only for pipe deliveries from that one router.
+ What you put for the ???? is up to you, and depends on the particular
+ circumstances.
+
+
+Q0602: Exim keeps crashing with segmentation errors (signal 11 or 139) during
+ delivery. This seems to happen when it is about to contact a remote
+ host or when a delivery is deferred.
+
+A0602: This could be a problem with Exim's databases. Try running a delivery
+ with debugging turned on. If the last line of the debug output is
+ something like this:
+
+==> locked /var/spool/exim/db/retry.lockfile
+
+ the crash is happening inside the DBM library. Check that your DBM
+ library is correctly installed. In particular, if you have installed a
+ second DBM library onto a system that already had one, check that its
+ version of \(ndbm.h)\ is being seen first. For example, if the new
+ version is in \(/usr/local/include)\, check that there isn't another
+ version in \(/usr/include)\. If you are using Berkeley db, you can set
+
+==> USE_DB=yes
+
+ in your \(Local/Makefile)\ to avoid using \(ndbm.h)\ altogether. This is
+ particularly relevant for version 2 (or later) of Berkeley db, because
+ no \(ndbm.h)\ file is distributed with it. Another thing you can try is
+ to run
+
+==> exim_dumpdb /var/spool/exim retry
+
+ to see if it also crashes, or build the \^test_dbfn^\ tool and fiddle
+ around with it. If both fail, it is most almost certainly a problem with
+ your DBM library. You could try to update it, or force Exim to use
+ another library. See the file \(doc/dbm.discuss.txt)\ for hints about
+ this.
+
+
+Q0603: How can mails that are being routed through routers that do not set
+ \check_local_user\ be delivered under the uid of the recipient?
+
+A0603: Q0601 contains background information on this. If you are using, say, an
+ alias file to direct messages to specific mailboxes, you can use
+ the \user\ option on either the router or the transport to set the uid.
+ What you put in the setting depends on how the required uid is to be
+ found. It could be looked up in a file or computed somehow from the
+ local part, for example.
+
+
+Q0604: I want to use MMDF-style mailboxes. How can I get Exim to append the
+ ctrl-A characters that separate indvidual emails?
+
+A0604: Set the \message_suffix\ option in the \%appendfile%\ transport. In fact,
+ for MMDF mailboxes you need a prefix as well as a suffix to get it
+ working right, so your transport should contain these settings:
+
+==> message_prefix = "\1\1\1\1\n"
+ message_suffix = "\1\1\1\1\n"
+
+ Also, you need to change the \check_string\ and \escape_string\ settings so
+ that the escaping happens for lines in the message that happen to begin
+ with the MMDF prefix or suffix string, rather than ``From'' (the default):
+
+==> check_string = "\1\1\1\1\n"
+ escape_string = "\1\1\1\1 \n"
+
+ Adding a space to the line is sufficient to prevent it being taken as a
+ separator.
+
+
+Q0605: If a user's mailbox is over quota, is there a way for me to set it up so
+ that the mail bounces to the sender and is not stored in the mail queue?
+
+A0605: In the retry section of the configuration, put
+
+==> *@your.dom.ain quota
+
+ That is, provide no retry timings for over quota errors. They will then
+ bounce immediately. Alternatively, you can set up retries for a short
+ time only, or use something like this:
+
+==> *@your.dom.ain quota_7d
+ *@your.dom.ain quota F,2h,15m; F,3d,1h
+
+ which bounces immediately if the user's mailbox hasn't been read for 7
+ days, but otherwise tries for up to 3 days after the first quota
+ failure.
+
+
+Q0606: I'm using tmail to do local deliveries, but when I turned on the
+ \use_crlf\ option on the \%pipe%\ transport (tmail prefers \"@\r@\n"\
+ terminations) message bodies started to vanish.
+
+A0606: You need to unset the \mesage_prefix\ option, or change it so that its
+ default \"@\n"\ terminator becomes \"@\r@\n"\. For example, the
+ transport could be:
+
+==> local_delivery_mbx:
+ driver = pipe
+ command = /usr/local/bin/tmail $local_part
+ user = exim
+ current_directory = /
+ use_crlf
+ message_prefix =
+
+ The reason for this is as follows: tmail uses the line terminator on
+ the first line it sees to determine whether lines are terminated by
+ \"@\r@\n"\ or \"@\n"\. If the latter, it moans to stderr and changes subsequent
+ \"@\n"\ terminators to \"@\r@\n"\. The default setting of the \message_prefix\
+ option is \"From ...@\n"\, and this is unaffected by the \use_crlf\ option.
+ If you don't change this, tmail sees the first line terminated by
+ \"@\n"\ and prepends \"@\r"\ to the \"@\n"\ terminator on all subsequent
+ lines. However, if \use_crlf\ is set, Exim makes all other lines
+ \"@\r@\n"\ terminated, leading to doubled \"@\r@\r@\n"\ lines and
+ corrupt mbx mailboxes.
+
+
+Q0607: When I activate ``return receipt'' for example in Netscape Mailbox
+ sending options, then I get an error message from Exim... something
+ like \*not supported*\. Can I activate delivery confirmations?
+
+A0607: Exim does not support any kind of delivery notification.
+
+ (1) You can configure it to recognize headers such as
+ \Return-receipt-to:\ if you wish.
+
+ (2) Some people want MSN (message status notification). Such services
+ are implemented in MUAs, and don't impact on the MTA at all.
+
+ (3) I investigated the RFCs which describe the DSN (delivery status
+ notification) system. However, I was unable to specify any sensible way
+ of actually doing anything with the data. There were comments on the
+ mailing list at the time; many people, including me, conclude that DSN
+ is in practice unworkable. The killer problem is with forwarding and
+ aliasing. Do you propagate the DSN data with the generated addresses?
+ Do you send back a ``reached end of the DSN world'' or ``expanded'' message?
+ Do you do this differently for different kinds of aliasing/forwarding?
+ For a user who has a \(.forward)\ file with a single address in, this
+ might seem easy - just propagate the data. But what if there are several
+ forwardings? If you propagate the DSN data, the sender may get back
+ several DSN messages - and should the sender really know about the
+ detail of the receiver's forwarding arrangements? There isn't really
+ any way to distinguish between a \(.forward)\ file that is forwarding
+ and one that is a mini mailing list. And so on, and so on. There are so
+ many questions that don't have obvious answers.
+
+
+Q0608: What does the message \*retry time not reached [for any host]*\ on the log
+ mean? Why won't Exim try to deliver the message?
+
+A0608: That is not an error. It means exactly what it says. A previous attempt
+ to deliver to that address failed with a temporary error, and Exim
+ computed the earliest time at which to try again. This can apply to
+ local as well as to remote deliveries. For remote deliveries, each host
+ (if there are several) has its own retry time.
+
+ If you are running on a dial-up host, the rest of this answer probably
+ does not apply to you. Go and read Q1404 instead. If your host is
+ permanently online, read on...
+
+ Some MTAs have a retrying schedule for each message. Exim does not work
+ like this. Retry timing is normally host-based for remote deliveries and
+ address-based for local deliveries. (There are some exceptions for certain
+ kinds of remote failure - see \*Errors in outgoing SMTP*\ in the manual.)
+
+ If a new message arrives for a failing address and the retry time has
+ not yet arrived, Exim will log \*retry time not reached*\ and leave the
+ message on the queue, without attempting delivery. Similarly, if a queue
+ runner notices the message before the time to retry has arrived, it
+ writes the same log entry. When the retry time has past, Exim attempts
+ delivery at the next queue run. If you want to know when that will be,
+ run the exinext utility on the address, for example:
+
+==> exinext user@some.domain
+
+ You can suppress these messages on the log by including \"-retry_defer"\
+ in the setting of \log_selector\. You can force a delivery attempt on a
+ specific message (overriding the retry time) by means of the -M option:
+
+==> exim -M 10hCET-0000Bf-00
+
+ If you want to do this for the entire queue, use the \-qf-\ option.
+
+
+Q0609: Exim seems to be sending the same message twice, according to the log,
+ although there is a difference in capitalization of the local part of
+ the address.
+
+A0609: That is correct. The RFCs are explicit in stating that capitalization
+ matters for local parts. For remote domains, Exim is not entitled to
+ assume case independence of local parts. I know, it is utterly silly,
+ and it causes a lot of grief, but that's what the rules say. Here is a
+ quote from RFC 2821:
+
+ ... a command verb, an argument value other than a mailbox local-part,
+ and free form text MAY be encoded in upper case, lower case, or any
+ mixture of upper and lower case with no impact on its meaning. This
+ is NOT true of a mailbox local-part. The local-part of a mailbox
+ MUST BE treated as case sensitive. Therefore, SMTP implementations
+ MUST take care to preserve the case of mailbox local-parts. Mailbox
+ domains are not case sensitive. In particular, for some hosts the
+ user "smith" is different from the user "Smith". However, exploiting
+ the case sensitivity of mailbox local-parts impedes interoperability
+ and is discouraged.
+
+
+Q0610: How can I force the next retry time for a host to be now?
+
+A0610: You can change the retry time with the \^exim_fixdb^\ utility, but its
+ interface is very clumsy. If you have a message for the host on the
+ queue, the simplest thing to do is to force a delivery with the \-M-\
+ command line option. If delivery succeeds, the retry data will get
+ cleared. If the host is past the cutoff time, so that messages are
+ bouncing immediately without trying a delivery, you can use \-odq-\ to
+ put a message on the queue without a delivery attempt, and then use
+ \-M-\ on it.
+
+
+Q0611: I set up \"|/bin/grep Subject|/usr/bin/smbclient -M <netbiosname>"\ as an
+ alias but it doesn't work.
+
+A0611: That is a shell command line. Exim does not run pipe commands under a
+ shell by default (for added security - and it saves a process). You
+ need something like
+
+==> "|/bin/sh -c '/bin/grep Subject|/usr/bin/smbclient -M <netbiosname>'"
+
+
+Q0612: Why does the \%pipe%\ transport add a line starting with \">From"\ to
+ messages?
+
+A0612: Actually, it adds a line starting with \"From"\ followed by a space.
+ This is commonly referred to as the \"From_"\ line, to emphasize the
+ fact that \"From"\ is followed by a space and not a colon. This is a
+ pseudo-header line that contains the envelope sender address and the
+ time of delivery. It originated as a separator line in Berkeley format
+ mailboxes, but is also used in other contexts. (And yes, it is often
+ confused with the ::From:: header line, and this causes a lot of grief.
+ The use of \"From_"\ was one of the really bad email design decisions.)
+
+ Exim's \%pipe%\ transport adds this pseudo-header line by default
+ because \(/usr/ucb/vacation)\ needs it, and that is one of the the most
+ common uses of piping. The \^procmail^\ local delivery agent also makes
+ use of the \"From_"\ line. If you do not want it, change the setting of
+ \message_prefix\ on the \%pipe%\ transport. For example, to remove the
+ line altogether, use
+
+==> message_prefix =
+
+ If you are not piping to \(/usr/ucb/vacation)\ or \^procmail^\, it is
+ likely that you do not need a \"From_"\ line, and indeed it may cause
+ problems if it is present.
+
+ One user reported that this line gave trouble when a pipe was used to
+ send messages to Courier's \^deliverquota^\ program. The line was
+ retained with the message, and caused problems for MS Exchange 2000 when
+ retrieving messages with its built-in POP collector. Specifically, it
+ caused Exchange to not be able to recognise message attachments.
+
+
+Q0613: I have set \fallback_hosts\ on my \%smtp%\ transport, but after the error
+ \*sem@chat.ru cannot be resolved at this time*\ Exim isn't using them.
+
+A0613: \fallback_hosts\ works only if an attempt at delivery to the original
+ host(s) fails. In this case, Exim couldn't even resolve the domain
+ \(chat.ru)\ to discover what the original hosts were, so it never got as far
+ as the transport. However, see Q0315 for a possible solution.
+
+
+Q0614: After the holidays my ISP has always hundreds of e-mails waiting for me.
+ These are forced down Exim's throat in one go. Exim spawns a lot of
+ kids, but is there some limit to the number of processes it creates?
+
+A0614: Unless you have changed \smtp_accept_queue_per_connection\ it should
+ spawn only that many processes per connection (default 10). Your ISP
+ may be making many connections, of course. That is limited by
+ \smtp_accept_max\.
+
+
+Q0615: When a message in the queue got to 12h old, Exim wrote \*retry timeout
+ exceeded*\ and removed all messages in the queue to this host - even
+ recent messages. How I can avoid this behaviour? I only want to remove
+ messages that have exceeded the maximum retry time.
+
+A0615: Exim's retrying is host-based rather than message-based. The philosophy
+ is that if a host has been down for a very long time, there is no point
+ in keeping messages hanging around. However, you might like to check
+ out \delay_after_cutoff\ in the \%smtp%\ transport. It doesn't do what you
+ want, but it might help.
+
+
+Q0616: Can Exim add a ::Content-Length:: header to messages it delivers?
+
+A0616: You could include something like
+
+==> headers_remove = "content-length"
+ headers_add = "Content-Length: $message_body_size"
+
+ to the \%appendfile%\ transport. However, the use of ::Content-Length:: can
+ cause several problems, and is not recommended unless you really know
+ what you are doing. There is a discussion of the problems in
+ \?http://home.netscape.com/eng/mozilla/2.0/relnotes/demo/content-length.html?\.
+
+
+Q0617: Exim seems to be trying to deliver a message every 10 minutes, though
+ the retry rules specify longer times after a while, because it is
+ writing a log entry every time, like this:
+
+==> 1999-08-26 14:51:19 11IVsE-000MuP-00 == example@example.com T=smtp defer
+ (-34): some host address lookups failed and retry time not reached for
+ other hosts or connection limit reached
+
+A0617: It is looking at the message every 10 minutes, but it isn't actually
+ trying to deliver. It's looking up \(example.com)\ in the DNS and finding
+ this information:
+
+==> example.com. MX 10 example-com.isp.example.com.
+ example.com. MX 0 mail.example.com.
+ mail.example.com. A 202.77.183.45
+ A lookup for example-com.isp.example.com. yielded NXDOMAIN
+
+ The last line means that there is no address (A) record in the DNS for
+ \(example-com.isp.example.com)\. That accounts for \*some host address
+ lookups failed*\, but the retry time for \(mail.example.com)\ hasn't been
+ reached, which accounts for \*retry time not reached for other hosts*\.
+
+
+Q0618: I am trying to set exim up to have a automatic failover if it sees that
+ the system that it is sending all mail to is down.
+
+A0618: Add to the \%remote_smtp%\ transport the following:
+
+==> fallback_hosts = failover.server.name(s)
+
+ If there are several names, they must be separated by colons.
+
+
+Q0619: I can't get Exim to deliver over NFS. I get the error \*fcntl() failed:
+ No locks available*\, though the lock daemon is running on the NFS server
+ and other hosts are able to access it.
+
+A0619: Check that you have \(lockd)\ running on the NFS client. This is not
+ always running by default on some systems (Red Hat is believed to be one
+ such system).
+
+
+Q0620: Why does Exim bounce messages without even attempting delivery, giving
+ the error \*retry time not reached for any host after a long failure
+ period*\?
+
+A0620: This message means that all hosts to which the message could be sent
+ have been failing for so long that the end of the retry period
+ (typically 4 or 5 days) has been reached. In this situation, Exim still
+ computes a next time to retry, but any messages that arrive in the
+ meantime are bounced straight away. You can alter this behaviour by
+ unsetting the \delay_after_cutoff\ option on the smtp transport. Then Exim
+ will try most messages for those hosts once before giving up.
+
+
+Q0621: My \(.forward)\ file is \"|/usr/bin/procmail -f-"\ and mail gets delivered,
+ but there was a bounce to the sender, sending him the output of procmail.
+ How can I prevent this?
+
+A0621: Exim's default configuration is set up like this:
+
+==> address_pipe:
+ driver = pipe
+ return_output
+
+ The \return_output\ option requests that any output that the pipe
+ produces be returned to the sender. That is the safest default. If you
+ don't want this, you can either remove the option altogether, or change
+ it to \return_fail_output\, to return output only if the command fails.
+ Note that this will affect all pipes that users run, not just your
+ procmail one. It might be better to arrange for procmail not to produce
+ any output when it succeeds.
+
+
+Q0622: Can I write an ordinary file when I run a perl script as a transport
+ filter for the \%remote_smtp%\ and \%address_pipe%\ transports?
+
+A0622: Yes, provided the file is writeable by the uid under which the transport
+ runs (the Exim user in the case of the remote transport). However, if two
+ messages are being delivered at once, their data will get mixed up in
+ the file unless you implement your own locking scheme. If all you want
+ to do is to take a copy of the message, another approach that avoids
+ the locking problem is to use a system filter to set up an ``unseen''
+ delivery to a file. If you only want the message's headers, you can
+ set \message_filter_file_transport\ to point to a special \%appendfile%\
+ transport that has \headers_only\ set.
+
+
+Q0623: My \(/var/spool/mail)\ has grown drastically. Is there any possibility of
+ using two directories?
+
+A0623: You can use an expansion string to split mailboxes between two
+ directories. For example,
+
+==> file = /var/spool/mail${nhash_2:$local_part}/$local_part
+
+ which does a hash on the local part, producing either 0 or 1, thereby
+ using \(mail0) or \(mail1)\. But remember, the MUAs that read these mailboxes
+ also have to know where they are.
+
+
+Q0624: Sendmail has a program called \^smrsh^\ that restricts what binaries
+ can be run from sendmail aliases. Is there something like this in Exim ?
+
+A0624: Check out the \allow_commands\ option in the \%pipe%\ transport.
+
+
+Q0625: I wish to have large emails go out one at a time.
+
+A0625: One possibility is to set up a router that defers all large messages,
+ except in queue runs. Since queue runners deliver just one
+ message at a time, if you limited the number of simultaneous queue
+ runners to 1, you would get the effect you wanted. A suitable router
+ might be
+
+==> defer_if_large_unless_queue_run:
+ driver = redirect
+ condition = ${if or{{queue_running}{<{$message_size}{200K}}}{no}{yes}}
+ allow_defer
+ data = :defer: too large for immediate delivery
+ no_verify
+
+ Of course, this would always delay any large message until the next
+ queue runner, but if you run them fairly regularly, this shouldn't be a
+ huge problem, and may even be desirable. Note the use of \no_verify\ to
+ ensure that this router is not used when Exim is verifying addresses.
+
+
+Q0626: Exim can route local parts independent of their case, but the Cyrus LMTP
+ daemon requires the correct case. How can I fix this?
+
+A0626: You need to rewrite the local part to the correct case before running
+ the router that routes to Cyrus. For example, if you require all lower
+ case, and your router is called \local_user\, put this router in front
+ of it:
+
+==> lowercase_local:
+ driver = redirect
+ redirect_router = local_user
+ domains = +local_domains
+ data = ${lc:$local_part}@$domain
+
+ The setting of \redirect_router\ causes processing of the rewritten
+ address to start at the next router, instead of the first router. See
+ also Q0630, and C045 for a more complete Cyrus configuration.
+
+
+Q0627: Is there a command I can send to Exim to retry all queued messages
+ regardless of their retry schedule?
+
+A0627: The \-qff-\ option starts a queue runner that forces a delivery attempt
+ for all messages, including frozen ones. If you use \-qf-\, frozen
+ messages are skipped.
+
+
+Q0628: I have the default retry rule, which I thought meant that Exim should
+ keep trying for four days, but it seems to be bouncing some messages
+ immediately.
+
+A0628: See Q0615 and Q0620.
+
+
+Q0629: I'm having trouble with quotas and Courier, because Exim is not handling
+ maildirsize files.
+
+A0629: You will do better to move the quota handling to Courier. Use \^maildrop^\
+ as your MDA rather than direct Exim delivery. This also has the
+ advantage that if you give web access to the mail spool (over \^sqwebmail^\)
+ you can then use the web front end to edit \^maildrop^\ filter files.
+
+
+Q0630: How can I configure Exim to deliver to a Cyrus message store?
+
+A0630: (1) The reference manual contains an example that uses pipe delivery.
+
+ (2) Here is a transport that uses LMTP delivery, assuming that
+ \$local_part$\ contains the username:
+
+==> cyrus_inbox:
+ driver =lmtp
+ user = cyrus
+ socket = /var/cyrus/socket/lmtp
+
+ (3) This is a transport that delivers direct to a non-inbox mailbox:
+
+==> cyrus_mailbox:
+ driver = pipe
+ user = $local_part
+ message_prefix =
+ message_suffix =
+ log_fail_output
+ return_output
+ command = "/usr/cyrus/bin/deliver -a $local_part \
+ -m <mailbox-name> $local_part"
+
+ This delivers to the Cyrus mailbox \"user.$local_part.<mailbox-name>"\.
+ Using \"user = $local_part"\ and \"-a $local_part"\ makes it work
+ without needing an explicit `p' ACL set for `anyone' on the mailbox.
+
+
+Q0631: I would like to choose a retry rule based on on the sender rather than
+ the recipient address. Is this possible?
+
+A0631: Yes. The address part of a retry rule is matched as a single-item
+ address list. Such lists are always expanded, so you can use something
+ like this:
+
+==> "${if eq{$sender_address}{xxx}{*@*}{no@no}}" quota F,1h,10m; ...
+
+ If the sender address is ``xxx'', the pattern expands to ``*@*'', which
+ matches all recipient addresses; if you want to, you can make this a
+ more restrictive pattern. If the sender address is not ``xxx'', the
+ pattern expands to ``no@no'', which is assumed to be a recipient address
+ that can never match, so the retry rule is skipped.
+
+
+Q0632: What does the error \*User 1 set for local_mbx_delivery transport is on
+ the never_users list*\ mean?
+
+A0632: You have configured the \%local_mbx_delivery%\ to run as the user whose
+ id (uid) is 1. However, this user is on the list defined by the
+ \never_users\ runtime option, or the \\FIXED_NEVER_USERS\\ compile-time
+ option. These are ``safety catch'' lists; Exim refuses to deliver to any
+ user that is on them. The most common use of \never_users\ is to avoid
+ doing any deliveries as \/root/\, but it can contain other uids.
+
+
+Q0633: Why is \$domain$\ not set in the \%smtp%\ transport?
+
+A0633: The \%smtp%\ transport can handle several recipient addresses at once.
+ This happens by default if the host lists for the addresses are
+ identical. A single copy of the message is sent, using multiple \\RCPT\\
+ commands to transmit multiple envelope recipients. The \$domain$\
+ variable is set in the \%smtp%\ transport only if all the recipient
+ addresses have the same domain. You must have a case where several
+ addresses with different domains resolve to the same set of hosts.
+
+ If you want to restrict the transport so that it handles only a single
+ domain at once (but still possibly with more than one recipient), set
+
+==> multi_domain = false
+
+ If you want to restrict the transport so that it handles only a single
+ address at once, set
+
+==> max_rcpt = 1
+
+
+Q0634: How can I stop a local transport from trying to access the user's home
+ directory, even when the delivery is to a file that is elsewhere?
+
+A0634: See answer (2) for Q0423.
+
+
+Q0635: The log message \*error ignored*\ appears after some delivery failures.
+ What does it mean?
+
+A0635: This message is written when Exim fails to deliver a bounce message whose
+ age is greater than \ignore_bounce_errors_after\. It indicates that the
+ failing bounce message has been discarded.
+
+ The same message is written after failed deliveries when a filter file
+ uses the \noerror\ feature when setting up a delivery, or if a router
+ has the setting
+
+==> errors_to = <>
+
+ Both of these specify that delivery failures are to be discarded.
+
+
+
+7. POLICY CONTROLS
+
+Q0701: How do I block unwanted messages from outside my host?
+
+A0701: Exim uses Access Control Lists (ACLs) for controlling incoming mail from
+ other hosts. A whole chapter in the reference manual is devoted to
+ describing how they work. A wide variety of conditions can be imposed on
+ incoming messages.
+
+ The default Exim run time configuration contains an example of an ACL
+ which blocks all relaying, and messages whose senders cannot be
+ verified. This example is heavily commented and worth studying.
+
+
+Q0702: I don't want to block spam entirely; how can I inspect each message
+ before deciding whether or not to deliver it?
+
+A0702: Wherever possible, inspection and rejection is best done automatically
+ in an ACL, that is, before the message is accepted. If you want to
+ verify manually each message that is classified as spam by an automatic
+ check, you can arrange for a system filter to freeze such messages after
+ they have been accepted.
+
+ If, after inspection, you decide not to deliver the message, it is
+ safest to discard it, using the \-Mrm-\ option. Use of the \-Mg-\ option
+ to force a bounce carries the risk of ``collateral spam'' if the sender
+ address is faked.
+
+
+Q0703: How can I test that my spam blocks are working?
+
+A0703: The \-bh-\ option allows you to run a testing SMTP session as if from a
+ given IP address. For example,
+
+==> exim -bh 192.168.178.39
+
+ In addition to the normal SMTP replies, it outputs commentary about
+ which tests have succeeded or failed. If you are not interested in the
+ details, but just want to know if a particular sender at a particular IP
+ address is able to mail to a particular recipient, you can use the
+ \exim_checkaccess\ utility, which provides a ``packaged'' version of
+ \-bh-\. You call it like this:
+
+==> exim_checkaccess 192.168.53.23 recip@my.domain -f sender@some.domain
+
+ If you don't give a sender, \"<>"\ is used (that it, it acts like a
+ bounce message).
+
+
+Q0704: How can I test that Exim is correctly configured to use the Realtime
+ Blackhole List (RBL)?
+
+A0704: The \-bh-\ option allows you to run a testing SMTP session as if from a
+ given address. The \^exim_checkaccess^\ utility provides a more packaged
+ version of this facility. You need to know a blocked IP address with
+ which to test. Such a testing address is kindly provided by Russell
+ Nelson:
+
+==> linux.crynwr.com [192.203.178.39]
+
+ You can also send mail to \(nelson@linux.crynwr.com)\ from the server
+ whose RBL block you are testing. The robot that receives that email
+ will attempt to send a piece of test email in reply. If your RBL block
+ didn't work, you get a message to that effect. Regardless of whether the
+ RBL block succeeds or not, it emails you the results of the SMTP
+ conversation from a host that is not on the RBL, so you can see how your
+ server looks from the view of someone on the RBL.
+
+
+Q0705: How can I use tcpwrappers in conjunction with Exim?
+
+A0705: Exim's own control facilities can do all that tcpwrappers can do.
+ However, if you are already using tcpwrappers for other things it might
+ be convenient to include Exim controls in the same place.
+
+ First of all, ensure that Exim is built to call the tcpwrappers library,
+ by including \\USE_TCPWRAPPERS=yes\\ in \(Local/Makefile)\. You also need to
+ ensure that the header file \(tcpd.h)\ is available at compile time, and the
+ \(libwrap.a)\ library is available at link time, typically by including it in
+ \\EXTRALIBS\\. You may need to copy these two files from the tcpwrappers
+ build directory to, for example, \(/usr/local/include)\ and \(/usr/local/lib)\,
+ respectively. Then you could reference them by
+
+==> CFLAGS=-I/usr/local/include
+ EXTRALIBS=-L/usr/local/lib -lwrap
+
+ in \(Local/Makefile)\. There are two ways to make use of the functionality,
+ depending on how you have tcpwrappers set up. If you have it set up to
+ use only one file, you ought to have something like:
+
+==> /etc/hosts.allow:
+
+==> exim : <client_list> : <allow_or_deny>
+
+ For example:
+
+==> exim : LOCAL 192.168.0. .friendly.domain special.host : ALLOW
+ exim : ALL : DENY
+
+ This allows connections from local hosts (chiefly //localhost//), from
+ the subnet 192.168.0.0/24, from all hosts in \(*.friendly.domain)\, and
+ from a specific host called \(special.host)\. All other connections are
+ denied. If you have tcpwrappers set up to use two files, use the
+ following:
+
+==> /etc/hosts.allow:
+
+==> exim : <client_list>
+
+==> /etc/hosts.deny:
+
+==> exim : <client_list>
+
+ Read the \^hosts_access^\ man page for more ways of specifying clients,
+ including ports, etc., and on logging connections.
+
+
+Q0706: How can I get POP-auth-before-relay (aka POP-before-SMTP) support in
+ Exim?
+
+A0706: Exim 4 supports the ``whoson'' (\?http://whoson.sourceforge.net?\)
+ facility for doing this. If you set this up, you can do the check in an
+ Exim ACL by a statement like this:
+
+==> require condition = \
+ ${lookup whoson {$sender_host_address}{yes}{no}}
+
+ Otherwise you need to arrange for a list of permitted IP addresses to be
+ maintained in a file or database, and use this in a \hosts\ condition in
+ an ACL statement. An Exim user has published this recipe:
+
+ \#\#\#\#\?http://www.zeiss.cx/memo/computer/linux/email/exim-s-a-p.html?\
+
+ Another Exim user submitted the following idea:
+
+ Use a script to grab authenticated IP addresses from the log files of
+ the POP3 and IMAP4 daemons. These are used to create files in the
+ directory tree \(/var/db/popb4smtp)\. The existence of a file represents a
+ valid ``popped recently token'' for the IP address used as the filename.
+
+ Another script periodically removes stale files from the tree (after two
+ hours). There's a small race condition here; it's possible for a file
+ to be deleted just after it has been updated by the script that watches
+ the logs. For low-volume servers, the odds of hitting this window are
+ low.
+
+ A POPB4SMTP_CLIENT macro in the Exim configure file provides a reusable
+ ``has this sender popped recently?'' query:
+
+==> POPB4SMTP_SUBDIR = /var/db/popb4smtp/${substr_-1_1:$sender_host_address}
+ POPB4SMTP_CLIENT = ${if exists {POPB4SMTP_SUBDIR/$sender_host_address} \
+ {$sender_host_address} {0} }
+
+ Now you can use it just about anywhere, including in your ACLs. Simple
+ examples include:
+
+==> hostlist relay_hosts = 127.0.0.1/32 : ... : POPB4SMTP_CLIENT
+ host_lookup = !127.0.0.1/32 : ... : !POPB4SMTP_CLIENT
+ rfc1413_hosts = !127.0.0.1/32 : ... : !POPB4SMTP_CLIENT
+
+ The two scripts (and a FreeBSD startup script for them) are available
+ for download at:
+
+ \#\#\#\#\?http://people.FreeBSD.org/~sheldonh/popb4smtp-nodb.tar.gz?\
+
+
+Q0707: I have one or two cases where my host correctly rejects messages, but
+ the remote host is quite persistent, and keeps trying over and over.
+
+A0707: It is an unfortunate fact that a number of SMTP clients, in violation of
+ the SMTP RFC, do not treat a permanent error code that is given after
+ the DATA portion of the transaction as a permanent error. Consequently
+ they keep resending the message, and the worst offenders do so at very
+ short intervals.
+
+ The only way to stop such behaviour is to blacklist the IP address, or
+ the envelope sender, or both, in such a way that future messages get
+ rejected at RCPT time instead of at DATA time. You could also complain
+ to the remote host's administrators.
+
+
+Q0708: How can I run customized verification checks on incoming addresses?
+
+A0708: There are a number of possibilities:
+
+ (1) If you can implement your checks in Perl, you can use Exim's
+ facility for running an embedded Perl interpreter. For example, if you
+ want to run special checks on local addresses, you could use ACL
+ an statement like this:
+
+==> require domains = my.local.domain
+ condition = ${perl{verify}{$local_part}}
+
+ The result of the Perl function should be ``yes'' or ``no''.
+
+ (2) You could also run an external program in a similar way, by a
+ statement such as:
+
+==> require domains = my.local.domain
+ condition = ${run{/my/verifier $local_part}}
+
+ This requires the use of another process, so could prove more expensive
+ than Perl.
+
+ (3) If you are prepared to write C code, read the chapter in the manual
+ entitled \*Adding a local scan function to Exim*\.
+
+
+Q0709: Does Exim apply RBL checks to error messages, those with an envelope
+ sender of \"<>"\ ?
+
+A0709: This depends on the ACL configuration. You can test for bounce messages
+ (by looking for an empty sender address) and thereby exclude them from
+ RBL checking if you want. This ACL statement does that:
+
+==> deny senders = ! :
+ dnslist = blackholes.mail-abuse.org
+
+ However, some spam does come with an empty sender address, so this may
+ not be a good idea.
+
+
+Q0710: I want to reject certain sender-recipient combinations, with a specific
+ message for each such combination.
+
+A0710: Set up a file (or database) containing the messages, keyed by the
+ combination, for example:
+
+==> sender1@sdomain1=>recipient1@rdomain1: blocked because...
+ sender2@sdomain2=>recipient2@rdomain2: blocked because...
+
+ If you have lots of recipients for the same sender, it might be easier
+ to generate this file from more convenient data. In your ACL that is run
+ for each RCPT command, you can then put:
+
+==> deny message = ${lookup{$sender_address=>$local_part@$domain}\
+ lsearch{/that/file}}
+ condition = ${lookup{$sender_address=>$local_part@$domain}\
+ lsearch{/that/file}}{yes}{no}}
+
+ The condition is tested first. If the lookup succeeds, the condition
+ succeeds so access is denied. The message is then expanded, but the
+ lookup won't be repeated, because Exim will have cached the previous
+ result.
+
+ This approach blocks only incoming SMTP messages. If you need to do
+ similar blocks for messages that do not arrive over SMTP, you have to
+ set up a suitable \%redirect%\ router with a \:fail:\ setting.
+
+
+Q0711: Will Exim allow me to create a file of regexs and match incoming
+ external email to the list - and if a match is found file the offending
+ message into a special location? Also is it possible to make Exim only
+ filter parts of an incoming email - e.g. ignore large MIME attachments
+ for example and only process text/plain?
+
+A0711: You can do some of this in a system filter. For example:
+
+==> if $message_body matches <...some complicated regex...> or
+ $message_body matches <...some other regex...> or
+ $header_from: matches <...regex...> or
+ etc.
+ then
+ save /some/special/file
+ endif
+
+ or instead of \"save"\ you could have \"deliver"\ (to some address) or
+ \"pipe"\ (to some script).
+
+ There isn't any mechanism for ignoring attachments, but \$message_body$\
+ only looks at the first n bytes of the body, where n defaults to 500 but
+ can be changed.
+
+ A more expensive alternative would be to run a Perl subroutine using the
+ embedded Perl mechanism. If you passed over the message id, the Perl
+ code could read the message files on the spool and implement any
+ algorithm it liked for deciding what should be done.
+
+
+Q0712: I've hacked sendmail to make an ioctl call at the time of the SMTP RCPT
+ command, to check if a user has exceeded their email quota. If they have
+ I issue a temporary failure and a message - can I do this with Exim?
+
+A0712: If you can make this happen in Perl you can use the embedded Perl
+ facility, and use it from a \condition\ condition in an ACL statement.
+ You can also use the expansion facility to run an external program, but
+ this uses more resources because it uses another process.
+
+
+Q0713: I'd like to pass all messages through a virus-scanning system before
+ delivery. Can Exim do this?
+
+A0713: One way of achieving this is to deliver all messages via a pipe to a
+ checking program that resubmits them for delivery in some private way
+ that can be checked (e.g. on a specific SMTP port, or IP address). One
+ possibility is to use the `received protocol` field that can be set
+ for locally submitted mail via the \-oMr-\ command line option. This
+ router sends all messages that are not from the local host and whose
+ received protocol is not \"scanned-ok"\ to the \%virus_scan%\ transport:
+
+==> vircheck:
+ driver = accept
+ transport = virus_scan
+ condition = ${if or {{eq {$received_protocol}{scanned-ok}} \
+ {eq {$sender_host_address}{127.0.0.1}}}\
+ {0}{1}}
+
+ One problem is that this approach scans the message for each recipient,
+ not just once per message.
+
+ The virus_scan transport should be set up to pipe the message to a
+ suitable checking program or script which runs as a trusted user. This
+ can then re-submit the message to Exim, using \-oMr-\ to set the received
+ protocol to \"scanned-ok"\, and the \-f-\ option to set the correct envelope
+ sender address. \**Warning:**\ If you forget to make the resubmitting process
+ run as a trusted user, the received protocol does not get set, and you
+ are likely to generate a loop.
+
+
+Q0714: Is there a way to configure Exim to reject mail to a certain local host?
+
+A0714: No, only to certain domains. To reject at SMTP time, you can put a line
+ like this in your ACL:
+
+==> deny message = this domain is deliberately rejected
+ domains = a.certain.domain
+
+ To fail addresses in messages that do not arrive over SMTP, you can set
+ up a router like this:
+
+==> reject_a_certain_domain:
+ driver = redirect
+ domains = a.certain.domain
+ allow_fail
+ data = :fail: this domain is deliberately rejected
+
+
+Q0715: How can I get Exim to remove attachments from messages?
+
+A0715: Exim does not contain facilities for modifying messages. You must use
+ an external program if you want to do this. You can route messages that
+ have a ::Content-type:: header line via a pipe to a command that does
+ the job and then re-submits the message to Exim. Alternatively, you
+ could use a transport filter to do this job.
+
+
+Q0716: How can I arrange for each user to have a file listing the only sender
+ addresses from which she will accept mail? I want to do this so my
+ family members don't get any spam (or other inappropriate mail).
+
+A0716: Let's assume each user has a file called \(.acceptlist)\ in the home
+ directory. You can put in your ACL a line like this:
+
+==> require senders = /home/$local_part/.acceptlist
+
+ This will reject RCPT commands when the sender is not in the accept
+ list for the recipient. (Replace \(/home/$local_part)\ with whatever
+ the correct path to your user's home directories is.)
+
+ One problem with this is that it will block bounce messages, which have
+ empty senders. You can get round this, by changing the line to this:
+
+==> require senders = : /home/$local_part/.acceptlist
+
+ However, this will, of course, let in spam that has a null sender.
+
+
+Q0717: When using Nessus on a system that runs Exim, a number of security
+ issues are raised. Nessus complains that Exim answers to EXPN and/or
+ VRFY; sometimes it even complains that Exim allows relaying.
+
+A0717: Exim supports EXPN and VRFY only if you permit it to do so in the ACLs
+ defined by \acl_smtp_expn\ and \acl_smtp_vrfy\, respectively. Otherwise,
+ its responses are
+
+==> 550 Administrative prohibition
+ 252 Administrative prohibition
+
+ Maybe the use of 252 is the ``problem''. It is recommended that this be
+ done (by those that discuss these things) because there are stupid
+ clients that attempt VRFY before sending a message.
+
+
+Q0718: Could anyone points me to right rules to prevent sending/receiving
+ messages to/for domains which have one MX to localhost or only have
+ address 127.0.0.1 ?
+
+A0718: See Q0319.
+
+
+Q0719: I would like to have a per-user limit for the maximum size of messages
+ that can be sent.
+
+A0719: The simplest way to do this is to put something in a system filter along
+ these lines:
+
+==> if $message_size is above
+ "${lookup{$sender_address}lsearch{/some/file}{$value}{10M}}"
+ then
+ fail "Message is larger than $sender_address is allowed to send"
+ endif
+
+ In practice, an additional check that the message has arrived from your
+ local host or local network is probably wise because sender addresses
+ are easily forged.
+
+
+Q0720: I set \"accept hosts=192.168.122.96/32"\ in order to accept mail for
+ relaying from my local LAN, but it doesn't work. What's wrong?
+
+A0720: 192.168.122.96/32 is not a network, it is a single host. Exim uses CIDR
+ notation for specifying networks, where the number after the slash is
+ the number of bits in the IP address that must match. Your setting says
+ ``32 bits must match''. If you really mean to specify ``the next 32
+ IP addresses'', you need 192.168.122.96/27.
+
+
+Q0721: I have POP-before-SMTP set up on my Exim server, but some clients use
+ Outlook Express, which sends queued messages before checking the
+ mailbox, so it doesn't work.
+
+A0721: Implement SMTP authentication.
+
+
+Q0722: I installed Amavis and it is working, but bounces are simply vanishing.
+
+A0722: Check that you haven't inadvertently set up the transport like this:
+
+==> amavis:
+ driver = pipe
+ command = "/usr/sbin/amavis -f ${sender_address} -d ${pipe_addresses}"
+
+ The last line should be:
+
+==> command = /usr/sbin/amavis -f <$sender_address> -d $pipe_addresses
+
+ The important thing is the <> around the sender address; removal of
+ the unnecessary "" and {} is just tidying. See the amavis FAQ at
+ \?http://www.amavis.org/amavis-faq.php3?\.
+
+
+Q0723: I can't get Pine to work with PLAIN authentication; Exim keeps
+ responding "535 Incorrect authentication data".
+
+A0723: You need to have this setting in your PLAIN authenticator:
+
+==> server_prompts = :
+
+ This is missing in the examples in all but the most recent Exim
+ documentation, because it was not realized that PLAIN authentication
+ could be requested by a client without sending the data with the
+ request. If the data is not sent, an empty prompt is expected.
+
+
+Q0724: I have used \":fail:"\ in some aliases; when one of these addresses is
+ refused, I see the message on the log, but the response to the remote
+ user is ``unknown user'' instead of the message from the alias file.
+ How can I change this?
+
+A0724: Have you got a \message\ qualifier in the relevant ACL? Exim uses the
+ message line in the ACL in preference to the message returned by the
+ router. This is so you can restrict the amount of information that
+ ``escapes'' from your site via SMTP if you want to. Remove the \message\
+ line in the ACL entry that has \"verify = recipient"\ and your message
+ will get through.
+
+ Alternatively, if you are running Exim 4.10 or later, you can use the
+ \$acl_verify_message$\ variable in your message to include the message
+ from the router. See also Q0725.
+
+
+Q0725: I've set up some specific rejection messages for certain recipients, but
+ when I test them, the SMTP message is always \*550 5.1.1
+ <user@mydomain.com>... User unknown*\.
+
+A0725: That is not an Exim message (the ``5.1.1'' is a clue; Exim doesn't use
+ those extended codes). You are probably being defeated by software that
+ sees the 550 error code, and insists on putting in its own text. There
+ is stupid software that does this. You can test Exim by using \-bh-\ or
+ making a telnet call to the SMTP port. That way, there's no other
+ software intervening.
+
+
+Q0726: My SMTP authentication can be bypassed by sending an unknown user name
+ and an empty password. What is wrong with this condition in a PLAIN
+ authenticator?
+
+==> server_condition = ${if eq{$2} {${lookup mysql{SELECT password FROM \
+ accounts WHERE username='${local_part:$1}'}}}{1}{0}}
+
+A0726: Your lookup item returns an empty string when the user does not exist.
+ You should instead arrange for the lookup to fail:
+
+==> server_condition = ${if eq{$2} {${lookup mysql{SELECT password FROM \
+ accounts WHERE username='${local_part:$1}'}{$value}fail}}{1}{0}}
+
+
+Q0727: When a message has many recipients, how can I stop SpamAssassin from
+ being called for each of them? I'm running it from a pipe transport.
+
+A0727: In the transport configuration, set \batch_max\ to a value greater than
+ one.
+
+
+Q0728: How do I use Exiscan, SA-Exim, SpamAssassin, Clam Antivirus, Sophos
+ SAVI, or sophie with Exim?
+
+A0728: There's a mini-HOWTO about these available via
+ \?http://www.timj.co.uk/linux/exim.php?\.
+ See also sample configuration C047.
+
+
+Q0729: How can I screen out addresses that are neither valid usernames or
+ distribution lists on mail being forwarded to an internal Win2K server?
+
+A0729: A user suggested using a router like this to do the recipient
+ verification:
+
+==> verify_user_router:
+ driver = accept
+ domains = win2kdomain.com
+ local_parts=\
+ ldap;user="cn=ldap-guest,cn=Users,dc=win2kdomain,dc=com"\
+ pass=guest \
+ ldap:://win2kpdc/dc=win2kdomain,dc=com?mailNickname?\
+ sub?(&(mailNickname=$local_part)\
+ (showInAddressBook=*)(sAMAccountName=*))
+ verify_only
+
+ Set up ldap-guest as a normal domain user on the Win2K PDC.
+
+ Also, you need to set \no_verify\ on all the other routers that handle
+ that domain.
+
+
+Q0730: How can I use the same passwords for SMTP authentication as I use for
+ Courier IMAP access to my server?
+
+A0730: You can access the Courier authdaemon from an Exim authenticator. You
+ must arrange for the Exim user (often \/exim/\ but sometimes \/mail/\)
+ to be able to access \(/var/run/courier/authdaemon/socket)\. The
+ configuration is something of a hack, but it is reported to work. Here
+ is a LOGIN authenticator:
+
+==> login:
+ driver = plaintext
+ public_name = LOGIN
+ server_prompts = Username:: : Password::
+ server_condition = \
+ ${if eq {${readsocket{/var/run/courier/authdaemon/socket}\
+ {AUTH 76\n${length_76:exim\nlogin\n$1\n$2\
+ \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\
+ \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\
+ \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n}}}}{FAIL\n} {no}{yes}}
+ server_set_id = $1
+
+ Here is a PLAIN authenticator:
+
+==> plain:
+ driver = plaintext
+ public_name = PLAIN
+ server_prompts = :
+ server_condition = \
+ ${if eq {${readsocket{/var/run/courier/authdaemon/socket}\
+ {AUTH 76\n${length_76:exim\nlogin\n$2\n$3\
+ \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\
+ \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\
+ \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n}}}}{FAIL\n} {no}{yes}}
+ server_set_id = $2
+
+
+Q0731: Is there any defence I can use against spam sent through an open proxy?
+
+A0731: The \*ident*\ feature can be used in some cases. See the discussion in
+ Q5023.
+
+
+Q0732: I would like to either warn or deny when a host uses an underscore in
+ the EHLO command.
+
+A0732: First, set
+
+==> helo_allow_chars = _
+
+ This tells Exim not to reject the EHLO or HELO command immediately. Once
+ you have done that, you can test for the underscore in an ACL. For
+ example, to log a warning for hosts in your LAN, and reject for other
+ hosts, you could do something like this:
+
+==> deny message = Underscores are not valid in host names
+ hosts = ! +lan_hosts
+ condition = ${if match{$sender_helo_name}{_}{yes}{no}}
+
+==> warn log_message = Accepted underscore from [$sender_host_address]
+ condition = ${if match{$sender_helo_name}{_}{yes}{no}}
+
+
+Q0733: Is there any way to tell Exim not to lookup the IP address against any
+ DNS black list if the connection is over IPv6?
+
+A0733: Use this condition in your ACL:
+
+==> condition = ${if match{${mask:$sender_host_address/0}}\
+ {${mask:::0/0}}{no}{yes}}
+
+ From Exim 4.23 onwards, this can be simplified to
+
+==> condition = ${if isip6{$sender_host_address}{no}{yes}}
+
+
+Q0734: How do MailScanner and Exiscan compare? What are the pros and cons?
+
+A0734: The big advantage of Exiscan is that it can reject messages at SMTP time
+ before you have accepted responsibility for them, which means you don't
+ have to deal with bouncing messages and thereby becoming a collateral
+ spammer.
+
+ The big advantage of MailScanner is that it gives you much greater
+ control over the load on your machines. You configure it according to
+ the maximum processing capacity of your computer and it will not exceed
+ that; in fact because it deals with messages in batches the cost of
+ processing a message actually goes down slightly as the load increases,
+ because the per-batch costs are shared by more messages.
+
+ With Exiscan, you have to rely on Exim's load protection mechanisms,
+ which basically means that you have to stop accepting messages when your
+ machine gets too loaded. This is bad if the machine happens to be an
+ SMTP smarthost. You therefore need more overcapacity with Exiscan than
+ with MailScanner.
+
+
+Q0735: How can I block non-FQDNs in HELO/EHLOs?
+
+A0735: Many workstation clients send single-component names; take care that you
+ do not block legitimate mail. With that proviso, you can do it using
+ something like this in an ACL:
+
+==> drop message = HELO doesn't look like a hostname
+ log_message = Not a hostname
+ condition = ${if match{$sender_helo_name} \
+ {\N^[^.].*\.[^.]+$\N}{no}{yes}}
+
+ This means: Drop the HELO unless it contains a dot somewhere in the HELO
+ string, but the string may not begin or end with a dot. Thus, the
+ imposed minimum length is 3 characters.
+
+ The data for HELO/EHLO doesn't have to be a host name; it may
+ legitimately be an IP address literal instead. The above test succeeds
+ with an IPv4 address literal, but if you want also to accept IPv6
+ address literals, you will have to modify the regular expression.
+
+
+Q0736: Is it possible to tell exim to drop the connection after a server
+ attempts to send a message to a number of unknown users?
+
+A0736: Yes. Use \$rcpt_fail_count$\ and the \^drop^\ ACL command, as in this
+ example:
+
+==> drop message = Too many unknown users
+ condition = ${if >{$rcpt_fail_count}{15}{yes}{no}}
+
+
+Q0737: Is there some way to tell Exim not to consider 127.0.0.1 as a valid MX?
+
+A0737: See Q0319.
+
+
+Q0738: How can I configure Exim to delay the SMTP connection if more than 10
+ invalid recipients are received in one message?
+
+A0738: Put something like this in your RCPT ACL:
+
+==> deny message = Max $rcpt_fail_count failed recipients allowed
+ condition = ${if >{$rcpt_fail_count}{10} {1}}
+ ! verify = recipient
+ delay = ${eval: $rcpt_fail_count * 10}s
+ log_message = $rcpt_fail_count failed recipient attempts
+
+ This example increases the delay for each failed recipient.
+
+
+Q0739: Does Exim support SPF?
+
+A0739: An Exim ACL can be used. See \?http://spf.pobox.com/downloads.html?\.
+
+
+
+8. REWRITING ADDRESSES
+
+Q0801: How can I get Exim to strip the hostname from the sender's address?
+
+A0801: If you set up a rewriting rule in the following form:
+
+==> *@*.your.domain $1@your.domain
+
+ then Exim will rewrite all addresses in the envelope and the headers,
+ removing anything between \"@"\ and \"your.domain"\. This applies to all
+ messages that Exim processes. If you want to rewrite sender addresses
+ only, the the rule should be
+
+==> *@*.your.domain $1@your.domain Ffrs
+
+ This applies the rule only to the envelope sender address and to the
+ ::From::, ::Reply-to::, and ::Sender:: headers.
+
+
+Q0802: I have Exim configured to remove the hostname portion of the domain on
+ outgoing mail, and yet the hostname is present when the mail gets
+ delivered.
+
+A0802: Check the DNS record for your domain. If the MX record points to a CNAME
+ record instead of to an A record, some MTAs (not Exim) are liable to
+ rewrite addresses, changing your domain name to its ``canonical'' form,
+ as obtained from the CNAME record.
+
+
+Q0803: I want to rewrite local addresses in mail that goes to the outside
+ world, but not for messages that remain within the local intranet.
+
+A0803: You can use the \headers_rewrite\ option on a transport to do this.
+ The rewriting will then apply to just those copies of a message that
+ pass through the transport. The \return_path\ option can similarly be
+ used to rewrite the sender address. There is no way of rewriting
+ recipient addresses at transport time. However, as these are by
+ definition remote addresses, you probably don't want to rewrite them.
+
+ You have to set up the configuration so that it uses different SMTP
+ transports for internal and external mail. If you are using a single
+ router in both cases, you could configure it like this:
+
+==> dnslookup:
+ driver = dnslookup
+ transport = ${if match{$domain}{\N\.my\.domain$\N}{int_smtp}{ext_smtp}}
+
+ This example uses the \%int_smtp%\ transport for domains ending in
+ \(.my.domain)\, and \%ext_smtp%\ for everything else. The \%ext_smtp%\ transport
+ could be something like this:
+
+==> ext_smtp:
+ driver = smtp
+ headers_rewrite = *@*.my.domain \
+ ${lookup{$1}cdb{/etc/$2/mail.handles.cdb}{$value}fail}
+ return_path = \
+ ${if match{$return_path}{\N^([^@]+)@(.*)\.my\.domain$\N}\
+ {\
+ ${lookup{$1}cdb{/etc/$2/mail.handles.cdb}{$value}fail}\
+ }\
+ fail}
+
+ This example uses a separate file of local-to-external address
+ translations for each domain. This is not the only possibility, of
+ course. The \headers_rewrite\ and \return_path\ options apply the same
+ rewriting to the header lines and the envelope sender address,
+ respectively.
+
+
+Q0804: I'm using this rewriting rule to change login names into ``friendly''
+ names, but if mail comes in for an upper case login name, it doesn't
+ get rewritten.
+
+==> *@my.domain ${lookup{$1}dbm{/usr/lib/exim/longforms}\
+ {$value}fail}@my.domain bcfrtFT
+
+ The longforms database has entries of the form:
+
+==> ano23: A.N.Other
+
+A0804: Replace \"$1"\ in your rule by \"${lc:$1}"\ to force the local part to lower
+ case before it is used as a lookup key.
+
+
+Q0805: Is it possible to completely fail a message if the rewrite rules fail?
+
+A0805: It depends on what you mean by ``fail a message'' and what addresses you
+ are rewriting. If you are rewriting recipient addresses for your local
+ domain, you can do:
+
+==> *@dom.ain ${lookup{$1}dbm{/wher/ever}{$value}{failaddr}} Ehq
+
+ and in your alias file put something like
+
+==> failaddr: :fail: Rewriting failed
+
+ This fails a single recipient - others are processed independently.
+
+
+Q0806: I'm using \$domain$\ as the key for a lookup in a rewriting rule, but its
+ contents are not being lowercased. Aren't domains supposed to be handled
+ caselessly?
+
+A0806: The value of \$domain$\ is the actual domain that appears in the address.
+ It could of course be lower cased, but I know that would cause some
+ unhappiness, because some people have mixed-case domain names which look
+ silly if the case is changed. Thus, one wants to preserve the case in
+ rewrites such as
+
+==> *@*.TheRap.com something@$domain
+
+ because ``therap'' doesn't look like two words. I know it seems trivial,
+ but it is important to some people - especially if by some unfortunate
+ accident the lowercased word is something indecent.
+
+ You can trivally force lower casing by means of the \"${lc:"\ operator.
+ Instead of \"$domain"\ write \"${lc:$domain}"\.
+
+
+Q0807: I want to rewrite local sender addresses depending on the domain of the
+ recipient.
+
+A0807: In general, this is not possible, because a message may have more than
+ one recipient and Exim keeps just a single copy of each message. It may
+ also deliver one copy of a message with several recipient addresses.
+ You can do an incomplete job by using a regular expression match in a
+ rewrite rule to test, for example, the contents of the ::To:: header. This
+ would work except in cases of multiple recipients.
+
+
+
+9. HEADERS
+
+Q0901: I would like add some custom headers to selected outgoing mail based on
+ a specific domain and the subject line.
+
+A0901: To the remote_smtp transport, add something like
+
+==> headers_add = ${if and{\
+ {eq{$domain}{spec.dom}}\
+ {matches{$h_subject:}{whatever}}}\
+ {Content-Type: text/html; charset="us-ascii"} fail }
+
+ This example shows a ::Content-Type:: header, but you can have anything you
+ like, and multiple headers can be inserted by using \"@\n"\ to separate them.
+
+
+Q0902: Is it possible to have Exim add a header to only certain local parts of
+ outgoing mail?
+
+A0902: Only if you arrange for each such local part to receive its own private
+ copy of the mail. See \max_rcpt\ in the SMTP transport. If you set this
+ to 1, you could use conditions in an expansion string to add or not add
+ a header.
+
+
+Q0903: How can I remove some part of the ::Received:: header?
+
+A0903: Set \received_header_text\.
+
+
+Q0904: How I can insert the PGP header line using Exim filters?
+
+A0904: You can't insert headers in a user filter. A system filter can do so,
+ but the inserted lines then are included for all recipients.
+
+
+Q0905: I know I can use a system filter to replace certain headers in messages,
+ but how can I add text to existing headers? I want to add [SPAM] to
+ the subject line of messages that appear to be spam.
+
+A0905: You can only do this in a round about way, using filter commands like
+ this:
+
+==> headers add "New-Subject: SPAM: $h_subject:"
+ headers remove subject
+ neaders add "Subject: $h_new-subject:"
+ headers remove new-subject
+
+ This trick works only in system filters, where the commands are obeyed
+ in order, and affect the master list of headers that apply to the whole
+ message. You cannot do this with the \headers_add\ and \headers_remove\
+ options on drivers.
+
+
+
+10. PERFORMANCE
+
+Q1001: I'm running a large mail server. Should I set \split_spool_directory\ to
+ improve performance?
+
+A1001: Splitting the spool directory has most benefit if there are times when
+ there are a large number of messages on the queue. If all mail is
+ delivered very quickly, and the queue is always less than, say, a few
+ hundred messages, there isn't any need to do this. With larger queues,
+ there is a definite performance benefit to splitting the spool. It shows
+ up earlier on some types of filing system, compared with others.
+
+ Exim was not designed for handling large queues. If you are in an
+ enviroment where lots of messages remain on the queue for long periods
+ of time, consider implementing a back up host to which you pass these
+ messages, so that the main host's queue remains short. You can use
+ \fallback_hosts\ to do this, or a router that is conditional on
+ \$message_age$\.
+
+
+Q1002: How well does Exim scale?
+
+A1002: Although the author did not specifically set out to write a high-
+ performance MTA, Exim does seem to be fairly efficient. The biggest
+ server at the University of Cambridge (a large Sun box) goes over
+ 100,000 deliveries per day on busy days (it has over 20,000 users).
+ There was a report of a mailing list exploder that sometimes handles
+ over 100,000 deliveries a day on a big Linux box, the record being
+ 177,000 deliveries (791MB in total). Up to 13,000 deliveries an hour
+ have been reported.
+
+ These are quotes from some Exim users:
+
+ "... Canada's largest internet provider, uses Exim on all of our mail
+ machines, and we're absolutely delighted with it. It brought life back
+ into one of our machines plagued with backlogs and high load averages.
+ Here's just an example of how much email our largest mail server
+ (quad SS1000) is seeing ... " [230,911 deliveries in a day: 4,475MB]
+
+ "... Exim has to ... do gethostbyname()s and RBL lookups on all of the
+ incoming mail servers, and he runs from inetd (TCP Wrappers connected).
+ All the same, it seems to me that he runs as fast as lightning on our
+ SCO 5.0.4 box (1 Pentium 166) - far faster than MMDF which I (and many
+ customers) had before."
+
+ "On a PII 400 with 128M of RAM running Linux 2.2.5, I have achieved
+ 36656 messages per hour (outgoing unique messages and recipients). For
+ about a 5 minute period, I was able to achieve an average of 30 messages
+ per second (that would be 108000 m/hour)! We are using: (options that
+ make a difference):
+
+==> queue_only
+ split_spool_directory
+ queue_run_max = 1
+ remote_max_parallel = 1
+
+ We have a cron job hat runs every five minutes that spawns 5 \"exim -q"\ if
+ there are less that 120 exim processes currently running. We found
+ that by manually controlling the concurrency of \"exim -q"\ processes
+ contending for the spool for \%remote_smtp%\ delivery that we gained
+ considerable performance - 10000 m/hour."
+
+
+Q1003: We have a large password file. Can Exim use alternative lookups during
+ delivery to speed things up?
+
+A1003: If you are using FreeBSD, this problem should not arise, because it
+ automatically uses an indexed password file. In some other operating
+ systems you can arrange for this to happen too. On Linux, for example,
+ all you need to do is
+
+==> # cd /var/db
+ # make
+
+ and put \"db"\ before \"files"\ in any \(/etc/nsswitch.conf)\ lines you want to
+ use db for.
+
+ On systems that do not include support for indexed password files, you
+ can build one yourself, and reference it from the Exim configuration.
+ For example, for routing to local mailboxes you could use this:
+
+==> localuser:
+ driver = accept
+ condition = ${lookup{$local_part}cdb{/etc/passwd.cdb}{yes}{no}}
+ transport = local_delivery
+ user = ${extract{1}{:}{${lookup{$local_part}cdb{/etc/passwd.cdb}}}
+
+ This assumes a cdb version of the password file.
+
+
+Q1004: I just wondered if it might be helpful to put the hints database on a
+ RAM disk during regular operation. Did anybody try that yet?
+
+A1004: A user reported thus: ``I have found that this works great under Solaris.
+ Make a RAM disk partition and keep everything in the \(db)\ directory on
+ it. However, when I try the same thing on Linux, I don't see the same
+ boost. I think that Linux's file buffer cache works about the same.
+ Plus, this leave more room for processes to run.''
+
+ There have been other reports that Linux's delayed buffer write provides
+ better overall performance in general.
+
+ Apparently there is support in the Solaris kernel for a delayed writing,
+ as in Linux, but Sun's server policy is to have it disabled so that you
+ don't lose so much if the server crashes. There is a program called
+ \^fastfs^\ to enable and disable this support. You have to download and
+ compile it yourself; find it by looking for \"fastfs.c"\ in a search
+ engine. Solaris performance is reported to be much improved, but you
+ should take care to understand the potential hazards. In particular,
+ \^fsck^\ may be unable to ``fix'' disks automatically after a crash.
+
+
+Q1005: A lot of incoming mail is pushing up my system load too much, and there
+ are many Exim processes. How can I control this?
+
+A1005: Have you set any of the Exim configuration options that limit what it
+ does under high load? For example, queue_only_load, deliver_queue_load_max?
+ See the list in the section entitled \*Resource control*\ in the manual.
+
+ It sounds like a lot of simultaneous incoming mail pushes your system
+ into uncontrolled overload. The multiple Exim processes are probably
+ just multiple incoming messages. You can use the \^exiwhat^\ utility to
+ confirm this.
+
+
+
+11. MAJORDOMO
+
+Q1101: How do I set up Majordomo to work with Exim?
+
+A1101: Users have found several ways of setting up Exim for use with Majordomo.
+ One way has been documented at
+ \?http://www.averillpark.net/exim/majordomo.html?\.
+
+ Somewhere in the Majordomo docs or FAQ it mentions using batchmail or
+ other additional programs to improve the performance of large lists.
+ They are not needed with Exim, and their use can actually make things
+ worse. However, it's a good idea to set \remote_max_parallel\ to a value
+ greater than 1 in the Exim configuration.
+
+
+Q1102: I have set \$mailer$\ in \(majordomo.cf)\, but it still isn't setting the
+ sender correctly in the messages it sends.
+
+A1102: Make sure you have got the quoting correct in the \$mailer$\ setting. For
+ example,
+
+==> $mailer = "$sendmail_command -oi -oee -f$sender\@lists.mydomain.de";
+
+ is not correct. It needs three backslashes, not one, and the $ at the
+ start of \$sender$\ has to be escaped with a backslash.
+
+
+Q1103: I'm trying to set up majordomo, but I'm getting a wrong mode error
+ when I try to send it mail.
+
+A1103: Check the mode of \(/var/lib/majordomo/lists/lists.aliases)\ and compare it
+ with the setting of the \modemask\ option in the Majordomo aliases
+ router. This option specifies bits which must not be set for the alias
+ file, and it defaults to 022.
+
+
+Q1104: I'm getting return code 9 from \(/home/majordomo/majordomo-1.94.4/wrapper)\
+ when it is passed a message from Exim.
+
+A1104: A problem like this turned out to be the Perl version that came with
+ RedHat 5.2. Rebuilding Perl 5.005x solved it.
+
+
+Q1105: Exim is complaining about an invalid command line when Majordomo tries
+ to send it a message for delivery.
+
+A1105: Take a look at your \(majordomo.cf)\ file, It should have something that
+ looks like
+
+==> $sendmail_command = "/usr/lib/sendmail";
+
+ and another line like
+
+==> $mailer = "$sendmail_command -oi -oee -f\$sender";
+
+ If you have modified \^resend^\ (one of the majordomo programs) to use
+ \$sendmail_command$\ instead of \$mailer$\ you will be calling Exim with no
+ command line arguments.
+
+
+
+12. FETCHMAIL
+
+Q1201: When I run fetchmail, I get the error \*SMTP listener doesn't like
+ recipient address xxx@localhost*\.
+
+A1201: Make sure that //localhost// is recognized as a domain that is to be
+ delivered locally. If you are using the default Exim run time
+ configuration, you'll see a line near the top like this:
+
+==> domainlist local_domains = @
+
+ Change it to
+
+==> domainlist local_domains = @ : localhost
+
+
+Q1202: I'm currently using Exim with fetchmail and I'd like to use the RBL on
+ Exim, but will it work? Do I need to configure fetchmail any particular
+ way? As far as Exim knows, all mail is coming from 127.0.0.1. Will it
+ check the source address against RBL? Or will it check the ::From:: header?
+
+A1202: It will check 127.0.0.1 (not very useful). The point of the RBL is to
+ keep messages from black-listed hosts out of your machine. If you are
+ using fetchmail, you have got the messages into your machine before you
+ approach Exim. That kind of defeats the purpose of the RBL. The right
+ way to do this would be for the host from which you fetch your mail to
+ do the RBL checking and insert some kind of warning header for you to
+ test, as Exim does if you run RBL checks in warning mode.
+
+
+
+13. PERL
+
+Q1301: Exim built with Perl support exits with the error message \*./exim: can't
+ load library 'libperl.so'*\.
+
+A1301: If you are using BSDI, see Q9401.
+
+
+Q1302: Exim built with Perl support exits with several error messages of the
+ form \*undefined reference to `PL_stack_sp'*\.
+
+A1302: This has been seen on FreeBSD systems that had two different versions of
+ Perl installed, the older with an \^a.out^\ library and the newer with an
+ ELF library. Ensure that the older package is removed.
+
+
+
+14. DIAL-UP AND ISDN
+
+Q1401: When I'm not connected to the Internet, how can I arrange for mail to
+ other hosts on my local network to be delivered, while at the
+ same time mail to Internet hosts is queued without any delivery
+ attempts?
+
+A1401: Use the \queue_domains\ option to control which domains are held
+ on the queue for later delivery. For example,
+
+==> queue_domains = ! *.localnet
+
+ allows delivery to domains ending in \(.localnet)\, while queueing all the
+ others.
+
+
+Q1402: I have a dial-up machine, and I use the \queue_smtp_domains\ option so
+ that remote mail only goes out when I do a queue run. However, any email
+ I send with an address \(anything@aol.com)\ is returned within about 15
+ minutes saying \*retry time exceeded*\, and all addresses are affected.
+
+A1402: You should be using \queue_domains\ rather than \queue_smtp_domains\.
+ With the latter, Exim is trying to route the addresses, which involves a
+ DNS lookup. This is presumably timing out, causing a retry time to be
+ set for the domain, and somehow a valid lookup never happened before the
+ maximum retry time (default of 4 days) passed. Hence the bounce. The
+ fact that it is \(aol.com)\ is probably not relevant. You should probably
+ also be using \-qq-\ to do your queue run rather than \-q-\.
+
+
+Q1403: How should Exim be configured when it is acting as a temporary storage
+ system for a domain on a dial-up host?
+
+A1403: Exim isn't really designed for this, but... The lowest-numbered MX
+ record for the domain should be pointing to the dial-up host. A higher
+ numbered MX record (lower priority) should point to the Exim server that
+ is acting as a temporary storage system.
+
+ You should set a large retry time for the domain, so that Exim doesn't
+ keep trying to deliver when the host is offline. When the host comes
+ online, the waiting messages have to be kicked somehow. This can be done
+ by calling Exim with the \-R-\ option, or via the SMTP ETRN command.
+
+ This works provided the number of messages is low. If you are handling
+ lots of mail, keeping messages waiting for their host to connect and
+ those that are having delivery problems to remote hosts all in the same
+ queue doesn't work so well. It is better in this case to get Exim to
+ deliver the mail for the dial-in hosts into some local files which then
+ get transmitted by other software when the host connects. One tool for
+ doing this can be found at \?http://cr.yp.to/serialmail.html?\.
+
+ For further discussion, see section entitled \*Intermittently connected
+ hosts*\ in the manual, and also the section in the Exim book with the
+ same name.
+
+
+Q1404: I have \queue_domains\ or \queue_smtp_domains\ set, and use \-qf-\ to
+ force delivery of waiting mail when I dial in. How can I arrange for any
+ new messages that arrive while I'm connected to be delivered immediately?
+
+A1404: Instead of \queue_domains\ or \queue_smtp_domains\, use the \queue_only_file\
+ option. This causes messages to be queued if a particular file exists.
+ If you put the word ``smtp'' before the file name, the queueing applies
+ only to domains that are delivered by SMTP, thus not affecting local
+ deliveries:
+
+==> queue_only_file = smtp/etc/present/when/not/connected
+
+ Then, in the scripts which are run when you connect and disconnect,
+ arrange to remove the file after connection, and create it just before
+ disconnection.
+
+
+Q1405: I have an ISDN connection and would like a way of running the queue
+ automatically when it is up.
+
+A1405: The following shell commands test for the interface being up and then
+ run the queue:
+
+==> ifconfig ppp0 | fgrep UP >/dev/null
+ if [ $? -eq 0 ] ; then exim -q ; fi
+
+ You could put these commands into a script which runs them at regular
+ intervals. You might want to use \-qq-\ instead of \-q-\.
+
+ With Linux, the script \(/etc/ppp/ip-up)\ is run after a ISDN connection
+ or a more general PPP connection has been established. If you are using
+ Linux, you could put the call to Exim in that script.
+
+
+Q1406: When I dial up to collect mail from my ISP, only the first 10 messages
+ get delivered immediately; the remainder just sit on the queue until a
+ queue runner process finds them.
+
+A1406: See Q0049.
+
+
+Q1407: RFC 1985 specifies that the SMTP command \"ETRN host.domain"\ causes all
+ mail queued for that host, no matter what domain it's for, to be
+ delivered. Why doesn't Exim support this?
+
+A1407: Exim does not keep queues of mail for specific destinations. It just
+ keeps one pool of undelivered messages. What is more, once you start a
+ delivery of a message, it tries to deliver to all the addresses in the
+ message, not just the one you may be interested in. (Of course, this
+ doesn't usually do any harm.)
+
+ The only way it could be done within Exim would be, for every message
+ on the queue, to go through the motions of routing each undelivered
+ address and see if that resulted in a delivery to the host of interest.
+ This could be extremely expensive (e.g. 1,000 messages on the queue,
+ only 1 for the given host).
+
+ The bottom line is that Exim just wasn't designed for this kind of
+ operation, that is, holding messages for intermittently connected hosts.
+ The queueing arrangements are designed for handling delivery problems
+ that are not expected to be common.
+
+ A better way to do this is to implement the required queues separately.
+ After all, keeping such mail on an active queue (where Exim will keep
+ trying to deliver) is silly. If there is a lot of mail for these hosts,
+ it also masks genuine delivery problems when you inspect the queue.
+
+ Large ISPs who provide this kind of functionality do not usually leave
+ waiting mail on the MTA's queue. Instead, they get it delivered into
+ per-host directories, one message per file, in one of the special
+ formats (BSMTP, maildir, or mailstore) and when an ETRN arrives, it
+ kicks off some completely different program that establishes an SMTP
+ connection to the host and shovels the waiting mail down it. That seems
+ to me to be a much neater way of doing this. It means you can easily add
+ additional functionality such as archiving or throwing away uncollected
+ mail.
+
+ One program that has this functionality is \^ssmtp^\, which can be
+ found in \?ftp://metalab.unc.edu/pub/Linux/system/mail/mta/?\.
+ Alternatively, sample configuration C037 demonstrates an elegant way of
+ using Exim itself to deliver the saved messages when the client issues
+ an ETRN.
+
+
+Q1408: If email has been deferred to a member on a local mailing list
+ (implemented through forward files), and one of our ETRN clients is on
+ this mailing list, the \-R-\ won't flush the mailing list message for
+ that client.
+
+A1408: That is because \-R-\ matches only original recipient addresses, not those
+ produced as a result of expansion, because these are not (by default)
+ preserved from delivery to delivery. You can get round this by setting
+ \one_time\ on the forwarding router, but you are not allowed to have
+ expansions to pipes or files on routers that have \one_time\ set.
+ Therefore, you will have to have a separate router for mailing lists
+ (with \one_time\ set) to the one used for normal forward files that might
+ specify pipe or file deliveries. However, the problem will still be
+ present for any user who sets up a \(.forward)\ file to redirect to any of
+ the ETRN domains. See the last 3 paragraphs of Q1407 for a discussion of
+ an alternative approach.
+
+
+Q1409: I would like to have a separate queue per domain for hosts which dial
+ in to collect their mail.
+
+A1409: Exim isn't really designed for this kind of operation. The only way to
+ do this would be to cause it to send those messages to a differently
+ configured version of Exim with its own spool area. This could be done
+ via a pipe or SMTP to a private port. The main Exim, listening on port
+ 25, would then be configured to run an appropriate command to prod one
+ of the others when it received ETRN, by means of the \smtp_etrn_command\
+ option.
+
+ You could probably manage this with a single Exim binary and a number of
+ different configuration files, passed to the special versions using the
+ \-C-\ option. For this application they could all run as \^exim^\, since no
+ root privilege would be needed.
+
+ An alternative approach id to get Exim to deliver mail for such hosts
+ in batch SMTP format into some directory, and have the ETRN run
+ something to pass such messages to the dialled-in host. See also Q1403.
+
+
+
+15. UUCP
+
+Q1501: The MX records for some UUCP domains point to my local host. How do I
+ get it to pass the messages on to UUCP?
+
+A1501: The simplest way is to create a file containing a list of domains, and
+ the hosts to which their messages should be sent, like this:
+
+==> uucp1.domain.example: uucp1.host.example
+ uucp2.domain.example: uucp2.host.example
+ ....
+
+ Then you can use a router like this:
+
+==> uucp_router:
+ driver = accept
+ domains = lsearch;/etc/uucp/domains
+ transport = uucp_transport
+
+ and a transport like this:
+
+==> uucp_transport:
+ driver = pipe
+ user = nobody
+ command = /usr/local/bin/uux - -r $domain_data!rmail $local_part
+ return_fail_output
+
+ The \$domain_data$\ variable retains the value that is looked up when
+ the \domains\ option in the router is matched.
+
+
+Q1502: How can I get Exim to handle ``bang path'' addresses?
+
+A1502: In general, you can't (Exim is an Internet mailer and recognizes only
+ RFC 2822 domain-style addresses) but some restricted kinds of bang path
+ can be dealt with by appropriate rewriting - but please note the warning
+ below.
+
+ Exim treats a bang path address as an unqualified local part, and so
+ will qualify it with your domain. A rule such as
+
+==> \N^([^!]+)!(.+)@your\.domain$\N $2@$1
+
+ turns \(a!b@your.domain)\ into \(b@a)\. You can also use a repeating rule to
+ turn multi-component paths into the ``percent hack'' notation with a rule
+ such as
+
+==> \N^([^!]+)!([^@%]+)(.+)$\N $2%$1$3 R
+
+ which turns \(a!b@c)\ into \(b%a@c)\ and \(a!b!c@d)\ first into \(b!c%a@d)\ and then,
+ because of the R flag, into \(c%b%a@d)\. The R flag causes repetition up to
+ 10 times.
+
+ \**Warning:**\ If you install a general rewriting rule like the above, you are
+ opening yourself up to the possibility of unwanted relaying. A host that
+ is not permitted to relay through your system could send a message with
+ an SMTP command line such as
+
+==> RCPT TO:<victim-host!victim-user@your.domain>
+
+ and this would be accepted because it is addressed to your domain.
+ However, the rewriting then converts the address, and the message does
+ in fact get relayed. One way round this, if all your bang path messages
+ are passed to Exim via SMTP, is to use the \"S"\ rewriting flag. This
+ applies a rewriting rule to incoming SMTP addresses as soon as they are
+ received, before checking for qualification, relaying, etc. So a rule
+ such as
+
+==> \N^([^!]+)!(.+)$\N $2@$1 S
+
+ rewrites simple two-component bang paths before the result is checked
+ for relaying. However, this does not rewrite addresses in the headers of
+ the message.
+
+
+Q1503: We see something strange on our system in regards to mail coming in via
+ rmail from a UUCP link. The sender is being set to mailmaster instead of
+ the real sender, and a ::Sender:: header is being added to the message.
+
+A1503: If \(mailmaster)\ is the user that is running rmail, you need to include
+ that user in the \trusted_users\ configuration option. Only trusted users
+ are permitted to specify senders when mail is passed to Exim via the
+ command line.
+
+
+
+16. MODIFYING MESSAGE BODIES
+
+Q1601: How can I add a disclaimer or an advertisement to a message?
+
+A1601: There are a number of technical and potential legal problems that arise
+ in connection with message modification. Some of them are listed below.
+ Some comment on the legal position of email disclaimers in English law
+ can be found at \?http://www.weblaw.co.uk/artemail.htm?\.
+
+ See also \?http://www.goldmark.org/jeff/stupid-disclaimers/?\. There is
+ some discussion about the problems of actually adding disclaimers in
+ \?http://www.goldmark.org/jeff/stupid-disclaimers/apply.html?\.
+
+ In many cases, email disclaimers will make your company look ridiculous,
+ at the very least. At worst, they may interfere with the normal
+ processing of mail.
+
+ If, despite these considerations, you still want to modify messages, you
+ can do so using Exim, but not directly in Exim itself. It is not the job
+ of an MTA to modify messages, something that requires understanding of
+ their content and format.
+
+ Exim provides a hook called a ``transport filter'' that lets you pass
+ any outgoing message through a program or script of your choice. It
+ is the job of this script to make any changes to the message that you
+ require. By this means, you have full control over what changes are
+ made, and Exim does not need to know anything about message bodies.
+ However, using a transport filter requires additional resources, and may
+ slow down mail delivery.
+
+ You can use Exim's routers to arrange for those messages that you want
+ to modify to be delivered via a transport filter. For example, suppose
+ you want to do this for messages from addresses in your domain that are
+ being delivered to a remote host. First you need to set up a special
+ \%smtp%\ transport that uses a filter, like this:
+
+==> remote_smtp_filter:
+ driver = smtp
+ transport_filter = /your/filter/command
+
+ Then you need to modify the \%dnslookup%\ router to use this transport
+ when the conditions are right:
+
+==> dnslookup:
+ driver = dnslookup
+ domains = ! +local_domains
+ transport = ${if eq {$sender_address_domain}{your.domain}\
+ {remote_smtp_filter}{remote_smtp}}
+ ignore_target_hosts = 127.0.0.0/8
+ no_more
+
+ This is the standard \%dnslookup%\ router, but with a modified setting of
+ the \transport\ option. When the sender address is in your domain, it
+ routes to the special transport instead of the standard one.
+
+ The entire message is passed to your filter command on its standard
+ input. It must write the modified version to the standard output, taking
+ care not to break the RFC 2822 syntax. The command is run as the Exim
+ user.
+
+ There are a number of potential problems in doing this kind of
+ modification in an MTA. Many people believe that to attempt is it wrong,
+ because:
+
+ 1. It breaks digital signatures, which are becoming legally binding
+ in some countries. It may well also break encryption.
+
+ 2. It is likely to break MIME encoding, that is, it is likely to wreck
+ attachments, unless great care is taken. And what about the case of a
+ message containing only binary MIME parts?
+
+ 3. It is illegal under German and Dutch law to change the body of
+ a mail message in transit. It might potentially be illegal in
+ the UK under European law. This consideration applies to ISPs and
+ other ``common carriers''. It would presumably not apply in a corporate
+ environment where modification was done only to messages originating
+ from the employees, before they left the company's network. It might
+ also not apply if the senders have explicitly given their consent
+ (e.g. agreed to have advertisements added to their incoming mail).
+
+ 4. Since the delivered message body was produced by the MTA (not the
+ originator, because it was modified), the MTA operator could
+ potentially be sued for any content. This again applies to `common
+ carrier' MTAs. It's interesting that adding a disclaimer of liability
+ could be making you liable for the message, but this case seems
+ more likely to involve adding advertisements than disclaimers. After
+ all, no postal service in the world opens all the mail it carries to
+ add disclaimers.
+
+ 5. Some mail clients (old versions of MS outlook) crash if the message
+ body of an incoming MIME message has been tampered with.
+
+ There are also potential problems that could arise if a scheme to add
+ disclaimers goes wrong for some messages:
+
+ 1. False negatives: `Ah, this guy usually says he does not represent
+ their views, but in this message he doesn't have the disclaimer'.
+
+ 2. False positives: `This official announcement does not represent our
+ views, oh no'.
+
+ An alternative approach to the disclaimer problem would be to insist
+ that all relevant messages have the disclaimer appended by the MUA. The
+ MTA should refuse to accept any that do not. Again, however, the MTA
+ must understand the format of messages in order to do this. Simply
+ checking for appropriate wording at the end of the body is not good
+ enough. It would probably be necessary to run a Perl script from within
+ an Exim system filter, or write a \^^local_scan()^^\ function in order
+ to adopt this approach.
+
+ Finally, it's a trivial matter to add customized headers of the sort:
+
+==> X-Disclaimer: This is a standard disclaimer that says that the views
+ X-Disclaimer: contained within this message are somebody else's.
+
+ which is a much easier alternative to modifying message bodies.
+
+
+Q1602: How can I remove attachments from messages?
+
+A1602: The answer to this is essentially the same as for Q1601.
+
+
+
+17. ENCRYPTION (TLS/SSL)
+
+Q1701: I am trying to set up an Exim server that uses a self-signed certificate
+ to enable my clients to use TLS. However, clients other than Exim
+ refuse to accept this certificate. What's wrong?
+
+A1701: It seems that some clients require that the certificate presented by
+ the server be a user (also called ``leaf'' or ``site'') certificate, and not
+ a self-signed certificate. In this situation, the self-signed
+ certificate must be installed on the client as a trusted root
+ \*certification authority*\ (CA), and the certificate used by the server
+ must be a user certificate signed with that self-signed certificate.
+
+ For information on creating self-signed CA certificates and using them
+ to sign user certificates, see the \*General implementation overview*\
+ chapter of the Open-source PKI book, available online at
+ \?http://ospkibook.sourceforge.net/?\. Here is a quick overview. First,
+ read this message:
+
+ \?http://www.FreeBSD.org/cgi/mid.cgi?id=3C3F3A93.C1ECF9B0%40mindspring.com?\
+
+ Then, follow the instructions found on these two (consecutive) pages:
+
+ \?http://ospkibook.sourceforge.net/docs/OSPKI-2.4.6/OSPKI/initialisation.htm?\
+ \?http://ospkibook.sourceforge.net/docs/OSPKI-2.4.6/OSPKI/keygensign.htm?\
+
+ Two points on the PKI Book literature:
+
+ (1) It's assumed that it's okay to use a passphrase-protected key to
+ encrypt the user/site/leaf certificate. If this isn't acceptable,
+ you seem to be able to strip out the passphrase as follows:
+
+==> openssl rsa -in user.key -our user.key.new
+ mv user.key.new
+
+ This should be done immediately after \(user.key)\ is created.
+
+ (2) The \*sign.sh*\ script is available in the \*mod_ssl*\ distribution,
+ available at \?http://www.modssl.org/source/?\.
+
+ Having followed the instructions, you end up with the following files:
+
+ (a) \(ca.crt)\
+
+ This file should be installed into the client software as a trusted
+ root certification authority. In Windows XP, this can be done as follows:
+
+ \#\#Call the file \(ca_cert.cer)\
+ [[br]]
+ \#\#Double-click on the file
+ [[br]]
+ \#\#"Install Certificate";
+ [[br]]
+ \#\#"Next"
+ [[br]]
+ \#\#"Place all certificates in the following store"
+ [[br]]
+ \#\#"Browse..."
+ [[br]]
+ \#\#"Trusted Root Certification Authorities"
+ [[br]]
+ \#\#"OK"
+ [[br]]
+ \#\#"Next"
+ [[br]]
+ \#\#"Finish"
+ [[br]]
+ \#\#"Yes"
+ [[br]]
+ \#\#"OK"
+
+ (b) \(user.crt)\ and \(user.key)\
+
+ These files should be installed into the server software. In Exim, this
+ can be done by adding these lines to the configuration file:
+
+==> tls_certificate = /usr/local/etc/exim/tls_cert
+ tls_privatekey = /usr/local/etc/exim/tls_key
+
+ Then install \(user.crt)\ and \(user.key)\ under the names \(tls_cert)\
+ and \(tls_key)\ in the appropriate directory.
+
+
+Q1702: How can I arrange for Exim to advertise support for SMTP authentication
+ only when the session is encrypted?
+
+A1702: Use this setting:
+
+==> auth_advertise_hosts = ${if eq{$tls_cipher}{}{}{*}}
+
+
+Q1703: I have some legacy clients that don't use STARTTLS, but which expect to
+ negotiate a TLS session automatically on connection to the ssmtp port
+ (465). Can Exim handle this?
+
+A1703: The \-tls-on-connect-\ option is available to handle this. You need to
+ run two instances of an Exim listener, listening on different ports, one
+ of which is started with \-tls-on-connect-\. You can either use two
+ daemons, or a single daemon, with the other listenever using \^inetd^\.
+ For example, here are commands to start two daemons:
+
+==> exim -bd -q15m
+ exim -bd -oX '[0.0.0.0]::465' -tls-on-connect
+
+ The first is a ``normal'' daemon; the second listens on port 465 and
+ expects to negotiate a TLS session at the start of each connection.
+
+
+Q1704: When my Outlook Express 6.0 client sends a STARTTLS command to begin a
+ TLS session, Exim doesn't seem to receive it.
+
+A1704: See Q0059.
+
+
+Q1705: I have listed some hosts in \tls_try_verify_hosts\, but when they
+ connect, no data appears in \$tls_peerdn$\.
+
+A1705: This means that the clients have not sent certificates when asked by
+ the server to do so. If the clients are running Exim, check that
+ \tls_certificate\ is correctly set in their \%smtp%\ transports. Note
+ that this value is not automatically inherited from the global
+ \tls_certificate\ option.
+
+
+Q1706: I have listed some hosts in \tls_verify_hosts\ and provided them with
+ certificates, but their connections are always rejected.
+
+A1706: Make sure that the server file containing the expected certificates
+ (defined by \tls_verify_certificates\) is readable by the Exim user.
+ See also the answer to Q1705.
+
+
+Q1707: I am trying to use TLS with Evolution as a client, and keep seeing this
+ error: \*SMTP protocol violation: synchronization error (next input
+ sent too soon): rejected "\200F^A^C".*\ What does it mean?
+
+A1707: See Q0086 for a general explanation of the error. In this case, it
+ probably means that Evolution is trying to negotiate a TLS session
+ immediately it connects, without first using the STARTTLS command. This
+ was an older way of starting up TLS, before STARTTLS was defined. You
+ will have to run a separate instance of Exim using the
+ \-tls-on-connect-\ command line option to cater for this usage, and
+ listening on a different port. For example:
+
+==> exim -bd -oX 465 -tls-on-connect
+
+ 465 is the ``smtps'' port which is an unofficial standard for this kind
+ of SMTP server.
+
+
+Q1708: I trying to use TLS with Outlook as a client on a box that is running
+ Norton Antivirus, but all my email is being rejected with \*Unsupported
+ command*\ errors. Why?
+
+A1708: Norton Antivirus does not support TLS or AUTH. It puts a broken SMTP
+ proxy between you and the Exim server. You need to turn off outbound
+ scanning of email.
+
+
+
+20. MILLENNIUM
+
+Q2000: Are there any Y2K issues with Exim?
+
+A2000: The author of Exim believes that it is Y2K-compliant, as long as the
+ underlying operating system and C library are. Exim does not parse dates
+ or times at all. Internally, it makes some use of binary timestamps in
+ Unix format (number of seconds since 1-Jan-1970) and uses C library
+ services to convert these to printing forms (e.g. for logging). The
+ printing forms all use 4-digit years. Some people have tried various
+ tests. No problems have been reported, but details of what tests have
+ been done are not available.
+
+ Well, it's now November 2001, and no Y2K problems have been reported, so
+ it looks like I was right. This entry is retained as historical
+ nostalgia.
+
+
+
+50. MISCELLANEOUS
+
+Q5001: How can I arrange to allow a limited set of users to perform a limited
+ set of Exim administration functions? I don't want to put them all in
+ the //exim// group.
+
+A5001: See \?http://www.chiark.greenend.org.uk/~ian/userv/?\. Using \^userv^\ you can
+ arrange (for example) for certain users to be able to invoke \^mailq^\ or
+ \^runq^\ or other preset commands as \^exim^\ (or any other user, as configured)
+ with only \^userv^\ configuration. If you want to check the particular Exim
+ options available you can easily do it with shell or Perl scripts and
+ \^userv^\ configuration, and provided you know how to do argument
+ ``unparsing'' properly in shell or Perl it will be secure.
+
+
+Q5002: I want to ``tail'' the Exim log, but I have a number of other logs I also
+ want to ``tail'', and the number of tailing windows is getting to be a
+ nuisance.
+
+A5002: Look for a program called \^xtail^\ (despite its name, it's not an
+ X-windows application). It allows you to do multiple tails, even of
+ entire directories.
+
+ Alternately, get the GNU version of \^tail^\, from the GNU textutils
+ package (\?ftp://ftp.gnu.org/gnu/textutils/?\). GNU tail lets you run
+ \"tail -f\" on multiple files at the same time, although it doesn't work
+ on entire directories like \^xtail^\ can. If you are running Linux, you
+ probably already have a version of GNU \^tail^\ that can follow multiple
+ files.
+
+
+Q5003: How can I persuade Exim to accept ETRN commands without the leading
+ # character?
+
+A5003: Set the option
+
+==> smtp_etrn_command = /usr/lib/sendmail -R $domain
+
+ This causes Exim to run that command, with \$domain$\ replaced by the
+ argument of ETRN. The default action of Exim is to require the # sign
+ in order to be RFC-compliant, and to run the equivalent of
+
+==> smtp_etrn_command = /usr/lib/sendmail -R ${substr_1:$domain}
+
+ which uses the argument without the leading # as the value for the \-R-\
+ option. You aren't restricted to running Exim with the \-R-\ option, of
+ course. You can specify any command you like, with any number of
+ arguments. In particular, you can pass over the IP address of the caller
+ via \$sender_host_address$\. However, if you make use of expansion strings
+ in the arguments, each one must be entirely contained in a single
+ argument. For example, if you want to remove the first character of the
+ ETRN argument when it is @ or #, you could use
+
+==> smtp_etrn_command = "/usr/lib/sendmail -R \
+ \"${if match {$domain}{^[@#]}{${substr_1:$domain}}{$domain}}\""
+
+ The internal quotes are necessary because of the white space inside the
+ expansion string.
+
+
+Q5004: I've recently noticed that emails I send with a ::Bcc:: line are being
+ delivered to their final destination with the ::Bcc:: line still present.
+
+A5004: Exim removes ::Bcc:: lines only if you call it with the \-t-\ option (i.e.
+ when it is acting partly as an MUA). It does not remove ::Bcc:: lines that
+ are present in incoming SMTP mail or command-line mail that does not
+ use \-t-\. Indeed, it should not remove them, because only the
+ initiating software (i.e. the MUA) can tell what to do with ::Bcc::
+ lines; any MTA software has to leave them alone. This is what RFC 2822
+ has to say about ::Bcc::
+
+ \*The ::Bcc:: field (where the ``Bcc'' means ``Blind Carbon Copy'') contains
+ addresses of recipients of the message whose addresses are not to be
+ revealed to other recipients of the message. There are three ways in
+ which the ::Bcc:: field is used. In the first case, when a message
+ containing a ::Bcc:: field is prepared to be sent, the ::Bcc:: line is
+ removed even though all of the recipients (including those specified
+ in the ::Bcc:: field) are sent a copy of the message. In the second
+ case, recipients specified in the ::To:: and ::Cc:: lines each are sent
+ a copy of the message with the ::Bcc:: line removed as above, but the
+ recipients on the ::Bcc:: line get a separate copy of the message
+ containing a ::Bcc:: line. (When there are multiple recipient
+ addresses in the ::Bcc:: field, some implementations actually send a
+ separate copy of the message to each recipient with a ::Bcc::
+ containing only the address of that particular recipient.) Finally,
+ since a ::Bcc:: field may contain no addresses, a ::Bcc:: field can be
+ sent without any addresses indicating to the recipients that blind
+ copies were sent to someone. Which method to use with ::Bcc:: fields
+ is implementation dependent, but refer to the ``Security
+ Considerations'' section of this document for a discussion of each.*\
+
+
+Q5005: I used \^gv^\ 3.5.8 (\^ghostview^\) to try printing \(spec.ps)\. After every
+ printed page, the printer ejects a blank sheet. Is this something to do
+ with using ``letter'' rather than A4 paper?
+
+A5005: This seems to be an effect of using \^ghostview^\. Although the PostScript
+ is generated for A4 pages, the size of the page images is such that they
+ should fit on a letter page (they are shorter than would normally be
+ used on A4 paper). If the PostScript file is sent directly to a
+ PostScript printer, there is no problem. An alternative is to get hold
+ of the \^psutils^\ toolset, which is available from
+ \?ftp://ftp.dcs.ed.ac.uk/pub/psutils/psutils.tar.gz?\.
+ It contains utilities for extracting pages (which can be useful for
+ double-sided printing) and for resizing pages. If you resize from A4 to
+ letter the text shrinks a bit, but should then be printable via
+ \^ghostview^\.
+
+
+Q5006: Why aren't there any man pages for Exim? I don't always carry my printed
+ documentation.
+
+A5006: A single man page which lists the command line options is provided in
+ file \(doc/exim.8)\ in the Exim distribution. Several other forms of
+ online documentation are available. As well as plain ASCII text, the
+ there are two forms - Texinfo and HTML - which have a certain amount of
+ built-in indexing for ease of finding your way around. There are no man
+ pages apart from the command line one because the author of Exim hasn't
+ the time (or desire :-) to maintain yet another documentation format.
+ Besides, it is hard to know how to split the Exim manual up.
+
+
+Q5007: When I send a message using the \-t-\ command line option, Exim sends only
+ to the addresses within the message, not to those on the command line.
+
+A5007: There seems to be some confusion in the Sendmail community about the
+ interpretation of recipient addresses on the command line if the \-t-\
+ option is used. Some versions do one thing, and some another. Here is an
+ except from one version of the Sendmail documentation for \-t-\:
+
+ \*Read message for recipients. ::To::, ::Cc::, and ::Bcc:: lines will
+ be scanned for recipient addresses. The ::Bcc:: line will be
+ deleted before transmission. Any addresses in the argument
+ list will be suppressed, that is, they will not receive
+ copies even if listed in the message header.*\
+
+ By default Exim follows this specification, and interprets addresses on
+ the command line as addresses not to send to. You can set
+
+==> extract_addresses_remove_arguments = false
+
+ to change this behaviour so that command line addresses are added to the
+ addresses that are taken from the header lines.
+
+
+Q5008: If I set up a domain list to contain //*customer.com//, it matches
+ //customer.com// and //abc.customer.com// as required, but it also matches
+ //noncustomer.com//, which is wrong. How can I get round this?
+
+A5008: You have to specify two entries in the list:
+
+==> customer.com : *.customer.com
+
+ because * in a domain list matches any characters, including \"."\ and
+ including a null sequence.
+
+
+Q5009: I want to match all domains of the form //*.oyoy.org// but want a few
+ exceptions. For instance I don't want //foo.oyoy.org// or //bar.oyoy.org// to be
+ included. What is the best way to do this?
+
+A5009: Use negative items in the domain list, like this:
+
+==> domainlist local_domains = !foo.oyoy.org : !bar.oyoy.org : *.oyoy.org
+
+ If there are many exceptions, you can use a lookup instead of listing
+ them all inline. If there are a number of exceptions that match a
+ particular pattern, you could use a regular expression.
+
+
+Q5010: I can't seem to find a pre-built version of Exim anywhere. The machine
+ is a Sparc 5 running Solaris 2.6.
+
+A5010: The primary distribution is source-only. However, some people have built
+ and distributed RPMs and debs for Linux systems, and ports for FreeBSD.
+ I haven't heard of anyone doing this for Solaris. The main problem with
+ binary distributions is that there are a number of build-time options,
+ requiring the answers to questions like:
+
+ . Which DBM library do you have? (On Solaris probably ndbm, but no easy
+ default on some other systems.)
+
+ . Which uid/gid do you want to use for Exim?
+
+ . Where do you want the configuration file to be? (Many different
+ answers, even on the same OS, depending on local policy.)
+
+ . Ditto for the binaries.
+
+ . Which optional bits of Exim do you want to include?
+
+
+Q5011: Is there a version of Exim available that runs under Windows?
+
+A5011: A long time ago somebody took a copy of the Exim source with the aim of
+ trying to port it to Windows NT. However, I never heard anything more.
+ However, current versions of Exim can be made to run under Cygwin.
+
+
+Q5012: Does Exim support Delivery Status Notification (DSN), Message Status
+ Notification (MSN), or any other form of delivery acknowledgement?
+
+A5012: See Q0607.
+
+
+Q5013: What does ``Exim'' stand for?
+
+A5013: Originally, it was ``EXperimental Internet Mailer'', which was the best I
+ could come up with when I was starting out. At that point it was
+ experimental - I wanted to see if the ideas I had for extending Smail's
+ approach actually worked. Then somebody discovered about it and wanted
+ to start using it, and told other people about it...
+
+
+Q5014: Although I haven't set \check_spool_space\, Exim is still checking the
+ amount of space on the spool for incoming SMTP messages that use the
+ SIZE option. Can I suppress this?
+
+A5014: The RFC for the SIZE option says:
+
+ \*If the server currently lacks sufficient resources to accept a
+ message of the indicated size, but may be able to accept the
+ message at a later time, it responds with code ``452
+ insufficient system storage''.*\
+
+ and that is what Exim is trying to implement. This is entirely
+ independent from \check_spool_space\, which says \*don't accept any mail
+ if there is less than so much space in the spool partition*\, though the
+ code is optimised to do both checks at the same time if required.
+ However, you can suppress the SIZE check if you want to, by unsetting
+ \smtp_check_spool_space\.
+
+
+Q5015: I just noticed log entries that start off \"<= <>"\. Am I correct in
+ assuming that the \"<>"\ indicates that the envelope did not contain any
+ ``From'' data?
+
+A5015: Yes. This indicates a delivery failure report (aka a ``bounce message''),
+ as specified in RFC 2821. The reason for using empty sender addresses is
+ to identify bounce messages so that they themselves do not cause further
+ bounces. Empty senders are also used for other kinds of report which
+ should not themselves cause the generation of bounce messages. For
+ example, Exim uses them when sending out warnings about delivery delays.
+
+
+Q5016: I've received a message which does not have my address in the ::To::
+ line. It is a spam message with the same address in both the ::From:: and
+ the ::To:: headers. How can this happen, and why doesn't Exim reject it?
+
+A5016: There is an important distinction between the ``envelope'' from and to and
+ the ``header'' from and to. The former are sometimes called the ``sender''
+ and ``recipient''. An email message needs an ``envelope'' for the same
+ reason that paper mail does - the envelope tells the delivery mechanism
+ what to do with this copy of the message, whereas the ::To:: header lists
+ all the recipients, including those who have been sent different copies
+ of the message because their mailbox is on some other host.
+
+ An MTA such as Exim works entirely with the ``envelope'' addresses, not
+ with those in the header lines. Don't try to block mail where envelope
+ from and the header from differ. There are common legitimate cases where
+ this happens, for example, messages forwarded from mailing lists and
+ delivery failure reports.
+
+
+Q5017: Can (or will) Exim ever handle a message delivery purely in memory,
+ that is, it is handled without it ever hitting the disk?
+
+A5017: It doesn't, and never will. Accepting and delivering a message are two
+ entirely separate, independent processes, which communicate only by
+ writing/reading the message on the disk.
+
+
+Q5018: If I am using dbm files for data that Exim reads, can I rebuild them
+ on the fly, or do I need to restart Exim every time I make a change?
+
+A5018: Exim re-reads the file every time it consults it, so if you are using a
+ cdb or a DBM library that uses just a single file (i.e. not ndbm),
+ you can just build the new file with a temporary file name, and use
+ \^mv^\ to rename it into the correct place on the fly. If there are two
+ files to rename, there is a window of time during which the DBM database
+ is inconsistent. On lightly loaded systems this may not matter.
+
+
+Q5019: I need an option that is the opposite of \-bpa-\, that is, a listing of
+ those addresses generated from a top-level address that have not yet
+ been delivered.
+
+A5019: Exim does not keep this information. It saves only the top-level
+ addresses and the list of addresses that are finished with. At each
+ delivery attempt, generated addresses are recomputed from scratch. This
+ makes it possible to correct errors in redirection data that is
+ causing delivery delays. However, there is an option you can set on a
+ \redirect\ router that changes things. It is called \one_time\, and if
+ it is set, the list of generated addresses gets added to the top-level
+ list at the first delivery attempt, and is never regenerated. Because
+ top-level address lists must be real email addresses, this option cannot
+ be used if any of the generated addresses are pipes, files, or
+ autoreplies.
+
+
+Q5020: How can I make Exim receive incoming mail, queue it, but not attempt to
+ deliver it? I want to be in this state while moving some mailboxes.
+
+A5020: Set \queue_only\ in the Exim configuration. Then kill your daemon,
+ and restart it without the \-q-\ option (i.e. with just the \-bd-\ option),
+ so that it does not spawn any queue runners. This stops all deliveries,
+ remote as well as local.
+
+
+Q5021: What does Exim use for POP and IMAP as a default? Do I have to install
+ anything else?
+
+A5021: Yes. Exim provides MTA functionality. That is, it delivers mail. POP and
+ IMAP are two of several ways of reading previously-delivered mail. Exim
+ does not provide that functionality. You need to install POP and/or IMAP
+ daemons; there are several to choose from. There is a mailing list at
+ //pop-imap@exim.org// for the discussion of POP/IMAP issues.
+
+
+Q5022: Is there an easy way of removing all queued messages at once in a safe
+ way?
+
+A5022: Try this command:
+
+==> exim -bp | awk '/^ *[0-9]+[mhd]/{print "exim -Mrm " $3}' | sh
+
+
+Q5023: Why does Exim do \*ident*\ callbacks by default? Isn't this just a waste
+ of resources? I've been told this is an ancient way of authentication.
+ Is it obsolete?
+
+A5023: This is a common misunderstanding, at least partially resulting from the
+ incorrect naming of the protocol when it was first published.
+ The service on port 113 is an identification service, which allows a
+ target host to record information identifying the user responsible for
+ making a connection to it. The information may not be intelligible to
+ the recording host - it could, for example, be encrypted so that only
+ someone on the calling host can make sense of it. It is useful for
+ providing additional information in an audit trail.
+
+ At least one site has found \^ident^\ effective against two rather
+ prevalent kinds of open proxy (whether already blacklisted at the RBLs
+ or not). An ACL statement is used to reject mail from servers that
+ return \^ident^\ strings of \"squid"\ and \"CacheFlow Server"\.
+ Snippets such as this in the RCPT ACL do the trick:
+
+==> deny condition = ${if eq{$sender_ident}{CacheFlow Server}{1}{0}}
+ message = Rejected - appears to be an unsecured proxy: $sender_ident
+
+ The likelihood that a genuine mail process would return those specific
+ ident strings is vanishingly small.
+
+ The \^ident^\ data should not be used for authentication in any form
+ except on a closed secure network between cooperating hosts (probably
+ not even then). The information from the source host is only as reliable
+ as the host itself. If it's not under your control then you have to
+ treat the information as opaque data that can be used only by the
+ sysadmin of the source system to trace back connection data. Some
+ \^ident^\ implementations send out opaque cookies or DES encrypted
+ information. \^Ident^\ is hugely useful at times - especially for
+ checking back on connections from multiuser machines (as opposed to
+ one-person desktop boxes).
+
+ You can stop Exim making ident calls by adding
+
+==> rfc1413_query_timeout = 0s
+
+ to its configuration, but it is better to leave it active (reducing the
+ timeout to 10s or less if it is causing problems) - it costs very
+ little, and in cases of mail forgery from a multiuser system can track
+ the sinner concerned very quickly.
+
+
+Q5024: I often have the problem that a message gets stuck in the mail queue and
+ I want it to be bounced to a certain address.
+
+A5024: You can do this using a combination of four command line options, like
+ this:
+
+==> exim -Mf 14Fdlq-0003kM-00
+ exim -Mmad 14Fdlq-0003kM-00
+ exim -Mar 14Fdlq-0003kM-00 new@ddress
+ exim -M 14Fdlq-0003kM-00
+
+ The first command freezes the message so that a queue runner won't start
+ to deliver it while you are changing things. The second command marks
+ all existing recipients as delivered. The third command adds a new
+ recipient, and the fourth command forces a delivery of the message,
+ which will cause it to be delivered to the new address, and then
+ deleted.
+
+
+Q5025: What precautions should I take when editing Exim's run time
+ configuration file?
+
+A5025: Edit the file and save the result in a new file. Test the syntax of
+ the new file by running a command like this:
+
+==> exim -bV -C exim.conf.new
+
+ That will check for syntax errors without disturbing your running
+ configuration. If you are paranoid enough, run, as \/root/\,
+
+==> exim -C exim.conf.new <some address>
+ <some message>
+ .
+
+ and see if it delivers it. Carry on testing until happy. When happy,
+
+==> mv exim.conf.new exim.conf
+ kill -HUP `cat /var/spool/exim/exim-daemon.pid`
+
+ Then check the Exim log to be sure the daemon restarted OK. Watch the
+ log for a bit to see that mail is flowing.
+
+
+Q5026: Is exim able to use RFC 2645, \*On-demand Mail Relay*\ (ODMR)?
+
+A5026: No.
+
+
+Q5027: Is there any way I can send bounces to the postmaster, and nobody else?
+ Basically, I want to receive them, and I don't want the reply/from
+ person to get them. If I think they need it I will forward it myself.
+
+A5027: Put \"errors_to=postmaster"\ on every router.
+
+
+Q5028: When I HUP the Exim daemon, the name shown in the process table changes
+ from \(/usr/lib/sendmail)\ (which is a symlink) to the real binary name.
+ Can I change this?
+
+A5028: Add this to your Exim configuration:
+
+==> exim_path = /usr/lib/sendmail
+
+
+Q5029: A message with a recipient address that contains a non-printing character
+ is stuck on my mail queue. How can I remove this address?
+
+A5029: You can use the \-Mmd-\ command line option to mark a recipient address
+ ``delivered'', which effectively removes it. If you are using the Bash
+ shell, you can enter non-printing characters using an escape sequence.
+ For example:
+
+==> exim -Mmd 15HKvU-00013Q-00 $'\240'abc@x.y.z
+
+ In this example, the first character of the local part has a code value
+ of 240. If you are using a shell that does not support this, create the
+ command in a file and run it as a shell script.
+
+
+Q5030: I am using exim in a two queues scenario, with two different
+ configuration files. How can I run a second copy of \^eximon^\ to
+ inspect and modify the alternate queue?
+
+A5030: Use these commands (or put them in a script):
+
+==> EXIMON_EXIM_CONFIG=/your/path/exim/configure.alternate
+ export EXIMON_EXIM_CONFIG
+ /your/path/exim/bin/eximon
+
+
+Q5031: Why is there no sender address on bounce messages? It shows up as "<>".
+
+A5031: See the answer to Q0042.
+
+
+Q5032: Are there any Exim web-based administration scripts?
+
+A5032: No (as far as is known). It seems likely that producing one that is
+ generic enough would be a difficult task.
+
+
+Q5033: How can I send a copy of all outgoing messages to another mailbox?
+
+A5033: The most straightforward way is to set up a system filter, and include
+ a command such as:
+
+==> unseen deliver mailbox@whatever.domain
+
+ This sends a copy of every message to //mailbox@whatever.domain//
+ (unless the message already has that recipient - Exim never does
+ duplicate deliveries).
+
+ To save only ``outgoing'' messages, you need to come up with a
+ definition of what ``outgoing'' means. Typically, this might be a check
+ on the sender address and/or on the originating host. Here is an
+ example:
+
+==> if $sender_address_domain is mydomain.com and
+ ${mask:$sender_host_address/24} is 192.168.324.0/24
+ then
+ unseen deliver mailbox@whatever.domain
+ endif
+
+
+Q5034: Is there any way to make the \queue_only\ option conditional? I would
+ like the ability to queue messages from external sources while deliver
+ locally generated email as normal.
+
+A5034: There is no direct way of doing this. However, you can achieve the
+ effect. In one of your ACLs that checks incoming mail from external
+ sources, put
+
+==> warn control = queue_only
+
+ You can add other conditions as well, of course.
+
+
+
+91. MAC OS X
+
+Q9101: How can I install Exim on Mac OS X?
+
+A9101: (1) There is useful advice on this web page:
+ \?http://www.afp548.com/Articles/Jaguar/exim410.html?\.
+
+ (2) There is a package installer available at this URL:
+ \?ftp://members.aol.com/AFP548dotcom/EximInstaller.sit?\.
+
+ (3) There is another package installer for the combination of MySQL,
+ Exim, Exiscan, CourierIMAP, and SpamAssassin at this URL:
+ \?http://maxo.captainnet.net/installs/mail-install.html?\.
+
+
+
+92. FREEBSD
+
+Q9201: On FreeBSD, \(/usr/sbin/sendmail)\ is a symbolic link to
+ \(/usr/sbin/mailwrapper)\; it doesn't contain the Sendmail binary. How
+ should I replace Sendmail with Exim on FreeBSD?
+
+A9201: There is a file called \(/etc/mail/mailer.conf)\ which selects what to
+ run for various MTA calls. Instead of changing \(/usr/sbin/sendmail)\,
+ you should edit this file instead, to read something like this:
+
+==> sendmail /usr/exim/bin/exim
+ send-mail /usr/exim/bin/exim
+ mailq /usr/exim/bin/exim -bp
+ newaliases /usr/bin/true
+
+ You probably also need to edit \(/etc/periodic.conf)\; see Q9202.
+
+
+Q9202: A script that FreeBSD runs nightly uses \^mailq^\ with the \-Ac-\
+ parameter. Why doesn't Exim recognize this?
+
+A9202: \-Ac-\ is a Sendmail option that requests that mailq ``Show the mail
+ submission queue specified in \(/etc/mail/submit.cf)\ instead of the
+ MTA queue specified in \(/etc/mail/sendmail.cf)\''. Exim doesn't have
+ the concept of a ``submission queue''. You can disable this feature
+ of the nightly script by adding the line
+
+==> daily_status_include_submit_mailq="NO" # No separate 'submit' queue
+
+ to the file \(/etc/periodic.conf)\.
+
+
+Q9203: How can I use Exim for authenticated SMTP using Cyrus on FreeBSD?
+
+A9203: This web page may help: \?http://www.munk.nu/exim/exim-freebsd-asmtp.php?\.
+
+
+
+93. HP-UX
+
+Q9301: I'm trying to compile on an HP machine and I don't have \^gcc^\ there. So I
+ put \"CC=cc"\ in the \(Local/Makefile)\, but I got this error:
+
+==> (Bundled) cc: "buildconfig.c", line 54: error 1705: Function prototypes
+ are an ANSI feature.
+
+A9301: The bundled compiler is not an ANSI C compiler. You either have to get a
+ copy of \^gcc^\ from the HPUX Software Porting Archives or buy the ANSI cc
+ from HP. The advice given by one user of HP systems on the Exim
+ mailing list was as follows:
+
+ \*Personally, I wouldn't use anything but the ANSI C compiler. gcc
+ works for compilation, but it doesn't know squat about PA-RISC chips
+ past the 1.0 rev. Since then, HP has come out with PA-RISC 1.1, 2.0,
+ and 2.1, each with better features. gcc will compile for them, but it
+ doesn't produce anywhere near the optimization that HP's compiler
+ does.*\
+
+ \*I took the gcc road when we moved from FreeBSD to HP-UX because I was
+ familiar with it. After 6 months, I had to go and re-port everything
+ over when we realized that gcc wasn't going to do it for us long-term.
+ If I could give advice to any new HP-UX admin: don't use gcc if you
+ can afford the ANSI C compiler. Based on the cost of even the lowest
+ HP workstation, that usually isn't a problem.*\
+
+
+
+94. BSDI
+
+Q9401: On BSDI 4.0, Exim built with Perl support exits with the error message
+
+==> ./exim: can't load library 'libperl.so'
+
+A9401: You probably compiled perl5 yourself, without looking into
+
+==> /usr/src/contrib/perl5/perl5.004_02/hints/bsdos.sh
+
+ first. The problem is that the command
+
+==> perl5 -MExtUtils::Embed -e ldopts
+
+ doesn't give you sufficient flags to link something with libperl.
+ Since 5.004_02 the \(hints/bsdos.sh)\ file has changed to adapt to the
+ changes between BSDI 3.1 and 4.0, but it is still not entirely right.
+
+ The solution is, when you compile perl, change the \ccdlflags\
+ variable in config.sh to:
+
+==> -rdynamic -Wl,-rpath,/usr/local/lib/perl5/5.00502/i386-bsdos/CORE
+
+ (or something similar). Alternatively, you can run \(./Configure)\ and
+ answering the question \*Any special flags to pass to cc to use dynamic
+ loading?*\ with the above line. It is not known what \-rdynamic-\ means
+ (it's not apparently documented in any man page), but that's what BSDI
+ guys did to compile perl5 which comes with BSDI 4.0 distribution.
+
+
+
+95. IRIX
+
+Q9501: The IP addresses for incoming calls are all being given as
+ 255.255.255.255 or 0.0.0.0.
+
+A9501: This problem should no longer occur because a workaround has been
+ installed in Exim.
+
+
+
+96. LINUX
+
+Q9601: Exim is mysteriously crashing, usually when forking to send a delivery
+ error message.
+
+A9601: This has been seen in cases where Exim has been incorrectly built with
+ a muddled combination of an \(ndbm.h)\ include file and a non-matching
+ DBM library.
+
+ Faults like this have also been seen on systems with faulty motherboards.
+ You could try to compile the Linux kernel 10 times - if the compile
+ process stops with signal 11, your hardware is to blame.
+
+
+Q9602: I want to use \^logrotate^\ which is standard with RH5.2 Linux to rotate
+ my mail logs. Anyone worked out the \^logrotate^\ config file that will
+ do this?
+
+A9602: Here's one suggestion:
+
+==> /var/log/exim/main.log {
+ create 644 exim exim
+ rotate 4
+ compress
+ delaycompress
+ }
+
+ The sleep is added to allow things to close the log file prior to
+ compression. You also need similar entries for the panic log and the
+ reject log, of course.
+
+
+Q9603: I'm seeing the message \*inetd[334]: imap/tcp server failing (looping),
+ service terminated*\ on a RedHat 5.2 system, causing \^imap^\ connections to
+ be refused. The \^imapd^\ in use is Washington Univers 12.250. Could this
+ be anything to do with Exim?
+
+A9603: No, it's nothing to do with Exim, but here's the answer anyway: there
+ is a maximum connection rate for \^inetd^\. If connections come in faster
+ than that, it thinks a caller is looping. The default setting on RedHat
+ 5.2 is 40 calls in any one minute before \^inetd^\ thinks there's a problem
+ and suspends further calls for 10 mins. This default setting is very
+ conservative. You should probably increase it by a factor of 10 or 20.
+ For example:
+
+==> imap stream tcp nowait.400 root /usr/sbin/tcpd /usr/local/etc/imapd
+
+ The rate setting is the number following ``nowait''. This syntax seems to
+ be specific to the Linux version of \^inetd^\. Other operating systems
+ provide similar functionality, but in different ways.
+
+
+Q9604: I get the \*too many open files*\ error especially when a lot of messages
+ land for Majordomo at the same time.
+
+A9604: The problem appears to be the number of open files the system can
+ handle. This is changable by using the proc filesystem. To your
+ \(/etc/rc.d/rc.local)\ file append something like the following:
+
+==> # Now System is up, Modify kernel parameters for max open etc.
+
+==> if [ -f /proc/sys/kernel/file-max ]; then
+ echo 16384 >> /proc/sys/kernel/file-max
+ fi
+ if [ -f /proc/sys/kernel/inode-max ]; then
+ echo 24576 >> /proc/sys/kernel/inode-max
+ fi
+ if [ -f /proc/sys/kernel/file-nr ]; then
+ echo 2160 >> /proc/sys/kernel/file-nr
+ fi
+
+ By echoing the value you want for file-max to the file \(file-max)\ etc.,
+ you actually change the kernel parameters.
+
+
+Q9605: I installed debian 2.2 linux on a small 325mb 486 laptop. When I try
+ to test the Mail program, I get the following error: \*Failed to open
+ configuration file /etc/exim.conf*\.
+
+A9605: The Debian installation should have given you \(/usr/sbin/eximconfig)\,
+ which asks you some questions and then sets up the configuration file
+ in \(/etc/exim.conf)\. Try running that (you'll probably need \/root/\) and see
+ how it goes. In any case you get a thoroughly commented conf file at
+ the end, which will give you a sample from which to work if you need
+ further modification.
+
+ The Exim docs in the Debian package are in \(/usr/doc/exim)\ where the full
+ reference manual is \(spec.txt.gz)\.
+
+
+Q9606: I'm having trouble configuring Exim 4 on a Debian system. How does
+ \(/etc/exim4/conf.d)\ work?
+
+A9606: The Debian Exim 4 package uses a quite uncommon, but elegant,
+ method of configuration where the ``real'' Exim configuration file is
+ assembled from a tree of snippets by a script invoked just before the
+ daemon is started (see Q9608).
+
+ This fits very well into the Debian system of configuration file
+ management and is a great ease for the automatic configuration with
+ Debconf. However, it is \*very*\ different from the normal way Exim 4 is
+ configured. Non-Debian users on the Exim mailing list will probably have
+ difficulty in trying to answer specific questions about it. You may have
+ to find a Debian expert.
+
+
+Q9607: I'm having difficulties trying to make Exim 4 with Redhat 9 and Berkeley
+ DB 4.
+
+A9607: Have you remembered to install the db4-devel package?
+
+
+Q9608: I'm running Exim 3 under Debian, and want to upgrade to Exim 4. How
+ difficult is it?
+
+A9608: A user who did this, using the Debian Exim 4 package, reported as
+ follows:
+
+ (1) The exim4 package installs easily, and the exim (3.38) package
+ uninstalls at the same time.
+
+ (2) Exim runs from \^inetd^\. Exim4 runs from \^/etc/init.d^\. \*Much*\ nicer!
+
+ (3) The exim conffile lives in \(/etc/exim/exim.conf)\. The exim4 conffile
+ lives in \(/var/lib/exim4/config.autogenerated)\. It is, as the name
+ suggests, autogenerated.
+
+ (4) A new directory is created called \(/etc/exim4)\. This contains the
+ conffiles to generate the above config. You make changes here.
+
+ (5) Once you have made changes to the files in \(/etc/exim4)\ you run the
+ script \^update-exim4.conf^\ which generates a replacement
+ \(config.autogenerated)\.
+
+ [Added comment by the Debian maintainer, slightly edited:
+ You also need to tell the Exim daemon to reread the changed
+ configuration. You can do this using SIGHUP by hand. Alternatively,
+ instead of running \^update-exim4.conf^\ you can use
+
+==> invoke-rc.d exim4 reload
+
+ which does the rebuild and also tells Exim to reread the changed
+ configuration.]
+
+ (6) In my experience, you need to \*carefully*\ check the generated
+ configs. eg, it did not generate a system filter file reference in the
+ \(config.autogenerated)\. I didn't bother too much, since this is a home
+ setup.
+
+ (7) All of this may be in the docs. I've read some of them, obviously,
+ but didn't come across an actual upgrade guide.
+
+ [The Debian maintainer says:
+ \(/usr/share/doc/exim4-base/README.Debian.gz)\ and \^update-exim4.conf(8)^\
+ should answer most of the questions.]
+
+ (8) I've still got some minor things to tweak to get back to where I
+ was before with Exim 3. But overall, it's no drama.
+
+
+Q9609: Why do some servers refuse SMTP connections from my Linux box, but accept
+ connections from hosts running other operating systems?
+
+A9609: If you are sure this isn't a policy issue (that is, your box isn't
+ administratively blocked for some reason), this may be because your
+ Linux box has ECN (Explicit Congestion Notification) enabled in its
+ TCP/IP stack. There are many broken firewalls that refuse connections
+ from ECN-enabled hosts. You can check the state of your box by running
+
+==> cat /proc/sys/net/ipv4/tcp_ecn
+
+ If the value is "1", you have ECN enabled. You can turn it off by
+ running this command:
+
+==> echo "0" > /proc/sys/net/ipv4/tcp_ecn
+
+
+
+97. SUN SYSTEMS
+
+Q9701: Exim builds fine with \^gcc^\ on SunOS 4 but crashes inside \^^sscanf()^^\.
+
+A9701: Make sure you are liking with the GNU \^ld^\ linker and not the system
+ version of \^ld^\.
+
+
+Q9702: How can I get rid of spurious \"^M"\ characters in messages sent from
+ CDE \^dtmail^\?
+
+A9702: CDE \^dtmail^\ passes messages to Exim via the command line interface with
+ lines terminated by CRLF, instead of the Unix convention of just LF. As
+ Exim is an 8-bit clean program it treats the CR as just another data
+ character. Exim has a command line option called \-dropcr-\ which causes
+ it to ignore all CR characters in an incoming non-SMTP message. You
+ should configure \^dtmail^\ to add this option to the command it uses to
+ call Exim (using the path \(/usr/lib/sendmail)\). However, it has been
+ reported that it isn't possible to change this call from \^dtmail^\ by any
+ official means. An alternative approach is to replace \(/usr/lib/sendmail)\
+ by a filtering script which removes the spurious CRs from the input
+ before passing it to Exim.
+
+
+Q9703: On SunOS 4 Exim crashes when looking up domains in the DNS that have
+ more than 10 A records.
+
+A9703: There are Sun library patches to fix this. It is not Exim's problem.
+ For 4.13_U1 the patch is 101558-xx; for 4.1.3 the patch is 100891-xx.
+ From the README: \*1054748 ftp, ping dump core when connecting to a host
+ with multiple DNS A records.*\ An alternative is to build another
+ resolver library - such as the ones that are part of the \^bind^\
+ distribution - and explicitly link against those.
+
+
+Q9704: I am experiencing mailbox locking problems with Sun's \^mailtool^\ used
+ over a network.
+
+A9704: Under the \"Expert"\ settings of \^mailtool^\ is a option to turn on \*Use
+ network aware mail file locking*\. By default \^dtmail^\ has this set, but
+ \^mailtool^\ doesn't. You should set it. The help info on \^dtmail^\ has this
+ to say about it:
+
+ \*Mailer tries to prevent two different instances of itself from opening
+ the same mail file at the same time through a technique that detects
+ this access when both instances of Mailer and the file are all on the
+ same machine. A network-aware mail file locking protocol is available
+ that uses ToolTalk to coordinate instances of Mailer running from more
+ than one machine, or mail files accessed over the network. Mailer can
+ only change this option when first opening a mail file.*\
+
+ If you are using the SunOS4 version of \^mailtool^\, this apparently
+ doesn't work. The only thing which does seem to work it getting the user
+ to hit the \"done"\ button to make it release the lock.
+
+
+Q9705: Exim has been crashing on my Solaris x86 system, apparently while
+ running DBM functions.
+
+A9705: The use of \^ndbm^\ with \^gcc^\ has caused problems on x86 Solaris systems.
+ Try changing one or the other; using either DB with gcc, or Sun's
+ WS compiler with \^ndbm^\, has fixed this in the past.
+
+
+Q9706: The \^exiwhat^\ utility isn't working for me on a Solaris 2 system.
+
+A9706: Have you got \(/usr/ucb)\ on your path? If so, it is probably picking up the
+ wrong version of the \^ps^\ command. The \^exiwhat^\ script is built on
+ Solaris to expect the normal Solaris version of \^ps^\.
+
+
+Q9707: How do I stop Sun's \^dtcm^\ from hanging?
+
+A9707: From qmail's FAQ: \*There is a novice programming error in dtcm, known as
+ ``failure to close the output side of the pipe in the child.'' Sun has,
+ at the time of this writing, not yet provided a patch.*\
+
+
+Q9708: I want Exim to use only the resolver (i.e. ignore \(/etc/hosts)\), but don't
+ want to alter the \(nsswitch.conf)\ file in Solaris 2.
+
+A9708: You need to rebuild Exim after fiddling with \(OS/os.h-SunOS5)\:
+
+==> #define gethostbyaddr res_gethostbyaddr
+ #define gethostbyname res_gethostbyname
+ #define endhostent res_endhostent
+ #define endnetent res_endnetent
+ #define gethostent res_gethostent
+ #define getnetbyaddr res_getnetbyaddr
+ #define getnetbyname res_getnetbyname
+ #define getnetent res_getnetent
+ #define sethostent res_sethostent
+ #define setnetent res_setnetent
+
+ Note that \-lnsl-\ is still needed in the Makefile as it
+ contains code used by the NIS lookup and also the \^^inet_addr()^^\ function
+ that Exim uses.
+
+
+Q9709: When I try to compile Exim 4.x on Solaris 2.5.1 I get an error along the
+ lines of \*no such field in struct as 'value.ui32'*\.
+
+A9709: Look in the Exim file \(OS/os.h-SunOS5.h)\ for the line
+
+==> #define LOAD_AVG_FIELD value.ui32
+
+ and change \"ui32"\ to \"ul"\ (that's u followed by the letter ell, not
+ the digit one). Solaris 2.5.1 is getting \*very*\ old now...
+
+
+
+98. CONFIGURATION COOKBOOK
+
+Q9801: How do I configure Exim as part of TPC (\?http://www.tpc.int?\)?
+
+A9801: Suppose you want to accept faxes destined for 1(801)539-*. These are
+ addressed to the domain //9.3.5.1.0.8.1.tpc.int//. Set up a transport to
+ handle the delivery:
+
+==> tpc:
+ driver = pipe
+ command = /usr/local/tpc/tpcmailer.pl $local_part@$domain \
+ $sender_address
+ pipe_as_creator
+
+ \(/usr/local/tpc/tpcmailer.pl)\ is the mail processing script that can
+ be obtained from the TPC distribution. Create a router to route mail
+ for the TPC domain to that transport. This must be placed before your
+ other routers:
+
+==> tpc_router:
+ driver = accept
+ transport = tpc
+ domains = *.9.3.5.1.0.8.1.tpc.int
+
+ Of course, there are other things to do as well before your system is
+ a functioning TPC server.
+
+
+Q9802: How do I configure Exim so that it sends mail to the outside world only
+ from a restricted list of our local users?
+
+A9802: You will need to have a convenient way of checking the list. If it is
+ only a handful of users, you could just list them inline. Otherwise, you
+ need to put them in a file or database. Let's suppose you've just got a
+ list in a file. Put this as your first router:
+
+==> check_outgoing:
+ driver = redirect
+ domains = ! +local_domains
+ senders = ! : ! lsearch;/etc/permitted/senders
+ allow_fail
+ data = :fail: you are not allowed to send outside
+
+ The senders should be listed as complete addresses, with both a local
+ part and a domain. For a large list, use a DBM or cdb file instead, or
+ a database. The first item in the \senders\ list is empty, to match the
+ empty sender. This is necessary because bounce messages have null
+ senders.
+
+
+Q9803: A site for which I provide secondary MX is down for some time. Is there
+ a way to run the queue for that destination separately from the main
+ queue?
+
+A9803: No, because Exim does not have the concept of ``the queue for that
+ destination''. It simply has a single pool of messages awaiting delivery
+ (and some of them may have several destinations). The best approach to
+ this is to arrange for all messages for the site to be saved somewhere
+ other than the main spool, either on a separate dedicated MTA, or in
+ BSMTP files.
+
+
+Q9804: We want to be able to temporarily lock out a user by disabling the
+ password and moving the home directory to another place. How can we
+ arrange to reject mail for users in this state?
+
+A9804: Change the home directory pointer in the passwd file to something
+ distinctive. For example, we use \(/home/CANCELLED)\ for cancelled users.
+ Then you can pick up such users with this router, which is placed
+ immediately after \%system_aliases%\:
+
+==> cancelled_users:
+ driver = redirect
+ check_local_user
+ condition = ${if eq {$home}{/home/CANCELLED}{yes}{no}}
+ allow_fail
+ data = :fail: this account is cancelled
+
+
+Q9805: How can I configure Exim so that all mails addressed to
+ //something@username.domain.net// get delivered to
+ \(/var/spool/mail/username)\?
+
+A9805: Assuming that you have set up //username// as a normal user, with
+ conventional routing for //username@domain.net// to that mailbox, all
+ you need to do is set up a redirection, using a router like this:
+
+==> user_in_domain:
+ driver = redirect
+ data = ${if match{$domain}{\N^(.*)\.domain\.net$\N}\
+ {$1}fail}@domain.net
+
+ If you set \envelope_to\ in the \%appendfile%\ transport, the original
+ envelope address is preserved in the message in an ::Envelope-to::
+ header line.
+
+
+Q9806: How do I get exim not to add a ::Sender:: header to locally originated
+ mail?
+
+A9806: It adds it only if the ::From:: header doesn't correspond to the user
+ sending the message. You can suppress this by setting
+ \no_local_from_check\. If your real question is \*How do I submit mail
+ from UUCP without it adding ::Sender::?*\, see Q1503.
+
+
+Q9807: Is there any way to have messages sent to a specific local address
+ delayed by - say - 24 hours?
+
+A9807: Set up a router like this:
+
+==> delay:
+ driver = redirect
+ domains = the.domain
+ local_parts = thelocalpart
+ condition = ${if < {$message_age}{86400}{yes}{no}}
+ allow_defer
+ data = :defer: message not old enough
+ no_verify
+
+ Of course, this will also have the effect of setting a retry time for
+ the address. You may want to set a special retry rule for it. Note the
+ use of \no_verify\ to ensure that this router is not used when Exim is
+ verifying addresses.
+
+
+Q9808: I have a mailing list exploder on one host, and three other hosts where
+ I want to do the actual deliveries from. How can I get Exim to split
+ a message into groups of recipients between the three hosts?
+
+A9808: Set up a router that routes all remote addresses to a specific
+ transport, with a list of your three hosts. For example:
+
+==> send_to_three:
+ driver = manualroute
+ transport = to_three_smtp
+ route_list = !+local_domains hostA:hostB:hostC
+
+ The transport looks like this:
+
+==> to_three_smtp:
+ driver = smtp
+ hosts_randomize
+
+ By setting \hosts_randomize\, you request that the host list be sorted
+ randomly each time the transport is called, in order to spread the load.
+ The number of times the transport is called for each message depends on
+ the setting of the global option \remote_max_parallel\. If it is set to
+ 1, the transport is called only once for each message, so only one host
+ is used, but different messages use different hosts because of the
+ randomizing.
+
+ The \max_rcpt\ option (default 100) controls the number of addresses
+ sent in each copy of the message - several copies are sent over the
+ same connection if necessary.
+
+ If you want individual messages to be split between the three hosts, you
+ must set the global option \remote_max_parallel\ to 3. This allows Exim
+ to run 3 separate instances of the transport at once. It will pass
+ one-third of all the addresses to each instance. Because the host list
+ is randomized, not round-robinned, there is no guarantee that a single
+ message will use all three hosts, but on average it should.
+
+
+Q9809: Can I configure Exim so that my gateway host sends a copy of each
+ incoming message to each of two internal hosts?
+
+A9809: The easiest way to do this is to make use of the \unseen\ router option,
+ and set up two separate routers. You need to be able to identify
+ incoming messages somehow. Typically this can be done by testing the
+ domain of the recipient address, in which case the configuration should
+ contain something like this:
+
+==> r1:
+ driver = manualroute
+ domains = ! *.your.domain.example
+ route_data = * host1.your.domain.example
+ transport = remote_smtp
+ unseen
+
+==> r2:
+ driver = manualroute
+ domains = ! *.your.domain.example
+ route_data = * host2.your.domain.example
+ transport = remote_smtp
+
+ The \unseen\ setting on \%r1%\ means that after it has accepted an
+ address, the address is also passed on to \%r2%\, and so two deliveries
+ occur.
+
+
+Q9810: How can I implement ``SMTP-after-POP'' with Exim?
+
+A9810: See Q0706.
+
+
+Q9811: I would like to ``tap off'' a proportion of real mail traffic from my
+ live mail server to use in tests of a new server. I want to preserve the
+ envelope contents, but to suppress any error notifications to the
+ original sender.
+
+A9811: See C046.
+
+
+Q9812: How can I lookup data from a single file using both single IP addresses
+ and IP address blocks as keys? I want to set \smtp_accept_max_per_host\
+ by this means, and also include a default.
+
+A9812: You cannot do this in a single lookup, because you need separate lookups
+ for individual addresses and address blocks. However, these lookups can
+ be nested in a single expansion string. For example, suppose you are
+ using an lsearch file with entries like this:
+
+==> 192.168.34.35: 4
+ 192.168.34.0/24: 2
+ *: 1
+
+ You can use this setting:
+
+==> smtp_accept_max_per_host = \
+ ${lookup{$sender_host_address}lsearch{/path/to/file}\
+ {$value}\
+ {\
+ ${lookup{${mask:$sender_host_address/24}}lsearch*{/path/to/file}}\
+ }}
+
+ Note that the first lookup does \*not*\ have an asterisk on the search
+ type. If you have blocks of different sizes (/24, /26, etc) you have to
+ configure it to do a separate lookup for each size, with just the final
+ one using a default.
+
+
+
+99. LIST OF SAMPLE CONFIGURATIONS
+
+As well as being hyperlinked from the HTML version of this document, each
+sample configuration is also available as a file in the \(config.samples)\
+directory, which can be independently downloaded.
+
+Samples whose names are of the form Cnnn are Exim configurations; those with
+names of the form Fnnn are filter file fragments; those with names of the form
+Lnnn are sample \^^local_scan()^^\ functions, and those with names of thf form
+Snnn are scripts of various kinds. There are other examples of
+\^^local_scan()^^\ functions at a number of web sites (for example,
+\?http://marc.merlins.org/linux/exim/sa.html?\).
+
+There are gaps in the C and F numbers because I have omitted the Exim 3 samples
+that have not been converted for Exim 4.
+
+C002: ``Although exim not intended for use in UUCP environment (it doesn't
+ know anything about bang!path addresses), I'm successfully using it for
+ delivering mail to UUCP clients.''
+
+C006: ``This is how I have configured a PP-inspired vacationnote, there is
+ (was?) such a feature in PP. The user makes a file \(tripnote)\ in his/her
+ home directory, the message is passed to the sender once with a short
+ leading text.''
+
+C022: ``This is the Exim configuration file of a machine which delivers mail to
+ several local domains where the mail is delivered locally, several hairy
+ domains, handled as described below, and a half-virtual domain, which is
+ first processed by its special alias file, then processed as other local
+ domains (including the processing by the global alias file).''
+
+C037: An elegant way of using ETRN, which does immediate delivery if the host
+ is online, but saves mail in a BSMTP file after some time on the queue.
+ ETRN then re-injects the mail.
+
+C042: ``Since the Exim 4 configuration needed to get Mailman to work differs a
+ little bit from Exim 3 and since I still haven't seen a recipe for
+ Mailman with Exim 4, I'm providing my configuration (based heavily on
+ \?http://www.exim.org/howto/mailman.html?\).''
+
+C043: ``Attached is an Exim 4 config file which is designed for an Exim server
+ that is put in front of an Exchange 5.5 system but which verifies the
+ valid addresses that are stored in Exchange via LDAP lookups against the
+ Exchange server.''
+
+C044: ``I thought I'd submit this as an example of an authenticated mail hub
+ configuration. Several people have asked for it so I thought it
+ might be of interest.''
+
+C045: ``Here it is, for Exim 4.10 and Cyrus IMAPD 2.1.5 using db3/db4-format
+ mailbox database. This configuration delivers the messages to Cyrus
+ IMAPD using LMTP over a TCP/IP socket.''
+
+C046: ``Deliver a duplicate of some proportion of all messages to a special
+ machine specified in the file \(/MAIL_TAP_HOST)\, if it exists.''
+
+C047: A sample configuration for calling Spamassassin directly from Exim.
+
+C049: ``I've been seeing a whole bunch of IPs that send me spam or virus mail
+ and HELOing as one of my own IPs, or as HELO one.of.my.own.domains (or
+ maybe HELO \primary_hostname\).''
+
+C050: A configuration that uses the DNS to implement virtual domains.
+
+C051: ``I've been working quite hard to come up with a config that reasonably
+ matches the qmail-ldap setup, without the warts.''
+
+F001: ``I thought that the rest of the list may be interested in reviewing our
+ filter as a starting point for their own system message filter.''
+
+F002: ``... program which refused mail from unknown addresses until they mailed
+ me promising not to spam me ... since I'd already thought through how
+ to do it in Exim, and knew it'd be slightly easier than falling out of
+ bed, I went ahead and did it.''
+
+F003: ``Here's four checks installed in our system wide filter that knock out
+ a lot of otherwise hard to detect rubbish.''
+
+F004: ``This is an Exim filter snippet to change locally-generated ::Message-Id::
+ and ::Resent-Message-Id:: headers to world-unique values.''
+
+L001: A \^^local_scan()^^\ function for Exim that calls \^uvscan^\.
+
+S001: A Perl script for patching the name of the configuration file in an
+ Exim binary.
+
+S002: ``When I moved from smail to exim I built a program that took individual
+ config pieces, stripped all the comments, and built a config file.''
+
+*** End of Exim FAQ ***
diff --git a/doc/doc-src/filter.src b/doc/doc-src/filter.src
new file mode 100644
index 000000000..73dfca9dc
--- /dev/null
+++ b/doc/doc-src/filter.src
@@ -0,0 +1,1644 @@
+. $Cambridge: exim/doc/doc-src/filter.src,v 1.1 2004/10/07 15:04:35 ph10 Exp $
+.
+.if !set style
+.library "a4ps"
+.linelength ~~sys.linelength + 0.2in
+.emphasis ~~sys.linelength + 0.1in
+.pagedepth ~~sys.pagedepth - 0.2in
+.bindfont 53 "atl/Times-Roman" 7
+.set ssspaceb 1.50
+.fi
+
+.include "markup.sg"
+
+.set sgcal true
+.set html false
+.set texinfo false
+
+
+.if ~~sys.fancy
+.flag $sm{ "$push$g0$f53"
+.
+.else
+.pagedepth ~~sys.pagedepth - 1ld
+.linelength 75em
+.emphasis 77em
+.footdepth 0
+.disable formfeed
+.backspace none
+.set chapspaceb 24
+.set sspacea 24
+.flag $sm{ "$push"
+.fi
+
+.macro tabs 6
+.if ~~sys.fancy
+.tabset ~~1em
+.else
+.set temp (~~1 * 5)/4
+.tabset ~~temp em
+.fi
+.endm
+
+.macro startitems
+.newline
+.push
+.indent 3em
+.endm
+
+.macro enditems
+.newline
+.pop
+.endm
+
+.macro item "item"
+.newpar
+.if ~~sys.leftonpage < 5ld
+.newpage
+.fi
+.tempindent 0
+\~~1\
+.blank
+.endm
+
+.macro index
+.endm
+
+.set contents false
+.set displayindent 2em
+
+
+. ======================================================
+
+
+.if ~~sys.fancy
+.footdepth 2ld
+.foot
+$c[~~sys.pagenumber]$e
+.endfoot
+.fi
+
+
+.set chapter -1
+.chapter Exim's interfaces to mail filtering
+.space -2ld
+Exim is a mail transfer agent for Unix-like systems. This document describes
+the user interfaces to its in-built mail filtering facilities, and is copyright
+(c) University of Cambridge 2004. It corresponds to Exim version 4.40.
+.rule
+
+. ---------------------------------------------------------------------------
+. Some clever jiggery-pokery here. The contents list is known to be less than
+. one page long, so we arrange for it to get onto the rest of the first page.
+. Because we aren't doing any indexing, the z-rawindex file will contain only
+. the TOC entries. The Makefile arranges for it to be empty at the start, then
+. runs SGCAL twice so on the second pass it gets inserted automatically.
+
+.if ~~sgcal
+.space 1ld
+$chead{Contents}
+.space 1ld
+.tabset 2em 2em
+.push
+.linedepth ~~sys.linedepth - 1
+.include "z-rawindex"
+.newline
+.pop
+.newpage
+.set contents true
+.fi
+. ---------------------------------------------------------------------------
+
+
+.set chapter 0
+.chapter Forwarding and filtering in Exim
+
+
+.section Introduction
+Most Unix mail transfer agents (programs that deliver mail) permit individual
+users to specify automatic forwarding of their mail, usually by placing a list
+of forwarding addresses in a file called \(.forward)\ in their home directories.
+Exim extends this facility by allowing the forwarding instructions to be a set
+of rules rather than just a list of addresses, in effect providing `\(.forward)\
+with conditions'. Operating the set of rules is called $it{filtering}, and the
+file that contains them is called a $it{filter file}.
+
+Exim supports two different kinds of filter file. An \*Exim filter*\ contains
+instructions in a format that is unique to Exim. A \*Sieve filter*\ contains
+instructions in the Sieve format that is defined by RFC 3028. As this is a
+standard format, Sieve filter files may already be familiar to some users.
+Sieve files should also be portable between different environments. However,
+the Exim filtering facility contains more features (such as variable
+expansion), and better integration with the host environment (such as the use
+of external processes and pipes).
+
+The choice of which kind of filter to use can be left to the end-user, provided
+that the system administrator has configured Exim appropriately for both kinds
+of filter. However, if interoperability is important, Sieve is the only
+choice.
+
+The ability to use filtering or traditional forwarding has to be enabled by the
+system administrator, and some of the individual facilities can be separately
+enabled or disabled. A local document should be provided to describe exactly
+what has been enabled. In the absence of this, consult your system
+administrator.
+
+It is important to realize that, in Exim, no deliveries are actually made while
+a filter or traditional \(.forward)\ file is being processed. The result of
+such processing is a list of destinations to which a message should be
+delivered -- the deliveries themselves take place later, along with all other
+deliveries for the message. This means that it is not possible to test for
+successful deliveries while filtering. It also means that any duplicate
+addresses that are generated are dropped, since Exim never delivers the same
+message to the same address more than once.
+
+This document describes how to use a filter file and the format of its
+contents. It is intended for use by end-users. Both Sieve filters and Exim
+filters are covered. However, for Sieve filters, only issues that relate to the
+Exim implementation are discussed, since Sieve itself is described elsewhere.
+
+The contents of traditional \(.forward)\ files are not described here. They
+normally contain just a list of addresses, file names, or pipe commands,
+separated by commas or newlines, but other types of item are also available.
+The full details can be found in the chapter on the \%redirect%\ router in the
+Exim specification, which also describes how the system administrator can set
+up and control the use of filtering.
+
+.section Testing a new filter file
+.rset SECTtesting "~~chapter.~~section"
+Filter files, especially the more complicated ones, should always be tested, as
+it is easy to make mistakes. Exim provides a facility for preliminary testing
+of a filter file before installing it. This tests the syntax of the file and
+its basic operation, and can also be used with traditional \(.forward)\ files.
+
+Because a filter can do tests on the content of messages, a test message is
+required. Suppose you have a new filter file called \(myfilter)\ and a test
+message called \(test-message)\. Assuming that Exim is installed with the
+conventional path name \(/usr/sbin/sendmail)\ (some operating systems use
+\(/usr/lib/sendmail)\), the following command can be used:
+.display asis
+/usr/sbin/sendmail -bf myfilter <test-message
+.endd
+The \-bf-\ option tells Exim that the following item on the command line is the
+name of a filter file that is to be tested. There is also a \-bF-\ option,
+which is similar, but which is used for testing system filter files, as opposed
+to user filter files, and which is therefore of use only to the system
+administrator.
+
+The test message is supplied on the standard input. If there are no
+message-dependent tests in the filter, an empty file (\(/dev/null)\) can be
+used. A supplied message must start with header lines or the `From' message
+separator line which is found in many multi-message folder files. Note that
+blank lines at the start terminate the header lines. A warning is given if no
+header lines are read.
+
+The result of running this command, provided no errors are detected in the
+filter file, is a list of the actions that Exim would try to take if presented
+with the message for real.
+For example, for an Exim filter, the output
+.display asis
+Deliver message to: gulliver@lilliput.fict.example
+Save message to: /home/lemuel/mail/archive
+.endd
+means that one copy of the message would be sent to
+\gulliver@@lilliput.fict.example\, and another would be added to the file
+\(/home/lemuel/mail/archive)\, if all went well.
+
+The actions themselves are not attempted while testing a filter file in this
+way; there is no check, for example, that any forwarding addresses are valid.
+For an Exim filter,
+if you want to know why a particular action is being taken, add the \-v-\
+option to the command. This causes Exim to output the results of any
+conditional tests and to indent its output according to the depth of nesting of
+\"if"\ commands. Further additional output from a filter test can be generated
+by the \"testprint"\ command, which is described below.
+
+When Exim is outputting a list of the actions it would take, if any text
+strings are included in the output, non-printing characters therein are
+converted to escape sequences. In particular, if any text string contains a
+newline character, this is shown as `@\n' in the testing output.
+
+When testing a filter in this way, Exim makes up an `envelope' for the message.
+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,
+.display
+.indent 0
+/usr/sbin/sendmail -bf myfilter -f islington@@never.where <test-message
+.endd
+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
+thing as a \"From:"\ header line), the sender is taken from there. If \-f-\ is
+present, the contents of any `From' line are ignored.
+
+The `return path' is the same as the envelope sender, unless the message
+contains a \"Return-path:"\ header, in which case it is taken from there. You
+need not worry about any of this unless you want to test out features of a
+filter file that rely on the sender address or the return path.
+
+It is possible to change the envelope recipient by specifying further options.
+The \-bfd-\ option changes the domain of the recipient address, while the
+\-bfl-\ option changes the `local part', that is, the part before the @@ sign.
+An adviser could make use of these to test someone else's filter file.
+
+The \-bfp-\ and \-bfs-\ options specify the prefix or suffix for the local part.
+These are relevant only when support for multiple personal mailboxes is
+implemented; see the description in section ~~SECTmbox below.
+
+.section Installing a filter file
+A filter file is normally installed under the name \(.forward)\ in your home
+directory -- it is distinguished from a conventional \(.forward)\ file by its
+first line (described below). However, the file name is configurable, and some
+system administrators may choose to use some different name or location for
+filter files.
+
+.section Testing an installed filter file
+Testing a filter file before installation cannot find every potential problem;
+for example, it does not actually run commands to which messages are piped.
+Some `live' tests should therefore also be done once a filter is installed.
+
+If at all possible, test your filter file by sending messages from some other
+account. If you send a message to yourself from the filtered account, and
+delivery fails, the error message will be sent back to the same account, which
+may cause another delivery failure. It won't cause an infinite sequence of such
+messages, because delivery failure messages do not themselves generate further
+messages. However, it does mean that the failure won't be returned to you, and
+also that the postmaster will have to investigate the stuck message.
+
+If you have to test an Exim filter from the same account, a sensible precaution
+is to include the line
+.display asis
+if error_message then finish endif
+.endd
+as the first filter command, at least while testing. This causes filtering to
+be abandoned for a delivery failure message, and since no destinations are
+generated, the message goes on to be delivered to the original address. Unless
+there is a good reason for not doing so, it is recommended that the above test
+be left in all Exim filter files.
+(This does not apply to Sieve files.)
+
+
+.section Details of filtering commands
+The filtering commands for Sieve and Exim filters are completely different in
+syntax and semantics. The Sieve mechanism is defined in RFC 3028; in the next
+chapter we describe how it is integrated into Exim. The subsequent chapter
+covers Exim filtering commands in detail.
+
+
+.
+.
+.
+.
+.
+.chapter Sieve filter files
+.rset CHAPsievefilter "~~chapter"
+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'.
+
+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.
+
+The Exim Sieve implementation offers the core as defined by RFC 3028, the
+\%envelope%\ and the \%fileinto%\ extensions, but not the \%reject%\ extension.
+Exim does not support message delivery notifications (MDNs), so adding it just
+to the Sieve filter (as required for \%reject%\) makes little sense.
+
+In order for Sieve to work properly in Exim, the system administrator needs to
+make some adjustments to the Exim configuration. These are described in the
+chapter on the \%redirect%\ router in the full Exim specification.
+
+.section Recognition of Sieve filters
+A filter file is interpreted as a Sieve filter if its first line is
+.display asis
+# Sieve filter
+.endd
+This is what distinguishes it from a conventional \(.forward)\ file or an Exim
+filter file.
+
+
+.section Saving to specified folders
+If the system administrator has set things up as suggested in the Exim
+specification, and you use \%keep%\ or \%fileinto%\ to save a mail into a
+folder, absolute files are stored where specified, relative files are stored
+relative to \$home$\, and \%inbox%\ goes to the standard mailbox location.
+
+
+.section 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.
+
+
+.section Exists test with empty list of headers
+The \%exists%\ test succeeds only if all 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.
+
+
+.section Header test with invalid MIME encoding in header
+Some MUAs process invalid base64 encoded data, generating junk.
+Others ignore junk after seeing an equal sign in base64 encoded data.
+RFC 2047 does not specify how to react in this case, other than stating
+that a client must not forbid to process a message for that reason.
+RFC 2045 specifies that invalid data should be ignored (apparently
+looking at end of line characters). It also specifies that invalid data
+may lead to rejecting messages containing them (and there it appears to
+talk about true encoding violations), which is a clear contradiction to
+ignoring them.
+
+RFC 3028 does not specify how to process incorrect MIME words.
+This implementation treats them literally, as it does if the word is
+correct but its character set cannot be converted to UTF-8.
+
+
+.section Address test for multiple addresses per header
+A header may contain multiple addresses. RFC 3028 does not explicitly
+specify how to deal with them, but since the address test checks if
+anything matches anything else, matching one address suffices to
+satisfy the condition. That makes it impossible to test if a header
+contains a certain set of addresses and no more, but it is more logical
+than letting the test fail if the header contains an additional address
+besides the one the test checks for.
+
+
+.section Semantics of keep
+The \%keep%\ command is equivalent to
+.display
+fileinto "inbox";
+.endd
+It saves the message and resets the implicit keep flag. It does not set the
+implicit keep flag; there is no command to set it once it has been reset.
+
+
+.section Semantics of fileinto
+RFC 3028 does not specify whether \fileinto\ should try to create a mail folder
+if it does not exist. This implementation allows the sysadmin to configure that
+aspect using the \%appendfile%\ transport options \create@_directory\,
+\create@_file\, and \file@_must@_exist\. See the \%appendfile%\ transport in
+the Exim specification for details.
+
+
+.section Semantics of redirect
+Sieve scripts are supposed to be interoperable between servers, so this
+implementation does not allow mail to be redirected to unqualified addresses,
+because the domain would depend on the system being used. On systems with
+virtual mail domains, the default domain is probably not what the user expects
+it to be.
+
+
+.section 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.
+
+
+.section 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.
+
+
+.section RFC compliance
+Exim requires the first line of a Sieve filter to be
+.display asis
+# Sieve filter
+.endd
+Of course the RFC does not specify that line. Do not expect examples to work
+without adding it, though.
+
+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
+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.
+
+Sieve scripts cannot contain NUL characters in strings, but mail
+headers could contain MIME encoded NUL characters, which could never
+be matched by Sieve scripts using exact comparisons. For that reason,
+this implementation extends the Sieve quoted string syntax with @\0
+to describe a NUL character, violating @\0 being the same as 0 in
+RFC 3028. Even without using @\0, the following tests are all true in
+this implementation. Implementations that use C-style strings will only
+evaluate the first test as true.
+.display asis
+Subject: =?iso-8859-1?q?abc=00def
+
+header :contains "Subject" ["abc"]
+header :contains "Subject" ["def"]
+header :matches "Subject" ["abc?def"]
+.endd
+
+Note that by considering Sieve to be a 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.
+The above example shows why.
+
+RFC 3028 states that if an implementation fails to convert a character
+set to UTF-8, two strings cannot be equal if one contains octets greater
+than 127. Assuming that all unknown character sets are one-byte character
+sets with the lower 128 octets being US-ASCII is not sound, so this
+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
+syntax of folders apart from \%keep%\ being equivalent to
+.display asis
+fileinto "INBOX";
+.endd
+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
+are filed into \"inbox"\ due to an error in the filter.
+
+
+.
+.
+.
+.
+.
+.chapter Exim filter files
+.rset CHAPeximfilter "~~chapter"
+This chapter contains a full description of the contents of Exim filter files.
+
+.section Format of Exim filter files
+Apart from leading white space, the first text in a filter file must be
+.display asis
+# Exim filter
+.endd
+This is what distinguishes it from a conventional \(.forward)\ file or a Sieve
+filter file. If the file does not have this initial line (or the equivalent for
+a Sieve filter), it is treated as a
+conventional \(.forward)\ file, both when delivering mail and when using the
+\-bf-\ testing mechanism. The white space in the line is optional, and any
+capitalization may be used. Further text on the same line is treated as a
+comment. For example, you could have
+.display asis
+# Exim filter <<== do not edit or remove this line!
+.endd
+The remainder of the file is a sequence of filtering commands, which consist of
+keywords and data values. For example, in the command
+.display asis
+deliver gulliver@lilliput.fict.example
+.endd
+the keyword is \"deliver"\ and the data value is
+\"gulliver@@lilliput.fict.example"\.
+White space or line breaks separate the components of a command, except in the
+case of conditions for the \"if"\ command, where round brackets (parentheses)
+also act as separators. Complete commands are separated from each other by
+white space or line breaks; there are no special terminators. Thus, several
+commands may appear on one line, or one command may be spread over a number of
+lines.
+
+If the character @# follows a separator anywhere in a command, everything from
+@# up to the next newline is ignored. This provides a way of including comments
+in a filter file.
+
+.section Data values in filter commands
+There are two ways in which a data value can be input:
+.numberpars $.
+If the text contains no white space then it can be typed verbatim. However, if
+it is part of a condition, it must also be free of round brackets
+(parentheses), as these are used for grouping in conditions.
+.nextp
+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:
+.display rm
+.tabs 8
+@\n $t is replaced by a newline
+@\r $t is replaced by a carriage return
+@\t $t is replaced by a tab
+.endd
+Backslash followed by up to three octal digits is replaced by the character
+specified by those digits, and @\x followed by up to two hexadecimal digits is
+treated similarly. Backslash followed by any other character is replaced
+by the second character, so that in particular, @\" becomes " and @\@\ becomes
+@\$<. A data item enclosed in double quotes can be continued onto the next line
+by ending the first line with a backslash. Any leading white space at the start
+of the continuation line is ignored.
+.endp
+In addition to the escape character processing that occurs when strings are
+enclosed in quotes, most data values are also subject to $it{string expansion}
+(as described in the next section), in which case the characters \@$\ and \@\\
+are also significant. This means that if a single backslash is actually
+required in such a string, and the string is also quoted, @\@\@\@\ has to be
+entered.
+
+The maximum permitted length of a data string, before expansion, is 1024
+characters.
+
+
+.section String expansion
+.rset SECTfilterstringexpansion "~~chapter.~~section"
+Most data values are expanded before use. Expansion consists of replacing
+substrings beginning with \"@$"\ with other text. The full expansion facilities
+available in Exim are extensive. If you want to know everything that Exim can
+do with strings, you should consult the chapter on string expansion in the Exim
+documentation.
+
+In filter files, by far the most common use of string expansion is the
+substitution of the contents of a variable. For example, the substring
+.display asis
+$reply_address
+.endd
+is replaced by the address to which replies to the message should be sent. If
+such a variable name is followed by a letter or digit or underscore, it must be
+enclosed in curly brackets (braces), for example,
+.display asis
+${reply_address}
+.endd
+If a \"@$"\ character is actually required in an expanded string, it must be
+escaped with a backslash, and because backslash is also an escape character in
+quoted input strings, it must be doubled in that case. The following two
+examples illustrate two different ways of testing for a \"@$"\ character in a
+message:
+.display asis
+if $message_body contains \$ then ...
+if $message_body contains "\\$" then ...
+.endd
+You can prevent part of a string from being expanded by enclosing it between
+two occurrences of \"@\N"\. For example,
+.display asis
+if $message_body contains \N$$$$\N then ...
+.endd
+tests for a run of four dollar characters.
+
+.section Some useful general variables
+A complete list of the available variables is given in the Exim documentation.
+This shortened list contains the ones that are most likely to be useful in
+personal filter files:
+
+\$body@_linecount$\: The number of lines in the body of the message.
+
+\$home$\: In conventional configurations, this variable normally contains the
+user's home directory. The system administrator can, however, change this.
+
+\$local@_part$\: The part of the email address that precedes the @@ sign --
+normally the user's login name. If support for multiple personal mailboxes is
+enabled (see section ~~SECTmbox below) and a prefix or suffix for the local
+part was recognized, it is removed from the string in this variable.
+
+\$local@_part@_prefix$\: If support for multiple personal mailboxes is enabled
+(see section ~~SECTmbox below), and a local part prefix was recognized,
+this variable contains the prefix. Otherwise it contains an empty string.
+
+\$local@_part@_suffix$\: If support for multiple personal mailboxes is enabled
+(see section ~~SECTmbox below), and a local part suffix was recognized,
+this variable contains the suffix. Otherwise it contains an empty string.
+
+\$message@_body$\: The initial portion of the body of the message. By default,
+up to 500 characters are read into this variable, but the system administrator
+can configure this to some other value. Newlines in the body are converted into
+single spaces.
+
+\$message@_body@_end$\: The final portion of the body of the message, formatted
+and limited in the same way as \$message@_body$\.
+
+\$message@_body@_size$\: The size of the body of the message, in bytes.
+
+\$message@_headers$\: The header lines of the message, concatenated into a
+single string, with newline characters between them.
+
+\$message@_id$\: The message's local identification string, which is unique for
+each message handled by a single host.
+
+\$message@_size$\: The size of the entire message, in bytes.
+
+\$original@_local@_part$\: When an address that arrived with the message is
+being processed, this contains the same value as the variable \$local@_part$\.
+However, if an address generated by an alias, forward, or filter file is being
+processed, this variable contains the local part of the original address.
+
+\$reply@_address$\: The contents of the \"Reply-to:"\ header, if the message
+has one; otherwise the contents of the \"From:"\ header. It is the address to
+which normal replies to the message should be sent.
+
+\$return@_path$\: The return path -- that is, the sender field that will be
+transmitted as part of the message's envelope if the message is sent to another
+host. This is the address to which delivery errors are sent. In many cases,
+this variable has the same value as \$sender@_address$\, but if, for example,
+an incoming message to a mailing list has been expanded, \$return@_path$\ may
+have been changed to contain the address of the list maintainer.
+
+\$sender@_address$\: The sender address that was received in the envelope of
+the message. This is not necessarily the same as the contents of the \"From:"\
+or \"Sender:"\ header lines. For delivery error messages (`bounce messages')
+there is no sender address, and this variable is empty.
+
+\$tod@_full$\: A full version of the time and date, for example: Wed, 18 Oct
+1995 09:51:40 +0100. The timezone is always given as a numerical offset from
+GMT.
+
+\$tod@_log$\: The time and date in the format used for writing Exim's log files,
+without the timezone, for example: 1995-10-12 15:32:29.
+
+\$tod@_zone$\: The local timezone offset, for example: +0100.
+
+
+.section Header variables
+.rset SECTheadervariables "~~chapter.~~section"
+There is a special set of expansion variables containing the header lines of
+the message being processed. These variables have names beginning with
+\"@$header@_"\ followed by the name of the header line, terminated by a colon.
+For example,
+.display asis
+$header_from:
+$header_subject:
+.endd
+The whole item, including the terminating colon, is replaced by the contents of
+the message header line. If there is more than one header line with the same
+name, their contents are concatenated. For header lines whose data consists of
+a list of addresses (for example, ::From:: and ::To::), a comma and newline is
+inserted between each set of data. For all other header lines, just a newline
+is used.
+
+Leading and trailing white space is removed from header line data, and if there
+are any MIME `words' that are encoded as defined by RFC 2047 (because they
+contain non-ASCII characters), they are decoded and translated, if possible, to
+a local character set. Translation is attempted only on operating systems that
+have the \iconv(@)\ function. This makes the header line look the same as it
+would when displayed by an MUA. The default character set is ISO-8859-1, but
+this can be changed by means of the \"headers"\ command (see below).
+
+If you want to see the actual characters that make up a header line, you can
+specify \"@$rheader@_"\ instead of \"@$header@_"\. This inserts the `raw'
+header line, unmodified.
+
+There is also an intermediate form, requested by \"@$bheader@_"\, which removes
+leading and trailing space and decodes MIME `words', but does not do any
+character translation. If an attempt to decode what looks superficially like a
+MIME `word' fails, the raw string is returned. If decoding produces a binary
+zero character, it is replaced by a question mark.
+
+The capitalization of the name following \"@$header@_"\ is not significant.
+Because any printing character except colon may appear in the name of a
+message's header (this is a requirement of RFC 2822, the document that
+describes the format of a mail message) curly brackets must $it{not} be used in
+this case, as they will be taken as part of the header name. Two shortcuts are
+allowed in naming header variables:
+.numberpars $.
+The initiating \"@$header@_"\, \"@$rheader@_"\, or \"@$bheader@_"\ can be
+abbreviated to \"@$h@_"\, \"@$rh@_"\, or \"@$bh@_"\, respectively.
+.nextp
+The terminating colon can be omitted if the next character is white space. The
+white space character is retained in the expanded string. However, this is not
+recommended, because it makes it easy to forget the colon when it really is
+needed.
+.endp
+If the message does not contain a header of the given name, an empty string is
+substituted. Thus it is important to spell the names of headers correctly. Do
+not use \"@$header@_Reply@_to"\ when you really mean \"@$header@_Reply-to"\.
+
+.section User variables
+There are ten user variables with names \$n0$\ -- \$n9$\ that can be
+incremented by the \"add"\ command (see section ~~SECTadd). These can be used
+for `scoring' messages in various ways. If Exim is configured to run a `system
+filter' on every message, the values left in these variables are copied into
+the variables \$sn0$\ -- \$sn9$\ at the end of the system filter, thus making
+them available to users' filter files. How these values are used is entirely up
+to the individual installation.
+
+.section Current directory
+The contents of your filter file should not make any assumptions about the
+current directory. It is best to use absolute paths for file names; you
+can normally make use of the \$home$\ variable to refer to your home directory.
+The \save\ command automatically inserts \$home$\ at the start of non-absolute
+paths.
+
+
+
+.section Significant deliveries
+When in the course of delivery a message is processed by a filter file, what
+happens next, that is, after the whole filter file has been processed, depends
+on whether the filter has set up any $it{significant deliveries} or not. If
+there is at least one significant delivery, the filter is considered to
+have handled the entire delivery arrangements for the current address, and no
+further processing of the address takes place. If, however, no significant
+deliveries have been set up, Exim continues processing the current address as
+if there were no filter file, and typically sets up a delivery of a copy of the
+message into a local mailbox. In particular, this happens in the special case
+of a filter file containing only comments.
+
+The delivery commands \"deliver"\, \"save"\, and \"pipe"\ are by default
+significant. However, if such a command is preceded by the word \"unseen"\, its
+delivery is not considered to be significant. In contrast, other commands such
+as \"mail"\ and \"vacation"\ do not count as significant deliveries unless
+preceded by the word \"seen"\.
+
+
+.section Filter commands
+The filter commands which are described in subsequent sections are listed
+below, with the section in which they are described in brackets:
+.display rm
+.tabs 15
+\add\ $t increment a user variable (section ~~SECTadd)
+\deliver\ $t deliver to an email address (section ~~SECTdeliver)
+\fail\ $t force delivery failure (sysadmin use) (section ~~SECTfail)
+\finish\ $t end processing (section ~~SECTfinish)
+\freeze\ $t freeze message (sysadmin use) (section ~~SECTfreeze)
+\headers\ $t set the header character set (section ~~SECTheaders)
+\if\ $t test condition(s) (section ~~SECTif)
+\logfile\ $t define log file (section ~~SECTlog)
+\logwrite\ $t write to log file (section ~~SECTlog)
+\mail\ $t send a reply message (section ~~SECTmail)
+\pipe\ $t pipe to a command (section ~~SECTpipe)
+\save\ $t save to a file (section ~~SECTsave)
+\testprint\ $t print while testing (section ~~SECTtestprint)
+\vacation\ $t tailored form of \mail\ (section ~~SECTmail)
+.endd
+In addition, when Exim's filtering facilities are being used as a system
+filter, the \"fail"\, \"freeze"\, and \"headers"\ commands are available.
+However, since they are usable only by the system administrator and not by
+ordinary users, they are described in the main Exim specification rather than
+in this document.
+
+.section The add command
+.rset SECTadd "~~chapter.~~section"
+.display
+ add <<number>> to <<user variable>>
+e.g. add 2 to n3
+.endd
+There are 10 user variables of this type, and their values can be obtained by
+the normal expansion syntax (for example \$n3$\) in other commands. At the
+start of filtering, these variables all contain zero. Both arguments of the
+\"add"\ command are expanded before use, making it possible to add variables to
+each other. Subtraction can be obtained by adding negative numbers.
+
+
+.section The deliver command
+.rset SECTdeliver "~~chapter.~~section"
+.display
+ deliver <<mail address>>
+e.g. deliver "Dr Livingstone <David@@somewhere.africa.example>"
+.endd
+This provides a forwarding operation. The message is sent on to the given
+address, exactly as happens if the address had appeared in a traditional
+\(.forward)\ file. If you want to deliver the message to a number of different
+addresses, you can use more than one \"deliver"\ command (each one may have
+only one address). However, duplicate addresses are discarded.
+
+To deliver a copy of the message to your normal mailbox, your login name can be
+given as the address. Once an address has been processed by the filtering
+mechanism, an identical generated address will not be so processed again, so
+doing this does not cause a loop.
+
+However, if you have a mail alias, you should $it{not} refer to it here. For
+example, if the mail address \"L.Gulliver"\ is aliased to \"lg103"\ then all
+references in Gulliver's \(.forward)\ file should be to \"lg103"\. A reference
+to the alias will not work for messages that are addressed to that alias,
+since, like \(.forward)\ file processing, aliasing is performed only once on an
+address, in order to avoid looping.
+
+Following the new address, an optional second address, preceded by
+\"errors@_to"\ may appear. This changes the address to which delivery errors on
+the forwarded message will be sent. Instead of going to the message's original
+sender, they go to this new address. For ordinary users, the only value that is
+permitted for this address is the user whose filter file is being processed.
+For example, the user \"lg103"\ whose mailbox is in the domain
+\lilliput.example\ could have a filter file that contains
+.display asis
+ deliver jon@elsewhere.example errors_to lg103@lilliput.example
+.endd
+Clearly, using this feature makes sense only in situations where not all
+messages are being forwarded. In particular, bounce messages must not be
+forwarded in this way, as this is likely to create a mail loop if something
+goes wrong.
+
+
+.section The save command
+.rset SECTsave "~~chapter.~~section"
+.display
+ save <<file name>>
+e.g. save @$home/mail/bookfolder
+.endd
+This causes a copy of the message to be appended to the given file (that is,
+the file is used as a mail folder). More than one \"save"\ command may appear;
+each one causes a copy of the message to be written to its argument file,
+provided they are different (duplicate \"save"\ commands are ignored).
+
+If the file name does not start with a / character, the contents of the
+\$home$\ variable are prepended, unless it is empty. In conventional
+configurations, this variable is normally set in a user filter to the user's
+home directory, but the system administrator may set it to some other path. In
+some configurations, \$home$\ may be unset, in which case a non-absolute path
+name may be generated. Such configurations convert this to an absolute path
+when the delivery takes place. In a system filter, \$home$\ is never set.
+
+The user must of course have permission to write to the file, and the writing
+of the file takes place in a process that is running as the user, under the
+user's primary group. Any secondary groups to which the user may belong are not
+normally taken into account, though the system administrator can configure Exim
+to set them up. In addition, the ability to use this command at all is
+controlled by the system administrator -- it may be forbidden on some systems.
+
+An optional mode value may be given after the file name. The value for the mode
+is interpreted as an octal number, even if it does not begin with a zero. For
+example:
+.display
+ save /some/folder 640
+.endd
+This makes it possible for users to override the system-wide mode setting for
+file deliveries, which is normally 600. If an existing file does not have the
+correct mode, it is changed.
+
+An alternative form of delivery may be enabled on your system, in which each
+message is delivered into a new file in a given directory. If this is the case,
+this functionality can be requested by giving the directory name terminated by
+a slash after the \"save"\ command, for example
+.display
+ save separated/messages/
+.endd
+There are several different formats for such deliveries; check with your system
+administrator or local documentation to find out which (if any) are available
+on your system. If this functionality is not enabled, the use of a path name
+ending in a slash causes an error.
+
+
+.section The pipe command
+.rset SECTpipe "~~chapter.~~section"
+.display
+ pipe <<command>>
+e.g. pipe "@$home/bin/countmail @$sender@_address"
+.endd
+This command sets up delivery to a specified command using a pipe. Remember,
+however, that no deliveries are done while the filter is being processed. All
+deliveries happen later on. Therefore, the result of running the pipe is not
+available to the filter.
+
+When the deliveries are done, a separate process is run, and a copy of the
+message is passed on its standard input. The process runs as the user, under
+the user's primary group. Any secondary groups to which the user may belong are
+not normally taken into account, though the system administrator can configure
+Exim to set them up. More than one \"pipe"\ command may appear; each one causes
+a copy of the message to be written to its argument pipe, provided they are
+different (duplicate \"pipe"\ commands are ignored).
+
+When the time comes to transport the message,
+the command supplied to \"pipe"\ is split up by Exim into a command name and a
+number of arguments. These are delimited by white space except for arguments
+enclosed in double quotes, in which case backslash is interpreted as an escape,
+or in single quotes, in which case no escaping is recognized. Note that as the
+whole command is normally supplied in double quotes, a second level of quoting
+is required for internal double quotes. For example:
+.display asis
+ pipe "$home/myscript \"size is $message_size\""
+.endd
+String expansion is performed on the separate components after the line has
+been split up, and the command is then run directly by Exim; it is not run
+under a shell. Therefore, substitution cannot change the number of arguments,
+nor can quotes, backslashes or other shell metacharacters in variables cause
+confusion.
+
+Documentation for some programs that are normally run via this kind of pipe
+often suggest that the command should start with
+.display asis
+IFS=" "
+.endd
+This is a shell command, and should $it{not} be present in Exim filter files,
+since it does not normally run the command under a shell.
+
+However, there is an option that the administrator can set to cause a shell to
+be used. In this case, the entire command is expanded as a single string and
+passed to the shell for interpretation. It is recommended that this be avoided
+if at all possible, since it can lead to problems when inserted variables
+contain shell metacharacters.
+
+The default \\PATH\\ set up for the command is determined by the system
+administrator, usually containing at least \/usr/bin\ so that common commands
+are available without having to specify an absolute file name. However, it is
+possible for the system administrator to restrict the pipe facility so that the
+command name must not contain any / characters, and must be found in one of the
+directories in the configured \\PATH\\. It is also possible for the system
+administrator to lock out the use of the \"pipe"\ command altogether.
+
+When the command is run, a number of environment variables are set up. The
+complete list for pipe deliveries may be found in the Exim reference manual.
+Those that may be useful for pipe deliveries from user filter files are:
+.display
+.tabs 20
+DOMAIN $t $rm{the domain of the address}
+HOME $t $rm{your home directory}
+LOCAL@_PART $t $rm{see below}
+LOCAL@_PART@_PREFIX $t $rm{see below}
+LOCAL@_PART@_SUFFIX $t $rm{see below}
+LOGNAME $t $rm{your login name}
+MESSAGE@_ID $t $rm{the message's unique id}
+PATH $t $rm{the command search path}
+RECIPIENT $t $rm{the complete recipient address}
+SENDER $t $rm{the sender of the message}
+SHELL $t $bf{/bin/sh}
+USER $t $rm{see below}
+.endd
+\\LOCAL@_PART\\, \\LOGNAME\\, and \\USER\\ are all set to the same value,
+namely, your login id. \\LOCAL@_PART@_PREFIX\\ and \\LOCAL@_PART@_SUFFIX\\ may
+be set if Exim is configured to recognize prefixes or suffixes in the local
+parts of addresses. For example, a message addressed to
+\*pat-suf2@@domain.example*\ may cause user \*pat*\'s filter file to be run. If
+this sets up a pipe delivery, \\LOCAL@_PART@_SUFFIX\\ is \"-suf2"\ when the
+pipe command runs. The system administrator has to configure Exim specially for
+this feature to be available.
+
+If you run a command that is a shell script, be very careful in your use of
+data from the incoming message in the commands in your script. RFC 2822 is very
+generous in the characters that are legally permitted to appear in mail
+addresses, and in particular, an address may begin with a vertical bar or a
+slash. For this reason you should always use quotes round any arguments that
+involve data from the message, like this:
+.display asis
+/some/command '$SENDER'
+.endd
+so that inserted shell meta-characters do not cause unwanted effects.
+
+Remember that, as was explained earlier, the pipe command is not run at the
+time the filter file is interpreted. The filter just defines what deliveries
+are required for one particular addressee of a message. The deliveries
+themselves happen later, once Exim has decided everything that needs to be done
+for the message.
+
+A consequence of this is that you cannot inspect the return code from the pipe
+command from within the filter. Nevertheless, the code returned by the command
+is important, because Exim uses it to decide whether the delivery has succeeded
+or failed.
+
+The command should return a zero completion code if all has gone well. Most
+non-zero codes are treated by Exim as indicating a failure of the pipe. This is
+treated as a delivery failure, causing the message to be returned to its
+sender. However, there are some completion codes which are treated as temporary
+errors. The message remains on Exim's spool disk, and the delivery is tried
+again later, though it will ultimately time out if the delivery failures go on
+too long. The completion codes to which this applies can be specified by the
+system administrator; the default values are 73 and 75.
+
+The pipe command should not normally write anything to its standard output or
+standard error file descriptors. If it does, whatever is written is normally
+returned to the sender of the message as a delivery error, though this action
+can be varied by the system administrator.
+
+
+.section Mail commands
+.rset SECTmail "~~chapter.~~section"
+There are two commands which cause the creation of a new mail message, neither
+of which count as a significant delivery unless the command is preceded by the
+word \"seen"\. This is a powerful facility, but it should be used with care,
+because of the danger of creating infinite sequences of messages. The system
+administrator can forbid the use of these commands altogether.
+
+To help prevent runaway message sequences, these commands have no effect when
+the incoming message is a delivery error message, and messages sent by this
+means are treated as if they were reporting delivery errors. Thus they should
+never themselves cause a delivery error message to be returned. The basic
+mail-sending command is
+.display
+ mail [to <<address-list>>]
+ [cc <<address-list>>]
+ [bcc <<address-list>>]
+ [from <<address>>]
+ [reply@_to <<address>>]
+ [subject <<text>>]
+ [extra@_headers <<text>>]
+ [text <<text>>]
+ [[expand] file <<filename>>]
+ [return message]
+ [log <<log file name>>]
+ [once <<note file name>>]
+ [once@_repeat <<time interval>>]
+.blank
+e.g. mail text "Your message about @$h@_subject: has been received"
+.endd
+
+Each <<address-list>> can contain a number of addresses, separated by commas,
+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. Thus, it may contain
+additional information as well as email addresses. For example:
+.display asis
+mail to "Julius Caesar <jc@rome.example>, \
+ <ma@rome.example> (Mark A.)"
+.endd
+Similarly, the texts supplied for ::From:: and ::Reply-to:: are copied into
+their respective header lines.
+
+As a convenience for use in one common case, there is also a command called
+\vacation\. It behaves in the same way as \mail\, except that the defaults for
+the
+\"subject"\,
+\"file"\, \"log"\, \"once"\, and \"once@_repeat"\ options are
+.display
+subject "On vacation"
+expand file .vacation.msg
+log .vacation.log
+once .vacation
+once@_repeat 7d
+.endd
+respectively. These are the same file names and repeat period used by the
+traditional Unix \"vacation"\ command. The defaults can be overridden by
+explicit settings, but if a file name is given its contents are expanded only
+if explicitly requested.
+
+\**Warning**\: The \"vacation"\ command should always be used conditionally,
+subject to at least the \"personal"\ condition (see section ~~SECTpersonal
+below) so as not to send automatic replies to non-personal messages from
+mailing lists or elsewhere. Sending an automatic response to a mailing list or
+a mailing list manager is an Internet Sin.
+
+For both commands, the key/value argument pairs can appear in any order. At
+least one of \"text"\ or \"file"\ must appear (except with \"vacation"\); if
+both are present, the text string appears first in the message. If \"expand"\
+precedes \"file"\, each line of the file is subject to string expansion as
+it is included in the message.
+
+Several lines of text can be supplied to \"text"\ by including the escape
+sequence `@\n' in the string where newlines are required. If the command is
+output during filter file testing, newlines in the text are shown as `@\n'.
+
+Note that the keyword for creating a \"Reply-To:"\ header is \reply@_to\,
+because Exim keywords may contain underscores, but not hyphens. If the \"from"\
+keyword is present and the given address does not match the user who owns the
+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
+header lines. You can use `@\n' within quoted text to specify newlines between
+headers, and also to define continued header lines. For example:
+.display asis
+extra_headers "h1: first\nh2: second\n continued\nh3: third"
+.endd
+No newline should appear at the end of the final header line.
+
+If no \"to"\ argument appears, the message is sent to the address in the
+\"@$reply@_address"\ variable (see section ~~SECTfilterstringexpansion above).
+An \"In-Reply-To:"\ header is automatically included in the created message,
+giving a reference to the message identification of the incoming message.
+
+If \"return message"\ is specified, the incoming message that caused the filter
+file to be run is added to the end of the message, subject to a maximum size
+limitation.
+
+If a log file is specified, a line is added to it for each message sent.
+
+If a \"once"\ file is specified, it is used to hold a database for remembering
+who has received a message, and no more than one message is ever sent to any
+particular address, unless \"once@_repeat"\ is set. This specifies a time
+interval after which another copy of the message is sent. The interval is
+specified as a sequence of numbers, each followed by the initial letter of one
+of `seconds', `minutes', `hours', `days', or `weeks'. For example,
+.display asis
+once_repeat 5d4h
+.endd
+causes a new message to be sent if 5 days and 4 hours have elapsed since the
+last one was sent. There must be no white space in a time interval.
+
+Commonly, the file name specified for \"once"\ is used as the base name for
+direct-access (DBM) file operations. There are a number of different DBM
+libraries in existence. Some operating systems provide one as a default, but
+even in this case a different one may have been used when building Exim. With
+some DBM libraries, specifying \"once"\ results in two files being created,
+with the suffixes \".dir"\ and \".pag"\ being added to the given name. With
+some others a single file with the suffix \".db"\ is used, or the name is used
+unchanged.
+
+Using a DBM file for implementing the \"once"\ feature means that the file
+grows as large as necessary. This is not usually a problem, but some system
+administrators want to put a limit on it. The facility can be configured not to
+use a DBM file, but instead, to use a regular file with a maximum size. The
+data in such a file is searched sequentially, and if the file fills up, the
+oldest entry is deleted to make way for a new one. This means that some
+correspondents may receive a second copy of the message after an unpredictable
+interval. Consult your local information to see if your system is configured
+this way.
+
+More than one \"mail"\ or \"vacation"\ command may be obeyed in a single filter
+run; they are all honoured, even when they are to the same recipient.
+
+
+.section Logging commands
+.rset SECTlog "~~chapter.~~section"
+A log can be kept of actions taken by a filter file. This facility is normally
+available in conventional configurations, but there are some situations where
+it might not be. Also, the system administrator may choose to disable it. Check
+your local information if in doubt.
+
+Logging takes place while the filter file is being interpreted. It does not
+queue up for later like the delivery commands. The reason for this is so that a
+log file need be opened only once for several write operations. There are two
+commands, neither of which constitutes a significant delivery. The first
+defines a file to which logging output is subsequently written:
+.display
+ logfile <<file name>>
+e.g. logfile @$home/filter.log
+.endd
+The file name must be fully qualified. You can use \$home$\, as in this
+example, to refer to your home directory. The file name may optionally be
+followed by a mode for the file, which is used if the file has to be created.
+For example,
+.display
+ logfile @$home/filter.log 0644
+.endd
+The number is interpreted as octal, even if it does not begin with a zero.
+The default for the mode is 600. It is suggested that the \"logfile"\ command
+normally appear as the first command in a filter file. Once \"logfile"\ has
+been obeyed, the \"logwrite"\ command can be used to write to the log file:
+.display
+ logwrite "<<some text string>>"
+e.g. logwrite "@$tod@_log @$message@_id processed"
+.endd
+It is possible to have more than one \"logfile"\ command, to specify writing to
+different log files in different circumstances. Writing takes place at the end
+of the file, and a newline character is added to the end of each string if
+there isn't one already there. Newlines can be put in the middle of the string
+by using the `@\n' escape sequence. Lines from simultaneous deliveries may get
+interleaved in the file, as there is no interlocking, so you should plan your
+logging with this in mind. However, data should not get lost.
+
+
+.section The finish command
+.rset SECTfinish "~~chapter.~~section"
+The command \"finish"\, which has no arguments, causes Exim to stop
+interpreting the filter file. This is not a significant action unless preceded
+by \"seen"\. A filter file containing only \"seen finish"\ is a black hole.
+
+.section The testprint command
+.rset SECTtestprint "~~chapter.~~section"
+It is sometimes helpful to be able to print out the values of variables when
+testing filter files. The command
+.display
+ testprint <<text>>
+e.g. testprint "home=@$home reply@_address=@$reply@_address"
+.endd
+does nothing when mail is being delivered. However, when the filtering code is
+being tested by means of the \-bf-\ option (see section ~~SECTtesting above),
+the value of the string is written to the standard output.
+
+.section The fail command
+.rset SECTfail "~~chapter.~~section"
+When Exim's filtering facilities are being used as a system filter, the
+\"fail"\ command is available, to force delivery failure. Because this command
+is normally usable only by the system administrator, and not enabled for use by
+ordinary users, it is described in more detail in the main Exim specification
+rather than in this document.
+
+.section The freeze command
+.rset SECTfreeze "~~chapter.~~section"
+When Exim's filtering facilities are being used as a system filter, the
+\"freeze"\ command is available, to freeze a message on the queue. Because this
+command is normally usable only by the system administrator, and not enabled
+for use by ordinary users, it is described in more detail in the main Exim
+specification rather than in this document.
+
+
+.section The headers command
+.rset SECTheaders "~~chapter.~~section"
+The \"headers"\ command can be used to change the target character set which is
+used when translating the contents of encoded header lines for insertion by the
+\"@$header@_"\ mechanism (see section ~~SECTheadervariables above). The default
+can be set in the Exim configuration; if not specified, ISO-8859-1 is used. The
+only currently supported format for the \"headers"\ command is as in this
+example:
+.display asis
+headers charset "UTF-8"
+.endd
+That is, \"headers"\ is followed by the word \"charset"\ and then the name of a
+character set. This particular example would be useful if you wanted to compare
+the contents of a header to a UTF-8 string.
+
+
+.section Obeying commands conditionally
+.rset SECTif "~~chapter.~~section"
+Most of the power of filtering comes from the ability to test conditions and
+obey different commands depending on the outcome. The \"if"\ command is used to
+specify conditional execution, and its general form is
+.display
+if <<condition>>
+then <<commands>>
+elif <<condition>>
+then <<commands>>
+else <<commands>>
+endif
+.endd
+There may be any number of \"elif"\ and \"then"\ sections (including none) and
+the \"else"\ section is also optional. Any number of commands, including nested
+\"if"\ commands, may appear in any of the <<commands>> sections.
+
+Conditions can be combined by using the words \"and"\ and \"or"\, and round
+brackets (parentheses) can be used to specify how several conditions are to
+combine. Without brackets, \"and"\ is more binding than \"or"\.
+For example,
+.display asis
+if
+ $h_subject: contains "Make money" or
+ $h_precedence: is "junk" or
+ ($h_sender: matches ^\\d{8}@ and not personal) or
+ $message_body contains "this is spam"
+then
+ seen finish
+endif
+.endd
+A condition can be preceded by \"not"\ to negate it, and there are also some
+negative forms of condition that are more English-like.
+
+
+
+.section String testing conditions
+There are a number of conditions that operate on text strings, using the words
+`begins', `ends', `is', `contains' and `matches'.
+
+Note that if you want to apply the same test to more than one header line, you
+can easily concatenate them into a single string for testing, as in this
+example:
+.display asis
+if "$h_to:, $h_cc:" contains me@domain.example then ...
+.endd
+
+If any of the condition names are written in lower case, the testing of letters
+is done without regard to case; if they are written in upper case (for example,
+`CONTAINS') then the case of letters is significant.
+.display
+ <<text1>> begins <<text2>>
+ <<text1>> does not begin <<text2>>
+e.g. @$header@_from: begins "Friend@@"
+.endd
+A `begins' test checks for the presence of the second string at the start of
+the first, both strings having been expanded.
+.display
+ <<text1>> ends <<text2>>
+ <<text1>> does not end <<text2>>
+e.g. @$header@_from: ends "@public.com.example"
+.endd
+An `ends' test checks for the presence of the second string at the end of
+the first, both strings having been expanded.
+.display
+ <<text1>> is <<text2>>
+ <<text1>> is not <<text2>>
+e.g. @$local@_part@_suffix is "-foo"
+.endd
+An `is' test does an exact match between the strings, having first expanded
+both strings.
+.display
+ <<text1>> contains <<text2>>
+ <<text1>> does not contain <<text2>>
+e.g. @$header@_subject: contains "evolution"
+.endd
+A `contains' test does a partial string match, having expanded both strings.
+.display
+ <<text1>> matches <<text2>>
+ <<text1>> does not match <<text2>>
+e.g. @$sender@_address matches "(bill|john)@@"
+.endd
+For a `matches' test, after expansion of both strings, the second one is
+interpreted as a regular expression. Exim uses the PCRE regular expression
+library, which provides regular expressions that are compatible with Perl.
+
+.em
+The match succeeds if the regular expression matches any part of the first
+string. If you want a regular expression to match only at the start or end of
+the subject string, you must encode that requirement explicitly, using the @^
+or @$ metacharacters. The above example, which is not so constrained, matches
+all these addresses:
+.display asis
+bill@test.example
+john@some.example
+spoonbill@example.com
+littlejohn@example.com
+.endd
+To match only the first two, you could use this:
+.display asis
+if $sender_address matches "^(bill|john)@" then ...
+.endd
+.nem
+
+Care must be taken if you need a backslash in a regular expression, because
+backslashes are interpreted as escape characters both by the string expansion
+code and by Exim's normal processing of strings in quotes. For example, if you
+want to test the sender address for a domain ending in \".com"\ the regular
+expression is
+.display asis
+\.com$
+.endd
+The backslash and dollar sign in that expression have to be escaped when used
+in a filter command, as otherwise they would be interpreted by the expansion
+code. Thus what you actually write is
+.display asis
+if $sender_address matches \\.com\$
+.endd
+An alternative way of handling this is to make use of the \"@\N"\ expansion
+flag for suppressing expansion:
+.display asis
+if $sender_address matches \N\.com$\N
+.endd
+Everything between the two occurrences of \"@\N"\ is copied without change by
+the string expander (and in fact you do not need the final one, because it is
+at the end of the string).
+
+If the regular expression is given in quotes (mandatory only if it contains
+white space) you have to write either
+.display asis
+if $sender_address matches "\\\\.com\\$"
+.endd
+or
+.display asis
+if $sender_address matches "\\N\\.com$\\N"
+.endd
+
+
+If the regular expression contains bracketed sub-expressions, numeric
+variable substitutions such as \$1$\ can be used in the subsequent actions
+after a successful match. If the match fails, the values of the numeric
+variables remain unchanged. Previous values are not restored after \"endif"\ --
+in other words, only one set of values is ever available. If the condition
+contains several sub-conditions connected by \"and"\ or \"or"\, it is the
+strings extracted from the last successful match that are available in
+subsequent actions. Numeric variables from any one sub-condition are also
+available for use in subsequent sub-conditions, since string expansion of a
+condition occurs just before it is tested.
+
+.section Numeric testing conditions
+The following conditions are available for performing numerical tests:
+.display
+ <<number1>> is above <<number2>>
+ <<number1>> is not above <<number2>>
+ <<number1>> is below <<number2>>
+ <<number1>> is not below <<number2>>
+e.g. @$message@_size is not above 10k
+.endd
+The <<number>> arguments must expand to strings of digits, optionally followed
+by one of the letters K or M (upper case or lower case) which cause
+multiplication by 1024 and 1024x1024 respectively.
+
+.section Testing for significant deliveries
+Whether or not any previously obeyed filter commands have resulted in a
+significant delivery can be tested by the condition \"delivered"\, for example:
+.display asis
+if not delivered then save mail/anomalous endif
+.endd
+
+.section Testing for error messages
+The condition \"error@_message"\ is true if the incoming message is a mail
+delivery error message (bounce message). Putting the command
+.display asis
+if error_message then finish endif
+.endd
+at the head of your filter file is a useful insurance against things going
+wrong in such a way that you cannot receive delivery error reports, and is
+highly recommended. Note that \"error@_message"\ is a condition, not an
+expansion variable, and therefore is not preceded by \@$\.
+
+.section Testing for personal mail
+.rset SECTpersonal "~~chapter.~~section"
+A common requirement is to distinguish between incoming personal mail and mail
+from a mailing list,
+or from a robot or other automatic process (for example, a bounce message).
+In particular, this test is normally required for so-called `vacation
+messages'. The condition
+.display
+ personal
+.endd
+is a shorthand for
+.display
+ not error@_message and
+ @$header@_to: contains "@$local@_part@@@$domain" and
+ @$header@_from: does not contain "@$local@_part@@@$domain" and
+ @$header@_from: does not contain "server@@" and
+ @$header@_from: does not contain "daemon@@" and
+ @$header@_from: does not contain "root@@" and
+ @$header@_auto-submitted: does not contain "auto-" and
+ @$header@_subject: does not contain "circular" and
+ @$header@_precedence: does not contain "bulk" and
+ @$header@_precedence: does not contain "list" and
+ @$header@_precedence: does not contain "junk"
+.endd
+The variable \$local@_part$\ contains the local part of the mail address of
+the user whose filter file is being run -- it is normally your login id. The
+\$domain$\ variable contains the mail domain. This condition tests for the
+appearance of the current user in the \"To:"\ header, checks that the sender is
+not the current user or one of a number of common daemons, and checks the
+content of the \"Subject:"\ and \"Precedence:"\ headers.
+
+If prefixes or suffixes are in use for local parts -- something which depends
+on the configuration of Exim (see section ~~SECTmbox below) -- the first two
+tests above are also done with
+.display asis
+$local_part_prefix$local_part$local_part_suffix
+.endd
+instead of just \$local@_part$\. If the system is configured to rewrite local
+parts of mail addresses, for example, to rewrite `dag46' as `Dirk.Gently',
+the rewritten form of the address is also used in the tests.
+
+This example shows the use of \"personal"\ in a filter file that is sending out
+vacation messages:
+.display asis
+if personal then
+ mail
+ to $reply_address
+ subject "Re: $h_subject:"
+ file $home/vacation/message
+ once $home/vacation/once
+ once_repeat 10d
+endif
+.endd
+
+It is quite common for people who have mail accounts on a number of different
+systems to forward all their mail to one system, and in this case a check for
+personal mail should test all their various mail addresses. To allow for this,
+the \"personal"\ condition keyword can be followed by
+.display
+alias <<address>>
+.endd
+any number of times, for example
+.display asis
+if personal alias smith@else.where.example
+ alias jones@other.place.example
+then ...
+.endd
+This causes messages containing the alias addresses in any places where the
+local address is tested to be treated as personal.
+
+.section Testing delivery status
+There are two conditions which are intended mainly for use in system filter
+files, but which are available in users' filter files as well. The condition
+\"first@_delivery"\ is true if this is the first attempt to deliver the
+message, and false otherwise.
+.em
+This indicator is not reset until the first delivery process successfully
+terminates; if there is a crash or a power failure (for example), the next
+delivery attempt is also a `first delivery'.
+.nem
+
+In a user filter file it will be false only if
+there was previously an error in the filter, or if a delivery for the user
+failed owing to, for example, a quota error, or forwarding to a remote
+address that was deferred for some reason.
+
+The condition \"manually@_thawed"\ is true only if the message was `frozen' for
+some reason, and was subsequently released by the system administrator. It is
+unlikely to be of use in users' filter files.
+
+.section Testing a list of addresses
+There is a facility for looping through a list of addresses and applying a
+condition to each of them. It takes the form
+.display
+foranyaddress <<string>> (<<condition>>)
+.endd
+where <<string>> is interpreted as a list of RFC 2822 addresses, as in a
+typical header line, and <<condition>> is any valid filter condition or
+combination of conditions. The `group' syntax that is defined for certain
+header lines that contain addresses is supported.
+
+The parentheses surrounding the condition are mandatory, to delimit it from
+possible further sub-conditions of the enclosing \"if"\ command. Within the
+condition, the expansion variable \$thisaddress$\ is set to the non-comment
+portion of each of the addresses in the string in turn. For example, if the
+string is
+.display asis
+B.Simpson <bart@sfld.example>, lisa@sfld.example (his sister)
+.endd
+then \$thisaddress$\ would take on the values \"bart@@sfld.example"\ and
+\"lisa@@sfld.example"\ in turn.
+
+If there are no valid addresses in the list, the whole condition is false. If
+the internal condition is true for any one address, the overall condition is
+true and the loop ends. If the internal condition is false for all addresses in
+the list, the overall condition is false. This example tests for the presence
+of an eight-digit local part in any address in a \To:\ header:
+.display asis
+if foranyaddress $h_to: ( $thisaddress matches ^\\d{8}@ ) then ...
+.endd
+When the overall condition is true, the value of \$thisaddress$\ in the
+commands that follow \"then"\ is the last value it took on inside the loop. At
+the end of the \"if"\ command, the value of \$thisaddress$\ is reset to what it
+was before. It is best to avoid the use of multiple occurrences of
+\"foranyaddress"\, nested or otherwise, in a single \"if"\ command, if the
+value of \$thisaddress$\ is to be used afterwards, because it isn't always
+clear what the value will be. Nested \"if"\ commands should be used instead.
+
+Header lines can be joined together if a check is to be applied to more than
+one of them. For example:
+.display asis
+if foranyaddress $h_to:,$h_cc: ....
+.endd
+scans through the addresses in both the \To:\ and the \Cc:\ headers.
+
+.section Multiple personal mailboxes
+.rset SECTmbox "~~chapter.~~section"
+The system administrator can configure Exim so that users can set up variants
+on their email addresses and handle them separately. Consult your system
+administrator or local documentation to see if this facility is enabled on your
+system, and if so, what the details are.
+
+The facility involves the use of a prefix or a suffix on an email address. For
+example, all mail addressed to \lg103-<<something>>\ would be the property of
+user \lg103\, who could determine how it was to be handled, depending on the
+value of <<something>>.
+
+There are two possible ways in which this can be set up. The first possibility
+is the use of multiple \(.forward)\ files. In this case, mail to \lg103-foo\,
+for example, is handled by looking for a file called \.forward-foo\ in
+\lg103's\ home directory. If such a file does not exist, delivery fails and the
+message is returned to its sender.
+
+The alternative approach is to pass all messages through a single \(.forward)\
+file, which must be a filter file in order to distinguish between the different
+cases by referencing the variables \$local@_part@_prefix$\ or
+\$local@_part@_suffix$\, as in the final example in section ~~SECTex below. If
+the filter file does not handle a prefixed or suffixed address, delivery fails
+and the message is returned to its sender.
+
+It is possible to configure Exim to support both schemes at once. In this case,
+a specific \.forward-foo\ file is first sought; if it is not found, the basic
+\(.forward)\ file is used.
+
+The \"personal"\ test (see section ~~SECTpersonal) includes prefixes and
+suffixes in its checking.
+
+
+.section Ignoring delivery errors
+As was explained above, filtering just sets up addresses for delivery -- no
+deliveries are actually done while a filter file is active. If any of the
+generated addresses subsequently suffers a delivery failure, an error message
+is generated in the normal way. However, if the filter command which sets up a
+delivery is preceded by the word \"noerror"\, errors for that delivery,
+$it{and any deliveries consequent on it} (that is, from alias, forwarding, or
+filter files it invokes) are ignored.
+
+
+.section Examples of Exim filter commands
+.rset SECTex "~~chapter.~~section"
+Simple forwarding:
+.display asis
+# Exim filter
+deliver baggins@rivendell.middle-earth.example
+.endd
+Vacation handling using traditional means, assuming that the \.vacation.msg\
+and other files have been set up in your home directory:
+.display asis
+# Exim filter
+unseen pipe "/usr/ucb/vacation \"$local_part\""
+.endd
+Vacation handling inside Exim, having first created a file called
+\.vacation.msg\ in your home directory:
+.display asis
+# Exim filter
+if personal then vacation endif
+.endd
+File some messages by subject:
+.display asis
+# Exim filter
+if $header_subject: contains "empire" or
+ $header_subject: contains "foundation"
+then
+ save $home/mail/f+e
+endif
+.endd
+Save all non-urgent messages by weekday:
+.display asis
+# Exim filter
+if $header_subject: does not contain "urgent" and
+ $tod_full matches "^(...),"
+then
+ save $home/mail/$1
+endif
+.endd
+Throw away all mail from one site, except from postmaster:
+.display asis
+# Exim filter
+if $reply_address contains "@spam.site.example" and
+ $reply_address does not contain "postmaster@"
+then
+ seen finish
+endif
+.endd
+.if ~~sgcal
+.if ~~sys.leftonpage < 6ld
+.newpage
+.fi
+.fi
+Handle multiple personal mailboxes
+.display asis
+# Exim filter
+if $local_part_suffix is "-foo"
+then
+ save $home/mail/foo
+elif $local_part_suffix is "-bar"
+then
+ save $home/mail/bar
+endif
+.endd
+
+. End of filter
diff --git a/doc/doc-src/markup.sg b/doc/doc-src/markup.sg
new file mode 100644
index 000000000..43e8853ac
--- /dev/null
+++ b/doc/doc-src/markup.sg
@@ -0,0 +1,86 @@
+. $Cambridge: exim/doc/doc-src/markup.sg,v 1.1 2004/10/07 15:04:35 ph10 Exp $
+.
+. SGCAL markup that is used for the Exim manual, and also for
+. the Filter document.
+
+. Flags for both plain and fancy
+
+.flag __ "@_$S0"
+
+.flag \\ "$sc{" "}"
+.flag ---- "@-@-@-@-"
+
+. Markup User for PostScript/PDF Text Info HTML
+. ------------------------------------------------------------------------------
+. \\...\\ SMTP, build small caps caps caps small caps
+. \(...)\ file name bold plain @file->`...' italic
+. \?...?\ URL bold plain plain URL
+. \%...%\ driver name bold "quoted" "quoted" bold
+. ::...:: header name bold: "quoted:" "quoted:" italic:
+. \...\ option bold "quoted" "quoted" fixed-pitch
+. \$...$\ variable $bold $plain $plain $fixed-pitch
+. \-...-\ cmd option -bold -plain -plain -italic
+. <<...>> data type <italic> <plain> <plain> <italic>
+. \*...*\ defn, emph, italic "quoted" @dfn->"..." italic
+. domain, user
+. \"..."\ literal fixed-pitch "quoted" @file->`...' fixed-pitch
+. \**...**\ warn, item bold plain plain bold
+
+.if ~~sys.fancy
+.flag \ "$bf{" "}"
+.flag \" "$tt{"
+.flag "\ "}"
+.flag \( "$bf{"
+.flag )\ "}"
+.flag \? "$bf{"
+.flag ?\ "}"
+.flag \$ "$bf{@$"
+.flag $\ "}"
+.flag \% "$bf{"
+.flag %\ "}
+.flag :: "$it{" ":}"
+.flag \- "$bf{-"
+.flag -\ "}"
+.flag << "<$it{"
+.flag >> "}>"
+.flag \** "$bf{"
+.flag **\ "}"
+.flag \* "$it{"
+.flag *\ "}"
+.flag $*$ "$D2*$U2"
+.flag $**$ "$rm{$=178}"
+.
+.else
+.pagedepth ~~sys.pagedepth - 1ld
+.linelength 78em
+.emphasis 79em
+.footdepth 0
+.disable formfeed
+.backspace none
+.set chapspaceb 24
+.set sspacea 24
+.flag \ """"
+.flag \" """"
+.flag "\ """"
+.flag \( ""
+.flag )\ ""
+.flag \? ""
+.flag ?\ ""
+.flag \$ "@$"
+.flag $\ ""
+.flag \% ""
+.flag %\ ""
+.flag :: "" ":"
+.flag \- "@-"
+.flag -\ ""
+.flag << "<"
+.flag >> ">"
+.flag \** ""
+.flag **\ ""
+.flag \* """"
+.flag *\ """"
+.flag $*$ "*"
+.flag $**$ "*"
+.flag --$< "-"
+.fi
+
diff --git a/doc/doc-src/spec.src b/doc/doc-src/spec.src
new file mode 100644
index 000000000..41a2ba13b
--- /dev/null
+++ b/doc/doc-src/spec.src
@@ -0,0 +1,27935 @@
+. $Cambridge: exim/doc/doc-src/spec.src,v 1.1 2004/10/07 15:04:35 ph10 Exp $
+.
+.set version "4.40"
+.set previousversion "4.30"
+.set versionmonth "July"
+.set versionyear "2004"
+.set ACL "ACL"
+
+. The last of those is to make ACL index entries easier to type. It is put
+. up here so that it gets picked up by the HTML converter, which otherwise
+. skips to the first chapter. A longer version is set below for use in the
+. printed index.
+
+.set sgcal true
+.set html false
+.set texinfo false
+
+.if !set style
+.library "a4ps"
+.linelength ~~sys.linelength + 0.2in
+.set newlinelength ~~sys.linelength
+.emphasis ~~sys.linelength + 0.1in
+.pagedepth ~~sys.pagedepth - 0.2in
+.bindfont 51 "atl/Times-Bold" 9
+.bindfont 52 "atl/Times-Roman" 9
+.bindfont 53 "atl/Times-Roman" 7
+.bindfont 54 "atl/Courier" 9
+.bindfont 55 "atl/Courier-Bold" ~~maintypesize
+.bindfont 56 "atl/Times-Italic" 7
+.bindfont 57 "atl/Times-Bold" 7
+.bindfont 58 "atl/Symbol" 7
+.set ssspaceb 1.50
+
+.if ~~sgcal
+. Used for the "small print" incorporated code stuff. Only rm, it, bf, sp are
+. actually used at present.
+. rm it sl bf bi ss tt sp sc
+.fontgroup 9 = 53 56 0 57 0 0 0 58 0
+.fi
+.fi
+
+.if !~~sys.fancy
+.fontgroup 9 = 0 0 0 0 0 0 0 0 0
+.fi
+
+.include "markup.sg"
+
+.if ~~sys.fancy
+.flag $smc{ "$push$g0$f54"
+.flag $sm{ "$push$g0$f53"
+.flag $smi{ "$push$g0$f56"
+.flag $as{ "$push$g0$f52"
+.flag $ab{ "$push$g0$f51"
+.flag $cb{ "$push$g0$f55"
+.
+.else
+.flag $smc{ "$push"
+.flag $sm{ "$push"
+.flag $smi{ "$push"
+.flag $cb{ "$push"
+.fi
+
+.macro isunderscore "string"
+.set string "~~1"
+.set length length "~~1"
+.undrec 1
+.endm
+
+.macro undrec "offset"
+.if ~~1 > ~~length
+.set underscore false
+.else
+.set sub "~~string"(1,~~1)
+.if "~~sub" == "_"
+.set underscore true
+.else
+.set next ~~1 + 1
+.undrec ~~next
+.fi
+.fi
+.endm
+
+.macro testunderscore "string"
+.isunderscore "~~1"
+.newline
+.endm
+
+.macro tabs 6
+.if ~~sys.fancy
+.tabset ~~1em
+.else
+.set temp (~~1 * 5)/4
+.tabset ~~temp em
+.fi
+.endm
+
+.macro startoptions
+.newline
+.push
+.if ~~sys.fancy
+.indent 6em
+.else
+.indent 7em
+.fi
+.endm
+
+.macro endoptions
+.newline
+.pop
+.endm
+
+.macro option "option" ""
+.newpar
+.index \-~~1-\ option
+.tempindent 0
+\-~~1-\~~2#$i
+.nosep
+.endm
+
+.macro startitems
+.newline
+.push
+.indent 3em
+.endm
+
+.macro enditems
+.newline
+.pop
+.endm
+
+.macro item "item" "6"
+.newpar
+.if ~~sys.leftonpage < ~~2ld
+.newpage
+.fi
+.tempindent 0
+\**~~1**\
+.blank
+.endm
+
+.macro startconf
+.newline
+.push
+.if ~~sys.fancy
+.indent 2em
+.tabset 9em
+.else
+.indent 4em
+.tabset 13em
+.fi
+.endm
+
+.macro endconf
+.newline
+.pop
+.endm
+
+.macro conf "option" "type" "default" "6"
+.newpar
+.if ~~sys.leftonpage < ~~4ld
+.newpage
+.fi
+.testunderscore "~~1"
+.if ~~underscore
+.index \~~1\
+.else
+.index \~~1\ option
+.fi
+.tempindent 0
+\**~~1**\ $c $rm{Type:} $it{~~2} $e $rm{Default:} $it{~~3}
+.blank
+.endm
+
+.set contents true
+.set figurenumber -1
+.set displayindent 2em
+
+.index @$1, @$2, etc. $it{see numerical variables}
+.index address||rewriting $it{see rewriting}
+.index CR character $it{see carriage return}
+.index CRL $it{see certificate revocation list}
+.index delivery||failure report $it{see bounce message}
+.index dialup $it{see intermittently connected hosts}
+.index failover $it{see fallback}
+.index fallover $it{see fallback}
+.index filter||Sieve $it{see Sieve filter}
+.index ident $it{see RFC 1413}
+.index LF character $it{see linefeed}
+.index maximum $it{see limit}
+.index NUL $it{see binary zero}
+.index process id $it{see pid}
+.index RBL $it{see DNS list}
+.index redirection $it{see address redirection}
+.index return path||$it{see also envelope sender}
+.index SSL $it{see TLS}
+.index string||expansion $it{see expansion}
+.index top bit $it{see 8-bit characters}
+.index variables $it{see expansion, variables}
+.index zero, binary $it{see binary zero}
+
+. This is used for the printed index. See setting above for
+. the HTML index value.
+
+.set ACL "access control lists (ACLs)"
+
+. ======================================================
+
+.push
+.disable filling
+.justify centre
+.nofoot
+.space 8ld
+$chead{University of Cambridge Computing Service}
+.space 2ld
+$chead{Specification of the Exim Mail Transfer Agent}
+.space 3ld
+by
+.space 1ld
+Philip Hazel
+.space ~~sys.leftonpage - 15*~~sys.linedepth
+.justify left
+University Computing Service
+New Museums Site
+Pembroke Street
+Cambridge CB2 3QH
+United Kingdom
+.blank
+.tabs 6
+$it{phone:} $t +44 1223 334600
+$it{fax:} $t +44 1223 334679
+$it{email:} $t ph10 $it{at} cus.cam.ac.uk
+.blank
+Edition for Exim ~~version, ~~versionmonth ~~versionyear
+.space 2ld
+.if ~~sgcal
+.fontgroup 1
+.fi
+$c$rm{Copyright (c) University of Cambridge ~~versionyear}
+
+
+.if ~~sgcal
+.fontgroup 0
+.font 0
+.fi
+
+.pop
+.newpage
+
+. Blank verso for title page
+.space 1ld
+.newpage
+
+
+. Set up for actual text pages
+.page 1
+. The first one to prevent a warning from sgfr
+. set runningfoot "~~chapter"
+.set runningfoot ""
+
+.if ~~sys.fancy
+.footdepth 2ld
+.foot
+.if "~~runningfoot" == ""
+.set rhs ""
+.else
+.set rhs "~~runningfoot (~~chapter)"
+.fi
+.set lhs "Exim ~~version"
+.linelength ~~newlinelength
+$it{~~lhs}$c[~~sys.pagenumber]$e$it{~~rhs}
+.endfoot
+.fi
+
+
+
+
+.
+.
+.
+.
+. ============================================================================
+.chapter Introduction
+.set runningfoot "introduction"
+
+.if ~~sys.fancy
+$c$bi{If I have seen further it is by standing on the shoulders of giants.}##(Isaac Newton)
+.elif !~~html
+$c"If I have seen further it is by standing on the shoulders of giants."
+.newline
+$e (Isaac Newton)
+.else
+\*If I have seen further it is by standing on the shoulders of giants.*\
+(Isaac Newton).
+.fi
+.blank 4
+
+Exim is a mail transfer agent (MTA) for hosts that are running Unix or
+Unix-like operating systems. It was designed on the assumption that it would be
+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.
+
+There are also configuration files for compiling Exim in the Cygwin environment
+that can be installed on systems running Windows. However, this document does
+not contain any information about running Exim in the Cygwin environment.
+
+The terms and conditions for the use and distribution of Exim are contained in
+the file \(NOTICE)\. Exim is distributed under the terms of the GNU General
+Public Licence, a copy of which may be found in the file \(LICENCE)\.
+
+The use, supply or promotion of Exim for the purpose of sending bulk,
+unsolicited electronic mail is incompatible with the basic aims of the program,
+which revolve around the free provision of a service that enhances the quality
+of personal communications. The author of Exim regards indiscriminate
+mass-mailing as an antisocial, irresponsible abuse of the Internet.
+
+Exim owes a great deal to Smail 3 and its author, Ron Karr. Without the
+experience of running and working on the Smail 3 code, I could never have
+contemplated starting to write a new MTA. Many of the ideas and user interfaces
+were originally taken from Smail 3, though the actual code of Exim is entirely
+new, and has developed far beyond the initial concept.
+
+Many people, both in Cambridge and around the world, have contributed to the
+development and the testing of Exim, and to porting it to various operating
+systems. I am grateful to them all. The distribution now contains a file called
+\(ACKNOWLEDGMENTS)\, in which I have started recording the names of
+contributors.
+
+.section Exim documentation
+.index documentation
+.em
+This edition of the Exim specification applies to version ~~version of Exim.
+Substantive changes from the ~~previousversion edition are marked by bars in
+the right-hand margin in the PostScript, PDF, and plain text versions of the
+document, and by green text in the HTML version, as shown by this paragraph.
+Changes are not marked in the Texinfo version, because Texinfo doesn't support
+change bars. Minor corrections and rewordings are not marked.
+.nem
+
+This document is very much a reference manual; it is not a tutorial. The reader
+is expected to have some familiarity with the SMTP mail transfer protocol and
+with general Unix system administration. Although there are some discussions
+and examples in places, the information is mostly organized in a way that makes
+it easy to look up, rather than in a natural order for sequential reading.
+Furthermore, the manual aims to cover every aspect of Exim in detail, including
+a number of rarely-used, special-purpose features that are unlikely to be of
+very wide interest.
+
+.index books about Exim
+An `easier' discussion of Exim which provides more in-depth explanatory,
+introductory, and tutorial material can be found in a book entitled
+.if ~~html
+[(A HREF="http://www.uit.co.uk/exim-book/")]
+$it{The Exim SMTP Mail Server},
+[(/A)]
+published by UIT Cambridge.
+.else
+$it{The Exim SMTP Mail Server}, published by UIT Cambridge
+(\?http://www.uit.co.uk/exim-book/?\).
+.fi
+
+This book also contains a chapter that gives a general introduction to SMTP and
+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.)
+
+.index \(doc/NewStuff)\
+.index \(doc/ChangeLog)\
+.index change log
+As the program develops, there may be features in newer versions that have not
+yet made it into this document, which is updated only when the most significant
+digit of the fractional part of the version number changes. However,
+specifications of new features that are not yet in this manual are placed in
+the file \(doc/NewStuff)\ in the Exim distribution. All changes to the program
+(whether new features, bug fixes, or other kinds of change) are noted briefly
+in the file called \(doc/ChangeLog)\.
+
+.index \(doc/spec.txt)\
+This specification itself is available as an ASCII file in \(doc/spec.txt)\ so
+that it can easily be searched with a text editor. Other files in the \(doc)\
+directory are:
+.display rm
+.tabs 18
+\(OptionLists.txt)\ $t $rm{list of all options in alphabetical order}
+\(dbm.discuss.txt)\ $t $rm{discussion about DBM libraries}
+\(exim.8)\ $t $rm{a man page of Exim's command line options}
+\(filter.txt)\ $t $rm{specification of the filter language}
+\(pcrepattern.txt)\ $t $rm{specification of PCRE regular expressions}
+\(pcretest.txt)\ $t $rm{specification of the PCRE testing program}
+\(Exim3.upgrade)\ $t $rm{upgrade notes from release 2 to release 3}
+\(Exim4.upgrade)\ $t $rm{upgrade notes from release 3 to release 4}
+.endd
+The main specification and the specification of the filtering language are also
+available in other formats (HTML, PostScript, PDF, and Texinfo). Section
+~~SECTavail below tells you how to get hold of these.
+
+
+.section FTP and web sites, and mailing list
+.index web site
+.index FTP site
+The primary distribution site for Exim is an FTP site, whose contents are
+described in \*Where to find the Exim distribution*\ below. In addition,
+there is a web site at \?http://www.exim.org?\ by courtesy of Energis Squared,
+formerly Planet Online Ltd, who are situated in the UK. The site is mirrored in
+a number of other countries; links to the mirrors are listed on the home page.
+The web site contains the Exim distribution, and you can also find the
+documentation and the
+.index FAQ
+.if ~~html
+[(A HREF="FAQ.html")]
+.fi
+FAQ
+.if ~~html
+[(/A)]
+.fi
+online there, as well as other relevant material.
+
+.index mailing lists||for Exim users
+Energis Squared also provide resources for the following mailing lists:
+.display rm
+.tabs 28
+$it{exim-users@@exim.org} $t general discussion list
+$it{exim-announce@@exim.org} $t moderated, low volume announcements list
+.endd
+You can subscribe to these lists, change your existing subscriptions, and view
+or search the archives via the
+.if ~~html
+[(A HREF="http://www.exim.org/maillist.html")]
+.fi
+mailing lists
+.if ~~html
+[(/A)]
+.fi
+link on the Exim home page. The $it{exim-users} mailing list is also forwarded
+to \?http://www.egroups.com/list/exim-users?\, an archiving system with
+searching capabilities.
+
+.section Exim training
+.index 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
+.if ~~html
+[(A HREF="http://www-tus.csx.cam.ac.uk/courses/exim/")]
+.fi
+\?http://www-tus@.csx@.cam@.ac.uk/courses/exim/?\.
+.if ~~html
+[(/A)]
+.fi
+
+.section Bug reports
+.index bug reports
+.index 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 $it{exim-users} mailing list and have it discussed.
+
+
+.section Where to find the Exim distribution
+.rset SECTavail "~~chapter.~~section"
+.index FTP site
+.index distribution||ftp site
+The master ftp site for the Exim distribution is
+.display rm
+.if ! ~~sys.fancy
+.indent 0
+.fi
+\?ftp://ftp.csx.cam.ac.uk/pub/software/email/exim?\
+.endd
+Within that directory there are subdirectories called \(exim3)\ (for previous
+Exim 3 distributions), \(exim4)\ (for the latest Exim 4 distributions), and
+\(Testing)\ for occasional testing versions. Those mirror sites that I know
+about are listed in the file
+.display rm
+.if ! ~~sys.fancy
+.indent 0
+.fi
+\?ftp://ftp.csx.cam.ac.uk/pub/software/email/exim/Mirrors?\
+.endd
+In the \(exim4)\ subdirectory, the current release can always be found in
+files called
+.display rm
+\(exim-$it{n.nn}.tar.gz)\
+\(exim-$it{n.nn}.tar.bz2)\
+.endd
+where $it{n.nn} is the highest such version number in the directory. The two
+files contain identical data; the only difference is the type of compression.
+The \(.bz2)\ file is usually a lot smaller than the \(.gz)\ file.
+.index distribution||signing details
+.index distribution||public key
+.index public key for signed distribution
+The distributions are signed with Philip Hazel's GPG key.
+The corresponding public key is available from a number of keyservers, and
+there is also a copy in the file:
+.display rm
+.if ! ~~sys.fancy
+.indent 0
+.fi
+\?ftp://ftp.csx.cam.ac.uk/pub/software/email/exim/Public-Key?\
+.endd
+The signatures for the tar bundles are in:
+.display rm
+\(exim-$it{n.nn}.tar.gz.sig)\
+\(exim-$it{n.nn}.tar.bz2.sig)\
+.endd
+
+When there is only a small amount of change from one release to the next, a
+patch file may be provided, with a final component name of the form
+.display rm
+\(exim-patch-$it{n.nn}-$it{m.mm}.gz)\
+.endd
+For each released version, the log of changes is made separately available in
+the directory
+.display rm
+\?ftp://ftp.csx.cam.ac.uk/pub/software/email/exim/ChangeLogs?\
+.endd
+so that it is possible to find out what has changed without having to download
+the entire distribution.
+
+.index documentation||available formats
+The main distribution contains ASCII versions of this specification and other
+documentation; other formats of the documents are available in separate files
+inside the \(exim4)\ directory of the FTP site:
+.display rm
+\(exim-html-$it{n.nn}.tar.gz)\
+\(exim-pdf-$it{n.nn}.tar.gz)\
+\(exim-postscript-$it{n.nn}.tar.gz)\
+\(exim-texinfo-$it{n.nn}.tar.gz)\
+.endd
+These tar files contain only the \(doc)\ directory, not the complete
+distribution, and are also available in \(.bz2)\ as well as \(.gz)\ forms.
+
+.index FAQ
+The FAQ is available for downloading in two different formats from
+.display rm
+.if ! ~~sys.fancy
+.indent 0
+.fi
+\?ftp://ftp.csx.cam.ac.uk/pub/software/email/exim/exim4/FAQ.txt.gz?\
+\?ftp://ftp.csx.cam.ac.uk/pub/software/email/exim/exim4/FAQ.html.tar.gz?\
+.endd
+The first of these is a single ASCII file that can be searched with a text
+editor. The second is a directory of HTML files, normally accessed by starting
+at \(index.html)\. The HTML version of the FAQ (which is also included in the
+HTML documentation tarbundle) includes a keyword-in-context index, which is
+often the most convenient way of finding your way around.
+
+.section Wish list
+.index wish list
+A wish list is maintained, containing ideas for new features that have been
+submitted. From time to time the file is exported to the ftp site:
+.display rm
+\?ftp://ftp.csx.cam.ac.uk/pub/software/email/exim/exim4/WishList?\
+.endd
+Items are removed from the list if they get implemented.
+
+
+.section Contributed material
+.index contributed material
+At the ftp site, there is a directory called
+.display rm
+.if ! ~~sys.fancy
+.indent 0
+.fi
+\?ftp://ftp.csx.cam.ac.uk/pub/software/email/exim/exim4/Contrib/?\
+.endd
+which contains miscellaneous files contributed to the Exim community by Exim
+users. There is also a collection of contributed configuration examples in
+.display rm
+.if ! ~~sys.fancy
+.indent 0
+.fi
+\?ftp://ftp.csx.cam.ac.uk/pub/software/email/exim/exim4/config.samples.tar.gz?\
+.endd
+These samples are referenced from the FAQ.
+
+
+.section Limitations
+.index limitations of Exim
+.numberpars $.
+Exim is designed for use as an Internet MTA, and therefore handles addresses
+in RFC 2822 domain format only.
+.index bang paths||not handled by Exim
+It cannot handle UUCP `bang paths', though simple two-component bang paths can
+be converted by a straightforward rewriting configuration. This restriction
+does not prevent Exim from being interfaced to UUCP as a transport mechanism,
+provided that domain addresses are used.
+.nextp
+.index domainless addresses
+.index address||without domain
+Exim insists that every address it handles has a domain attached. For incoming
+local messages, domainless addresses are automatically qualified with a
+configured domain value. Configuration options specify from which remote
+systems unqualified addresses are acceptable. These are then qualified on
+arrival.
+.nextp
+.index transport||external
+.index external transports
+The only external transport currently implemented is an SMTP transport over a
+TCP/IP network (using sockets, including support for IPv6). However, a pipe
+transport is available, and there are facilities for writing messages to files
+and pipes, optionally in \*batched SMTP*\ format; these facilities can be used
+to send messages to some other transport mechanism such as UUCP, provided it
+can handle domain-style addresses. Batched SMTP input is also catered for.
+.nextp
+Exim is not designed for storing mail for dial-in hosts. When the volumes of
+such mail are large, it is better to get the messages `delivered' into files
+(that is, off Exim's queue) and subsequently passed on to the dial-in hosts by
+other means.
+.nextp
+Although Exim does have some facilities for scanning incoming messages, these
+are not comprehensive enough to do full virus or spam scanning. Such operations
+are best carried out using additional specialized software packages.
+.endp
+
+
+
+.section Run time configuration
+Exim's run time configuration is held in a single text file that is divided
+into a number of sections. The entries in this file consist of keywords and
+values, in the style of Smail 3 configuration files. A default configuration
+file which is suitable for simple online installations is provided in the
+distribution, and is described in chapter ~~CHAPdefconfil below.
+
+
+.section Calling interface
+.index Sendmail compatibility||command line interface
+Like many MTAs, Exim has adopted the Sendmail command line interface so that it
+can be a straight replacement for \(/usr/lib/sendmail)\ or
+\(/usr/sbin/sendmail)\ when sending mail, but you do not need to know anything
+about Sendmail in order to run Exim. For actions other than sending messages,
+Sendmail-compatible options also exist, but those that produce output (for
+example, \-bp-\, which lists the messages on the queue) do so in Exim's own
+format. There are also some additional options that are compatible with Smail
+3, and some further options that are new to Exim. Chapter ~~CHAPcommandline
+documents all Exim's command line options. This information is automatically
+made into the man page that forms part of the Exim distribution.
+
+Control of messages on the queue can be done via certain privileged command
+line options. There is also an optional monitor program called \*eximon*\, which
+displays current information in an X window, and which contains a menu
+interface to Exim's command line administration options.
+
+
+.section Terminology
+.index terminology definitions
+.index body of message||definition of
+The \*body*\ of a message is the actual data that the sender wants to transmit.
+It is the last part of a message, and is separated from the \*header*\ (see
+below) by a blank line.
+
+.index bounce message||definition of
+When a message cannot be delivered, it is normally returned to the sender in a
+delivery failure message. The term \*bounce*\ is commonly used for this action,
+and the error reports are often called \*bounce messages*\. This is a
+convenient shorthand for `delivery failure error report'. Such messages have an
+empty sender address in the message's \*envelope*\ (see below) to ensure that
+they cannot themselves give rise to further bounce messages.
+
+The term \*default*\ appears frequently in this manual. It is used to qualify a
+value which is used in the absence of any setting in the configuration. It may
+also qualify an action which is taken unless a configuration setting specifies
+otherwise.
+
+The term \*defer*\ is used when the delivery of a message to a specific
+destination cannot immediately take place for some reason (a remote host may be
+down, or a user's local mailbox may be full). Such deliveries are \*deferred*\
+until a later time.
+
+The word \*domain*\ is sometimes used to mean all but the first component of a
+host's name. It is $it{not} used in that sense here, where it normally
+refers to the part of an email address following the @@ sign.
+
+.index envelope, definition of
+.index sender||definition of
+A message in transit has an associated \*envelope*\, as well as a header and a
+body. The envelope contains a sender address (to which bounce messages should
+be delivered), and any number of recipient addresses. References to the
+sender or the recipients of a message usually mean the addresses in the
+envelope. An MTA uses these addresses for delivery, and for returning bounce
+messages, not the addresses that appear in the header lines.
+
+.index message||header, definition of
+.index header section||definition of
+The \*header*\ of a message is the first part of a message's text, consisting
+of a number of lines, each of which has a name such as ::From::, ::To::,
+::Subject::, etc. Long header lines can be split over several text lines by
+indenting the continuations. The header is separated from the body by a blank
+line.
+
+.index local part||definition of
+.index domain||definition of
+The term \*local part*\, which is taken from RFC 2822, is used to refer to that
+part of an email address that precedes the @@ sign. The part that follows the
+@@ sign is called the \*domain*\ or \*mail domain*\.
+
+.index local delivery||definition of
+.index 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.
+
+.index return path||definition of
+\*Return path*\ is another name that is used for the sender address in a
+message's envelope.
+
+.index queue||definition of
+The term \*queue*\ is used to refer to the set of messages awaiting delivery,
+because this term is in widespread use in the context of MTAs. However, in
+Exim's case the reality is more like a pool than a queue, because there is
+normally no ordering of waiting messages.
+
+.index queue runner||definition of
+The term \*queue runner*\ is used to describe a process that scans the queue
+and attempts to deliver those messages whose retry times have come. This term
+is used by other MTAs, and also relates to the command \runq\, but in Exim
+the waiting messages are normally processed in an unpredictable order.
+
+.index spool directory||definition of
+The term \*spool directory*\ is used for a directory in which Exim keeps the
+messages on its queue -- that is, those that it is in the process of
+delivering. This should not be confused with the directory in which local
+mailboxes are stored, which is called a `spool directory' by some people. In
+the Exim documentation, `spool' is always used in the first sense.
+
+
+
+.
+.
+.
+.
+. ============================================================================
+.chapter Incorporated code
+.set runningfoot "incorporated code"
+.index incorporated code
+.index regular expressions||library
+.index PCRE
+A number of pieces of external code are included in the Exim distribution.
+.numberpars $.
+Regular expressions are supported in the main Exim program and in the Exim
+monitor using the freely-distributable PCRE library, copyright (c) 2003
+University of Cambridge. The source is distributed in the directory
+\(src/pcre)\. However, this is a cut-down version of PCRE. If you want to use
+the PCRE library in other programs, you should obtain and install the full
+version from \?ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre?\.
+
+.space 1ld
+.nextp
+.index cdb||acknowledgement
+Support for the cdb (Constant DataBase) lookup method is provided by code
+contributed by Nigel Metheringham of Planet Online Ltd. which contains the
+following statements:
+.rule
+.push
+.if ~~sgcal
+.fontgroup 9
+.font 0
+.fi
+Copyright (c) 1998 Nigel Metheringham, Planet Online Ltd
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation; either version 2 of the License, or (at your option) any later
+version.
+
+This code implements Dan Bernstein's Constant DataBase (cdb) spec. Information,
+the spec and sample code for cdb can be obtained from
+\?http://www.pobox.com/@~djb/cdb.html?\. This implementation borrows some code
+from Dan Bernstein's implementation (which has no license restrictions applied
+to it).
+.newline
+.pop
+.rule
+The implementation is completely contained within the code of Exim.
+It does not link against an external cdb library.
+.space 1ld
+.nextp
+.index SPA authentication
+.index Samba project
+.index Microsoft Secure Password Authentication
+Client support for Microsoft's \*Secure Password Authentication*\ is provided
+by code contributed by Marc Prud'hommeaux. Server support was contributed by
+Tom Kistner. This includes code taken from the Samba project, which is released
+under the Gnu GPL.
+
+.space 1ld
+.nextp
+.index Cyrus
+.index \*pwcheck*\ daemon
+.index \*pwauthd*\ daemon
+Support for calling the Cyrus \*pwcheck*\ and \*saslauthd*\ daemons is provided
+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.
+
+.rule
+.push
+.if ~~sgcal
+.fontgroup 9
+.font 0
+.fi
+Copyright (c) 2001 Carnegie Mellon University. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+.if ~~sgcal
+.cancelflag $npbracket
+.flag $npbracket "" "."
+.fi
+.numberpars
+Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+.nextp
+Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in
+the documentation and/or other materials provided with the
+distribution.
+.nextp
+The name `Carnegie Mellon University' must not be used to
+endorse or promote products derived from this software without
+prior written permission. For permission or any other legal
+details, please contact
+.display rm
+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
+.endd
+.nextp
+Redistributions of any form whatsoever must retain the following
+acknowledgment:
+.newline
+.push
+.indent ~~sys.indent + 3em
+.justify left
+$it{This product includes software developed by Computing Services
+at Carnegie Mellon University (\?http://www.cmu.edu/computing/?\).}
+.newline
+.pop
+.endp
+.if ~~sgcal
+.cancelflag $npbracket
+.flag $npbracket "(" ")"
+.fi
+
+CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
+THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
+FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 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.
+.newline
+.pop
+.rule
+
+.space 1ld
+.nextp
+.index monitor
+.index X-windows
+.index Athena
+The Exim Monitor program, which is an X-Window application, includes
+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.
+
+.rule
+.push
+.if ~~sgcal
+.fontgroup 9
+.font 0
+.fi
+Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
+and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
+.blank
+$c All Rights Reserved
+.blank
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the names of Digital or MIT not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
+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.
+.newline
+.pop
+.rule
+.endp
+
+
+
+.
+.
+.
+.
+. ============================================================================
+.chapter How Exim receives and delivers mail
+.set runningfoot "receiving & delivering mail"
+
+.section Overall philosophy
+.index design philosophy
+Exim is designed to work efficiently on systems that are permanently connected
+to the Internet and are handling a general mix of mail. In such circumstances,
+most messages can be delivered immediately. Consequently, Exim does not
+maintain independent queues of messages for specific domains or hosts, though
+it does try to send several messages in a single SMTP connection after a host
+has been down, and it also maintains per-host retry information.
+
+
+.section Policy control
+.index policy control||overview
+Policy controls are now an important feature of MTAs that are connected to the
+Internet. Perhaps their most important job is to stop MTAs being abused as
+`open relays' by misguided individuals who send out vast amounts of unsolicited
+junk, and want to disguise its source. Exim provides flexible facilities for
+specifying policy controls on incoming mail:
+.numberpars $.
+.index ~~ACL||introduction
+Exim 4 (unlike previous versions of Exim) implements policy controls on
+incoming SMTP mail by means of \*Access Control Lists*\ (ACLs). Each list is a
+series of statements that may either grant or deny access. ACLs can be used at
+several places in the SMTP dialogue while receiving a message. However, the
+most common places are after each \\RCPT\\ command, and at the very end of the
+message. The sysadmin can specify conditions for accepting or rejecting
+individual recipients or the entire message, respectively, at these two points
+(see chapter ~~CHAPACL). Denial of access results in an SMTP error code.
+.nextp
+An ACL is also available for locally generated, non-SMTP messages. In this
+case, the only available actions are to accept or deny the entire message.
+.nextp
+When a message has been received, either from a remote host or from the local
+host, but before the final acknowledgement has been sent, a locally supplied C
+function called \*local@_scan()*\ can be run to inspect the message and decide
+whether to accept it or not (see chapter ~~CHAPlocalscan). If the message is
+accepted, the list of recipients can be modified by the function.
+.nextp
+After a message has been accepted, a further checking mechanism is available in
+the form of the $it{system filter} (see chapter ~~CHAPsystemfilter). This runs
+at the start of every delivery process.
+.endp
+
+.section User filters
+.index filter||introduction
+.index Sieve filter
+In a conventional Exim configuration, users are able to run private filters by
+setting up appropriate \(.forward)\ files in their home directories. See
+chapter ~~CHAPredirect (about the \%redirect%\ router) for the configuration
+needed to support this, and the separate document entitled
+.if ~~html
+[(A HREF="filter_toc.html")]
+.fi
+\*Exim's interfaces to mail filtering*\
+.if ~~html
+[(/A)]
+.fi
+for user details. Two different kinds of filtering are available:
+.numberpars $.
+Sieve filters are written in the standard filtering language that is defined by
+RFC 3028.
+.nextp
+Exim filters are written in a syntax that is unique to Exim, but which is more
+powerful than Sieve, which it pre-dates.
+.endp
+User filters are run as part of the routing process, described below.
+
+
+.section Message identification
+.rset SECTmessiden "~~chapter.~~section"
+.index message||ids, details of format
+.index format||of message id
+.index id of message
+.index base62
+.index base36
+.index Darwin
+.index Cygwin
+Every message handled by Exim is given a \*message id*\ which is sixteen
+characters long. It is divided into three parts, separated by hyphens, for
+example \"16VDhn-0001bo-D3"\. Each part is a sequence of letters and digits,
+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.
+
+.index pid (process id)||re-use of
+The detail of the contents of the message id have changed as Exim has evolved.
+Earlier versions relied on the operating system not re-using a process id (pid)
+within one second. On modern operating systems, this assumption can no longer
+be made, so the algorithm had to be changed. To retain backward compatibility,
+the format of the message id was retained, which is why the following rules are
+somewhat eccentric:
+.numberpars $.
+The first six characters of the message id are the time at which the message
+started to be received, to a granularity of one second. That is, this field
+contains the number of seconds since the start of the epoch (the normal Unix
+way of representing the date and time of day).
+.nextp
+After the first hyphen, the next six characters are the id of the process that
+received the message.
+.nextp
+There are two different possibilities for the final two characters:
+.numberpars alpha
+.index \localhost@_number\
+If \localhost@_number\ is not set, this value is the fractional part of the
+time of reception, normally in units of 1/2000 of a second, but for systems
+that must use base 36 instead of base 62 (because of case-insensitive file
+systems), the units are 1/1000 of a second.
+.nextp
+If \localhost@_number\ is set, it is multiplied by 200 (100) and added to
+the fractional part of the time, which in this case is in units of 1/200
+(1/100) of a second.
+.endp
+.endp
+After a message has been received, Exim waits for the clock to tick at the
+appropriate resolution before proceeding, so that if another message is
+received by the same process, or by another process with the same (re-used)
+pid, it is guaranteed that the time will be different. In most cases, the clock
+will already have ticked while the message was being received.
+
+.section Receiving mail
+.index receiving mail
+.index 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
+SMTP commands. However, from a locally running process (such as a user's MUA),
+there are several possibilities:
+.numberpars $.
+If the process runs Exim with the \-bm-\ option, the message is read
+non-interactively (usually via a pipe), with the recipients taken from the
+command line, or from the body of the message if \-t-\ is also used.
+.nextp
+If the process runs Exim with the \-bS-\ option, the message is also read
+non-interactively, but in this case the recipients are listed at the start of
+the message in a series of SMTP \\RCPT\\ commands, terminated by a \\DATA\\
+command. This is so-called `batch SMTP' format,
+but it isn't really SMTP. The SMTP commands are just another way of passing
+envelope addresses in a non-interactive submission.
+.nextp
+If the process runs Exim with the \-bs-\ option, the message is read
+interactively, using the SMTP protocol. A two-way pipe is normally used for
+passing data between the local process and the Exim process.
+This is `real' SMTP and is handled in the same way as SMTP over TCP/IP. For
+example, the ACLs for SMTP commands are used for this form of submission.
+.nextp
+A local process may also make a TCP/IP call to the host's loopback address
+(127.0.0.1) or any other of its IP addresses. When receiving messages, Exim
+does not treat the loopback address specially. It treats all such connections
+in the same way as connections from other hosts.
+.endp
+
+.index message||sender, constructed by Exim
+.index sender||constructed by Exim
+In the three cases that do not involve TCP/IP, the sender address is
+constructed from the login name of the user that called Exim and a default
+qualification domain (which can be set by the \qualify@_domain\ configuration
+option). For local or batch SMTP, a sender address that is passed using the
+SMTP \\MAIL\\ command is ignored. However, the system administrator may allow
+certain users (`trusted users') to specify a different sender address
+unconditionally, or all users to specify certain forms of different sender
+address. The \-f-\ option or the SMTP \\MAIL\\ command is used to specify these
+different addresses. See section ~~SECTtrustedadmin for details of trusted
+users, and the \untrusted@_set@_sender\ option for a way of allowing untrusted
+users to change sender addresses.
+
+Messages received by either of the non-interactive mechanisms are subject to
+checking by the non-SMTP ACL, if one is defined. Messages received using SMTP
+(either over TCP/IP, or interacting with a local process) can be checked by a
+number of ACLs that operate at different times during the SMTP session. Either
+individual recipients, or the entire message, can be rejected if local policy
+requirements are not met. The \*local@_scan()*\ function (see chapter
+~~CHAPlocalscan) is run for all incoming messages.
+
+Exim can be configured not to start a delivery process when a message is
+received; this can be unconditional, or depend on the number of incoming SMTP
+connections or the system load. In these situations, new messages wait on the
+queue until a queue runner process picks them up. However, in standard
+configurations under normal conditions, delivery is started as soon as a
+message is received.
+
+
+
+
+.section Handling an incoming message
+.index spool directory||files that hold a message
+.index file||how a message is held
+When Exim accepts a message, it writes two files in its spool directory. The
+first contains the envelope information, the current status of the message,
+and the header lines, and the second contains the body of the message. The
+names of the two spool files consist of the message id, followed by $tt{-H} for
+the file containing the envelope and header, and $tt{-D} for the data file.
+
+.index spool directory||\(input)\ sub-directory
+By default all these message files are held in a single directory called
+\(input)\ inside the general Exim spool directory. Some operating systems do
+not perform very well if the number of files in a directory gets very large; to
+improve performance in such cases, the \split@_spool@_directory\ option can be
+used. This causes Exim to split up the input files into 62 sub-directories
+whose names are single letters or digits.
+
+The envelope information consists of the address of the message's sender and
+the addresses of the recipients. This information is entirely separate from
+any addresses contained in the header lines. The status of the message includes
+a list of recipients who have already received the message. The format of the
+first spool file is described in chapter ~~CHAPspool.
+
+.index rewriting||addresses
+Address rewriting that is specified in the rewrite section of the configuration
+(see chapter ~~CHAPrewrite) is done once and for all on incoming addresses,
+both in the header lines and the envelope, at the time the message is accepted.
+If during the course of delivery additional addresses are generated (for
+example, via aliasing), these new addresses are rewritten as soon as they are
+generated. At the time a message is actually delivered (transported) further
+rewriting can take place; because this is a transport option, it can be
+different for different forms of delivery. It is also possible to specify the
+addition or removal of certain header lines at the time the message is
+delivered (see chapters ~~CHAProutergeneric and ~~CHAPtransportgeneric).
+
+
+.section Life of a message
+.index message||life of
+.index message||frozen
+A message remains in the spool directory until it is completely delivered to
+its recipients or to an error address, or until it is deleted by an
+administrator or by the user who originally created it. In cases when delivery
+cannot proceed -- for example, when a message can neither be delivered to its
+recipients nor returned to its sender, the message is marked `frozen' on the
+spool, and no more deliveries are attempted.
+
+.index frozen messages||thawing
+.index message||thawing frozen
+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.
+
+.index \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.
+.index \timeout@_frozen@_after\
+There is also an option called \timeout@_frozen@_after\, which discards frozen
+messages after a certain time.
+
+.index message||log file for
+.index 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
+delayed deliveries for each recipient (see chapter ~~CHAPlog). The log lines
+are also written to a separate $it{message log} file for each message. These
+logs are solely for the benefit of the administrator, and are normally deleted
+along with the spool files when processing of a message is complete.
+The use of individual message logs can be disabled by setting
+\no@_message@_logs\; this might give an improvement in performance on very
+busy systems.
+
+.index journal file
+.index file||journal
+All the information Exim itself needs to set up a delivery is kept in the first
+spool file, along with the header lines. When a successful delivery occurs, the
+address is immediately written at the end of a journal file, whose name is the
+message id followed by $tt{-J}. At the end of a delivery run, if there are some
+addresses left to be tried again later, the first spool file (the $tt{-H} file)
+is updated to indicate which these are, and the journal file is then deleted.
+Updating the spool file is done by writing a new file and renaming it, to
+minimize the possibility of data loss.
+
+Should the system or the program crash after a successful delivery but before
+the spool file has been updated, the journal is left lying around. The next
+time Exim attempts to deliver the message, it reads the journal file and
+updates the spool file before proceeding. This minimizes the chances of double
+deliveries caused by crashes.
+
+
+.section Processing an address for delivery
+.rset SECTprocaddress "~~chapter.~~section"
+.index drivers||definition of
+.index router||definition of
+.index transport||definition of
+The main delivery processing elements of Exim are called $it{routers} and
+$it{transports}, and collectively these are known as $it{drivers}. Code for a
+number of them is provided in the source distribution, and compile-time options
+specify which ones are included in the binary. Run time options specify which
+ones are actually used for delivering messages.
+
+.index drivers||instance definition
+Each driver that is specified in the run time configuration is an \*instance*\
+of that particular driver type. Multiple instances are allowed; for example,
+you can set up several different \%smtp%\ transports, each with different
+option values that might specify different ports or different timeouts. Each
+instance has its own identifying name. In what follows we will normally use the
+instance name when discussing one particular instance (that is, one specific
+configuration of the driver), and the generic driver name when discussing
+the driver's features in general.
+
+A $it{router} is a driver that operates on an address, either determining how
+its delivery should happen, by routing 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.
+
+A $it{transport} is a driver that transmits a copy of the message from Exim's
+spool to some destination. There are two kinds of transport: for a $it{local}
+transport, the destination is a file or a pipe on the local host, whereas for a
+$it{remote} transport the destination is some other host. A message is passed
+to a specific transport as a result of successful routing. If a message has
+several recipients, it may be passed to a number of different transports.
+
+.index 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.
+
+.if ~~sys.fancy
+.figure "Routing an address" rm
+.indent 0
+.call aspic
+centre ~~sys.linelength;
+magnify 0.8;
+boundingbox 30;
+ ibox depth 14 "address";
+B: arrow down 44;
+ textdepth 14;
+A: box width 100 "first router" "conditions ok?";
+ arrow right "yes";
+C: box width 100 "run" "first router";
+ arrow down "fail";
+D: ibox depth 20 "address bounces";
+
+ arc clockwise from right of C "accept";
+ arrow down 10;
+ ibox "queue for" "transport";
+
+ arrow down from A align bottom of D plus (0,-20) "no"(-6,20)/r;
+E: box width 100 "second router" "conditions ok?";
+ arrow right "yes";
+F: box width 100 "run" "second router";
+ line right 100 "redirect";
+ line up align middle of B;
+ arrow left to middle of B "new addresses";
+
+ line down 20 from bottom left of F plus (30,0);
+ arrow left align centre of E "decline";
+
+ line down 20 from bottom right of F plus (-30,0);
+ arrow right "fail";
+ ibox width 64 "address" "bounces";
+
+ arrow down 64 from E "no"(-6,20)/r;
+G: box width 100 "third router" "conditions ok?";
+ arrow right "yes";
+H: box width 100 "run" "third router";
+ arc clockwise from right of H "accept";
+ arrow down 10;
+ ibox "queue for" "transport";
+
+ line down 20 from bottom of H;
+ arrow left align centre of G "decline";
+ arrow down 64 from G "no"(-6,20)/r;
+
+ ibox "no more routers" "address bounces";
+.endcall
+.endfigure
+.elif !~~html
+.display asis
+
+ address
+ |
+ |<------------- new addresses -----------------------------
+ V |
+ ----------------- ----------------- |
+ | first router |----- yes ----->| run |--- accept |
+ | conditions ok?| | first router | | |
+ ----------------- ----------------- | |
+ | | V |
+ no | fail | queue for |
+ | V transport |
+ | address bounces |
+ | |
+ V |
+ ----------------- ----------------- |
+ | second router |----- yes ----->| run |----redirect ----
+ | conditions ok?| | second router |
+ ----------------- -----------------
+ | | |
+ no | | |
+ |<-------- decline ----------- --- fail ---> address
+ | bounces
+ V
+ ----------------- -----------------
+ | third router |----- yes ----->| run |--- accept
+ | conditions ok?| | third router | |
+ ----------------- ----------------- |
+ | | V
+ no | | queue for
+ |<-------- decline --------------- transport
+ |
+ V
+ no more routers
+ address bounces
+.endd
+.else
+[(img src="routing.gif" alt="Routing an address")][(br)]
+.fi
+To make this a more concrete example, we'll describe it 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.
+
+The first router that is specified in a configuration is often one that handles
+addresses in domains that are not recognized specially by the local host. These
+are typically addresses for arbitrary domains on the Internet. A precondition
+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 $it{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
+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 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
+see if the local part is the name of a login account, or it may look up the
+local part in a file or a database. If its preconditions are not met, or if
+the router declines, we have reached the end of the routers. When this happens,
+the address is bounced.
+
+
+.section Processing an address for verification
+.index router||for verification
+.index verifying||address, overview
+As well as being used to decide how to deliver to an address, Exim's routers
+are also used for \*address verification*\. Verification can be requested as
+one of the checks to be performed in an ACL for incoming messages, on both
+sender and recipient addresses, and it can be tested using the \-bv-\ and
+\-bvs-\ command line options.
+
+When an address is being verified, the routers are run in `verify mode'. This
+does not affect the way the routers work, but it is a state that can be
+detected. By this means, a router can be skipped or made to behave differently
+when verifying. A common example is a configuration in which the first router
+sends all messages to a message-scanning program, unless they have been
+previously scanned. Thus, the first router accepts all addresses without any
+checking, making it useless for verifying. Normally, the \no@_verify\ option
+would be set for such a router, causing it to be skipped in verify mode.
+
+
+
+.section Running an individual router
+.rset SECTrunindrou "~~chapter.~~section"
+.index router||running details
+.index preconditions||checking
+.index router||result of running
+As explained in the example above, a number of preconditions are checked before
+running a router. If any are not met, the router is skipped, and the address is
+passed to the next router. When all the preconditions on a router $it{are} met,
+the router is run. What happens next depends on the outcome, which is one of
+the following:
+.numberpars $.
+\*accept*\: The router accepts the address, and either queues it for a
+transport, or generates one or more `child' addresses. Processing the original
+address ceases,
+.index \unseen\ option
+unless the \unseen\ option is set on the router. This option
+can be used to set up multiple deliveries with different routing (for example,
+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.
+
+.index case of local parts
+.index 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
+\redirect@_router\ may be anywhere in the router configuration.
+.nextp
+\*pass*\: The router recognizes the address, but cannot handle it itself. It
+requests that the address be passed to another router. By default the address
+is passed to the next router, but this can be changed by setting the
+\pass@_router\ option. However, (unlike \redirect@_router\) the named router
+must be below the current router (to avoid loops).
+.nextp
+\*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.
+.nextp
+\*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.
+.nextp
+\*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.
+.nextp
+\*error*\: There is some error in the router (for example, a syntax error in
+its configuration). The action is as for defer.
+.endp
+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.
+
+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.
+You can do this by having a second router that explicitly fails the delivery
+when the relevant conditions are met. The \%redirect%\ router has a `fail'
+facility for this purpose.
+
+
+
+.section Router preconditions
+.rset SECTrouprecon "~~chapter.~~section"
+.index router||preconditions, order of processing
+.index preconditions||order of processing
+The preconditions that are tested for each router are listed below, in the
+order in which they are tested. The individual configuration options are
+described in more detail in chapter ~~CHAProutergeneric.
+.numberpars $.
+The \local@_part@_prefix\ and \local@_part@_suffix\ options can specify that
+the local parts handled by the router may or must have certain prefixes and/or
+suffixes. If a mandatory affix (prefix or suffix) is not present, the router is
+skipped. These conditions are tested first. When an affix is present, it is
+removed from the local part before further processing, including the evaluation
+of any other conditions.
+.nextp
+Routers can be designated for use only when not verifying an address, that is,
+only when routing it for delivery (or testing its delivery routing). If the
+\verify\ option is set false, the router is skipped when Exim is verifying an
+address.
+Setting the \verify\ option actually sets two options, \verify@_sender\ and
+\verify@_recipient\, which independently control the use of the router for
+sender and recipient verification. You can set these options directly if
+you want a router to be used for only one type of verification.
+.nextp
+If the \address@_test\ option is set false, the router is skipped when Exim is
+run with the \-bt-\ option to test an address routing. This can be helpful when
+the first router sends all new messages to a scanner of some sort; it makes it
+possible to use \-bt-\ to test subsequent delivery routing without having to
+simulate the effect of the scanner.
+.nextp
+Routers can be designated for use only when verifying an address, as
+opposed to routing it for delivery. The \verify@_only\ option controls this.
+.nextp
+Certain routers can be explicitly skipped when running the routers to check an
+address given in the SMTP \\EXPN\\ command (see the \expn\ option).
+.nextp
+If the \domains\ option is set, the domain of the address must be in the set of
+domains that it defines.
+.nextp
+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
+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.
+.nextp
+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.
+.nextp
+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
+later, the value of \$home$\ as set by \check@_local@_user\ would be used in
+subsequent tests. Having two different values of \$home$\ in the same router
+could lead to confusion.
+.nextp
+If the \senders\ option is set, the envelope sender address must be in the set
+of addresses that it defines.
+.nextp
+If the \require@_files\ option is set, the existence or non-existence of
+specified files is tested.
+.nextp
+.index customizing||precondition
+If the \condition\ option is set, it is evaluated and tested. This option uses
+an expanded string to allow you to set up your own custom preconditions.
+Expanded strings are described in chapter ~~CHAPexpand.
+.endp
+
+Note that \require@_files\ comes near the end of the list, so you cannot use it
+to check for the existence of a file in which to lookup up a domain, local
+part, or sender. However, as these options are all expanded, you can use the
+\exists\ expansion condition to make such tests within each condition. The
+\require@_files\ option is intended for checking files that the router may be
+going to use internally, or which are needed by a specific transport (for
+example, \(.procmailrc)\).
+
+
+.section Delivery in detail
+.index delivery||in detail
+When a message is to be delivered, the sequence of events is as follows:
+.numberpars $.
+If a system-wide filter file is specified, the message is passed to it. The
+filter may add recipients to the message, replace the recipients, discard the
+message, cause a new message to be generated, or cause the message delivery to
+fail. The format of the system filter file is the same as for Exim user filter
+files, described in the separate document entitled
+.if ~~html
+[(A HREF="filter.html")]
+.fi
+\*Exim's interfaces to mail filtering*\.
+.if ~~html
+[(/A)]
+.fi
+.index Sieve filter||not available for system filter
+(\**Note**\: Sieve cannot be used for system filter files.)
+Some additional features are available in system filters -- see chapter
+~~CHAPsystemfilter for details. Note that a message is passed to the system
+filter only once per delivery attempt, however many recipients it has. However,
+if there are several delivery attempts because one or more addresses could not
+be immediately delivered, the system filter is run each time. The filter
+condition \first@_delivery\ can be used to detect the first run of the system
+filter.
+.nextp
+Each recipient address is offered to each configured router in turn, subject to
+its preconditions, until one is able to handle it. If no router can handle
+the address, that is, if they all decline, the address is failed. Because
+routers can be targeted at particular domains, several locally handled domains
+can be processed entirely independently of each other.
+.nextp
+.index routing||loops in
+.index 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.
+.nextp
+When all the routing has been done, addresses that have been successfully
+handled are passed to their assigned transports. When local transports are
+doing real local deliveries, they handle only one address at a time, but if a
+local transport is being used as a pseudo-remote transport (for example, to
+collect batched SMTP messages for transmission by some other means) multiple
+addresses can be handled. Remote transports can always handle more than one
+address at a time, but can be configured not to do so, or to restrict multiple
+addresses to the same domain.
+.nextp
+Each local delivery to a file or a pipe runs in a separate process under a
+non-privileged uid, and these deliveries are run one at a time. Remote
+deliveries also run in separate processes, normally under a uid that is private
+to Exim (`the Exim user'), but in this case, several remote deliveries can be
+run in parallel. The maximum number of simultaneous remote deliveries for any
+one message is set by the \remote@_max@_parallel\ option.
+.em
+The order in which deliveries are done is not defined, except that all local
+deliveries happen before any remote deliveries.
+.nem
+.nextp
+.index queue runner
+When it encounters a local delivery during a queue run, Exim checks its retry
+database to see if there has been a previous temporary delivery failure for the
+address before running the local transport. If there was a previous failure,
+Exim does not attempt a new delivery until the retry time for the address is
+reached. However, this happens only for delivery attempts that are part of a
+queue run. Local deliveries are always attempted when delivery immediately
+follows message reception, even if retry times are set for them. This makes for
+better behaviour if one particular message is causing problems (for example,
+causing quota overflow, or provoking an error in a filter file).
+.nextp
+.index delivery||retry in remote transports
+Remote transports do their own retry handling, since an address may be
+deliverable to one of a number of hosts, each of which may have a different
+retry time. If there have been previous temporary failures and no host has
+reached its retry time, no delivery is attempted, whether in a queue run or
+not. See chapter ~~CHAPretry for details of retry strategies.
+.nextp
+If there were any permanent errors, a bounce message is returned to an
+appropriate address (the sender in the common case), with details of the error
+for each failing address. Exim can be configured to send copies of bounce
+messages to other addresses.
+.nextp
+.index delivery||deferral
+If one or more addresses suffered a temporary failure, the message is left on
+the queue, to be tried again later. Delivery of these addresses is said to be
+\*deferred*\.
+.nextp
+When all the recipient addresses have either been delivered or bounced,
+handling of the message is complete. The spool files and message log are
+deleted, though the message log can optionally be preserved if required.
+.endp
+
+
+.section Retry mechanism
+.index delivery||retry mechanism
+.index retry||description of mechanism
+.index queue runner
+Exim's mechanism for retrying messages that fail to get delivered at the first
+attempt is the queue runner process. You must either run an Exim daemon that
+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
+passed its retry time.
+You can run several queue runners at once.
+
+Exim uses a set of configured rules to determine when next to retry the failing
+address (see chapter ~~CHAPretry). These rules also specify when Exim should
+give up trying to deliver to the address, at which point it generates a bounce
+message. If no retry rules are set for a particular host, address, and error
+combination, no retries are attempted, and temporary errors are treated as
+permanent.
+
+
+.section Temporary delivery failure
+.index delivery||temporary failure
+There are many reasons why a message may not be immediately deliverable to a
+particular address. Failure to connect to a remote machine (because it, or the
+connection to it, is down) is one of the most common. Temporary failures may be
+detected during routing as well as during the transport stage of delivery.
+Local deliveries may be delayed if NFS files are unavailable, or if a mailbox
+is on a file system where the user is over quota. Exim can be configured to
+impose its own quotas on local mailboxes; where system quotas are set they will
+also apply.
+
+If a host is unreachable for a period of time, a number of messages may be
+waiting for it by the time it recovers, and sending them in a single SMTP
+connection is clearly beneficial. Whenever a delivery to a remote host is
+deferred,
+.index hints database
+Exim makes a note in its hints database, and whenever a successful
+SMTP delivery has happened, it looks to see if any other messages are waiting
+for the same host. If any are found, they are sent over the same SMTP
+connection, subject to a configuration limit as to the maximum number in any
+one connection.
+
+
+
+.section Permanent delivery failure
+.index delivery||permanent failure
+.index bounce message||when generated
+When a message cannot be delivered to some or all of its intended recipients, a
+bounce message is generated. Temporary delivery failures turn into permanent
+errors when their timeout expires. All the addresses that fail in a given
+delivery attempt are listed in a single message. If the original message has
+many recipients, it is possible for some addresses to fail in one delivery
+attempt and others to fail subsequently, giving rise to more than one bounce
+message. The wording of bounce messages can be customized by the administrator.
+See chapter ~~CHAPemsgcust for details.
+
+.index ::X-Failed-Recipients:: header line
+Bounce messages contain an ::X-Failed-Recipients:: header line that lists the
+failed addresses, for the benefit of programs that try to analyse such messages
+automatically.
+
+.index bounce message||recipient of
+A bounce message is normally sent to the sender of the original message, as
+obtained from the message's envelope. For incoming SMTP messages, this is the
+address given in the \\MAIL\\ command. However, when an address is
+expanded via a forward or alias file, an alternative address can be specified
+for delivery failures of the generated addresses. For a mailing list expansion
+(see section ~~SECTmailinglists) it is common to direct bounce messages to the
+manager of the list.
+
+
+
+.section Failures to deliver bounce messages
+.index 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
+for only a short time (see \timeout@_frozen@_after\ and
+\ignore@_bounce@_errors@_after\).
+
+
+
+.
+.
+.
+.
+. ============================================================================
+.chapter Building and installing Exim
+.set runningfoot "building/installing"
+
+.index building Exim
+.section Unpacking
+Exim is distributed as a gzipped or bzipped tar file which, when upacked,
+creates a directory with the name of the current release (for example,
+\(exim-~~version)\) into which the following files are placed:
+.display rm
+.if !~~sys.fancy && ~~sgcal
+.tabs 16
+.else
+.tabs 22
+.fi
+\(ACKNOWLEDGMENTS)\ $t contains some acknowledgments
+.newline
+\(CHANGES)\ $t contains a reference to where changes are documented
+\(LICENCE)\ $t the GNU General Public Licence
+\(Makefile)\ $t top-level make file
+\(NOTICE)\ $t conditions for the use of Exim
+\(README)\ $t list of files, directories and simple build instructions
+.endd
+Other files whose names begin with \(README)\ may also be present. The
+following subdirectories are created:
+.display rm
+.if !~~sys.fancy && ~~sgcal
+.tabs 16
+.else
+.tabs 22
+.fi
+\(Local)\ $t an empty directory for local configuration files
+\(OS)\ $t OS-specific files
+\(doc)\ $t documentation files
+\(exim@_monitor)\$t source files for the Exim monitor
+\(scripts)\ $t scripts used in the build process
+\(src)\ $t remaining source files
+\(util)\ $t independent utilities
+.endd
+The main utility programs are contained in the \(src)\ directory, and are built
+with the Exim binary. The \(util)\ directory contains a few optional scripts
+that may be useful to some sites.
+
+.section Multiple machine architectures and operating systems
+.index building Exim||multiple OS/architectures
+The building process for Exim is arranged to make it easy to build binaries for
+a number of different architectures and operating systems from the same set of
+source files. Compilation does not take place in the \(src)\ directory. Instead,
+a \*build directory*\ is created for each architecture and operating system.
+.index symbolic link||to build directory
+Symbolic links to the sources are installed in this directory, which is where
+the actual building takes place.
+
+In most cases, Exim can discover the machine architecture and operating system
+for itself, but the defaults can be overridden if necessary.
+
+.section DBM libraries
+.rset SECTdb "~~chapter.~~section"
+.index DBM||libraries, discussion of
+.index hints database||DBM files used for
+Even if you do not use any DBM files in your configuration, Exim still needs a
+DBM library in order to operate, because it uses indexed files for its hints
+databases. Unfortunately, there are a number of DBM libraries in existence, and
+different operating systems often have different ones installed.
+
+.index Solaris||DBM library for
+.index IRIX, DBM library for
+.index BSD, DBM library for
+.index Linux, DBM library for
+If you are using Solaris, IRIX, one of the modern BSD systems, or a modern
+Linux distribution, the DBM configuration should happen automatically, and you
+may be able to ignore this section. Otherwise, you may have to learn more than
+you would like about DBM libraries from what follows.
+
+.index \*ndbm*\ DBM library
+Licensed versions of Unix normally contain a library of DBM functions operating
+via the \*ndbm*\ interface, and this is what Exim expects by default. Free
+versions of Unix seem to vary in what they contain as standard. In particular,
+some early versions of Linux have no default DBM library, and different
+distributors have chosen to bundle different libraries with their packaged
+versions. However, the more recent releases seem to have standardised on the
+Berkeley DB library.
+
+Different DBM libraries have different conventions for naming the files they
+use. When a program opens a file called \(dbmfile)\, there are four
+possibilities:
+.numberpars
+A traditional \*ndbm*\ implementation, such as that supplied as part of
+Solaris, operates on two files called \(dbmfile.dir)\ and \(dbmfile.pag)\.
+.nextp
+.index \*gdbm*\ DBM library
+The GNU library, \*gdbm*\, operates on a single file. If used via its \*ndbm*\
+compatibility interface it makes two different hard links to it with names
+\(dbmfile.dir)\ and \(dbmfile.pag)\, but if used via its native interface, the
+file name is used unmodified.
+.nextp
+.index Berkeley DB library
+The Berkeley DB package, if called via its \*ndbm*\ compatibility interface,
+operates on a single file called \(dbmfile.db)\, but otherwise looks to the
+programmer exactly the same as the traditional \*ndbm*\ implementation.
+.nextp
+If the Berkeley package is used in its native mode, it operates on a single
+file called \(dbmfile)\; the programmer's interface is somewhat different to
+the traditional \*ndbm*\ interface.
+.nextp
+To complicate things further, there are several very different versions of the
+Berkeley DB package. Version 1.85 was stable for a very long time, releases
+2.$it{x} and 3.$it{x} were current for a while, but the latest versions are now
+numbered 4.$it{x}. Maintenance of some of the earlier releases has ceased. All
+versions of Berkeley DB can be obtained from
+.display rm
+\?http://www.sleepycat.com/?\
+.endd
+.nextp
+.index \*tdb*\ DBM library
+Yet another DBM library, called \*tdb*\, has become available from
+.display rm
+\?http://download.sourceforge.net/tdb?\
+.endd
+It has its own interface, and also operates on a single file.
+.endp
+.index \\USE@_DB\\
+.index DBM||libraries, configuration for building
+Exim and its utilities can be compiled to use any of these interfaces. In order
+to use any version of the Berkeley DB package in native mode, you must set
+\\USE@_DB\\ in an appropriate configuration file (typically
+\(Local/Makefile)\). For example:
+.display asis
+USE_DB=yes
+.endd
+Similarly, for gdbm you set \\USE@_GDBM\\, and for tdb you set \\USE@_TDB\\. An
+error is diagnosed if you set more than one of these.
+
+At the lowest level, the build-time configuration sets none of these options,
+thereby assuming an interface of type (1). However, some operating system
+configuration files (for example, those for the BSD operating systems and
+Linux) assume type (4) by setting \\USE@_DB\\ as their default, and the
+configuration files for Cygwin set \\USE@_GDBM\\. Anything you set in
+\(Local/Makefile)\, however, overrides these system defaults.
+
+As well as setting \\USE@_DB\\, \\USE@_GDBM\\, or \\USE@_TDB\\, it may also be
+necessary to set \\DBMLIB\\, to cause inclusion of the appropriate library, as
+in one of these lines:
+.display asis
+DBMLIB = -ldb
+DBMLIB = -ltdb
+.endd
+Settings like that will work if the DBM library is installed in the standard
+place. Sometimes it is not, and the library's header file may also not be in
+the default path. You may need to set \\INCLUDE\\ to specify where the header
+file is, and to specify the path to the library more fully in \\DBMLIB\\, as in
+this example:
+.display asis
+INCLUDE=-I/usr/local/include/db-4.1
+DBMLIB=/usr/local/lib/db-4.1/libdb.a
+.endd
+
+There is further detailed discussion about the various DBM libraries in the
+file \(doc/dbm.discuss.txt)\ in the Exim distribution.
+
+
+.section Pre-building configuration
+.index building Exim||pre-building configuration
+.index configuration for building Exim
+.index \(Local/Makefile)\
+.index \(src/EDITME)\
+Before building Exim, a local configuration file that specifies options
+independent of any operating system has to be created with the name
+\(Local/Makefile)\. A template for this file is supplied as the file
+\(src/EDITME)\, and it contains full descriptions of all the option settings
+therein. These descriptions are therefore not repeated here. If you are
+building Exim for the first time, the simplest thing to do is to copy
+\(src/EDITME)\ to \(Local/Makefile)\, then read it and edit it appropriately.
+
+There are three settings that you must supply, because Exim will not build
+without them. They are the location of the run time configuration file
+(\\CONFIGURE@_FILE\\), the directory in which Exim binaries will be installed
+(\\BIN@_DIRECTORY\\), and the identity of the Exim user (\\EXIM@_USER\\ and
+maybe \\EXIM@_GROUP\\ as well). The value of \\CONFIGURE@_FILE\\ can in fact be
+a colon-separated list of file names; Exim uses the first of them that exists.
+
+There are a few other parameters that can be specified either at build time or
+at run time, to enable the same binary to be used on a number of different
+machines. However, if the locations of Exim's spool directory and log file
+directory (if not within the spool directory) are fixed, it is recommended that
+you specify them in \(Local/Makefile)\ instead of at run time, so that errors
+detected early in Exim's execution (such as a malformed configuration file) can
+be logged.
+
+.index \(Local/eximon.conf)\
+.index \(exim@_monitor/EDITME)\
+If you are going to build the Exim monitor, a similar configuration process is
+required. The file \(exim@_monitor/EDITME)\ must be edited appropriately for
+your installation and saved under the name \(Local/eximon.conf)\. If you are
+happy with the default settings described in \(exim@_monitor/EDITME)\,
+\(Local/eximon.conf)\ can be empty, but it must exist.
+
+This is all the configuration that is needed in straightforward cases for known
+operating systems. However, the building process is set up so that it is easy
+to override options that are set by default or by operating-system-specific
+configuration files, for example to change the name of the C compiler, which
+defaults to \gcc\. See section ~~SECToverride below for details of how to do
+this.
+
+
+.section Support for iconv()
+.index \*iconv()*\ support
+The contents of header lines in messages may be encoded according to the rules
+described RFC 2047. This makes it possible to transmit characters that are not
+in the ASCII character set, and to label them as being in a particular
+character set. When Exim is inspecting header lines by means of the \@$h@_\
+mechanism, it decodes them, and translates them into a specified character set
+(default ISO-8859-1). The translation is possible only if the operating system
+supports the \*iconv()*\ function.
+
+However, some of the operating systems that supply \*iconv()*\ do not support
+very many conversions. The GNU \libiconv\ library (available from
+\?http:/@/www.gnu.org/software/libiconv/?\) can be installed on such systems to
+remedy this deficiency, as well as on systems that do not supply \*iconv()*\ at
+all. After installing \libiconv\, you should add
+.display asis
+HAVE_ICONV=yes
+.endd
+to your \(Local/Makefile)\ and rebuild Exim.
+
+
+.section Including TLS/SSL encryption support
+.rset SECTinctlsssl "~~chapter.~~section"
+.index TLS||including support for TLS
+.index encryption||including support for
+.index \\SUPPORT@_TLS\\
+.index OpenSSL||building Exim with
+.index GnuTLS||building Exim with
+Exim can be built to support encrypted SMTP connections, using the \\STARTTLS\\
+command as per RFC 2487. It can also support legacy clients that expect to
+start a TLS session immediately on connection to a non-standard port (see the
+\-tls-on-connect-\ command line option).
+
+If you want to build Exim with TLS support, you must first install either the
+OpenSSL or GnuTLS library. There is no cryptographic code in Exim itself for
+implementing SSL.
+
+If OpenSSL is installed, you should set
+.display asis
+SUPPORT_TLS=yes
+TLS_LIBS=-lssl -lcrypto
+.endd
+in \(Local/Makefile)\. You may also need to specify the locations of the
+OpenSSL library and include files. For example:
+.display asis
+SUPPORT_TLS=yes
+TLS_LIBS=-L/usr/local/openssl/lib -lssl -lcrypto
+TLS_INCLUDE=-I/usr/local/openssl/include/
+.endd
+
+If GnuTLS is installed, you should set
+.index \\USE@_GNUTLS\\
+.display asis
+SUPPORT_TLS=yes
+USE_GNUTLS=yes
+TLS_LIBS=-lgnutls -ltasn1 -lgcrypt
+.endd
+in \(Local/Makefile)\, and again you may need to specify the locations of the
+library and include files. For example:
+.display asis
+SUPPORT_TLS=yes
+USE_GNUTLS=yes
+TLS_LIBS=-L/usr/gnu/lib -lgnutls -ltasn1 -lgcrypt
+TLS_INCLUDE=-I/usr/gnu/include
+.endd
+You do not need to set \\TLS@_INCLUDE\\ if the relevant directory is already
+specified in \\INCLUDE\\. Details of how to configure Exim to make use of TLS
+are given in chapter ~~CHAPTLS.
+
+
+
+.section Use of tcpwrappers
+.index tcpwrappers, building Exim to support
+.index \\USE@_TCP@_WRAPPERS\\
+Exim can be linked with the \*tcpwrappers*\ library in order to check incoming
+SMTP calls using the \*tcpwrappers*\ control files. This may be a convenient
+alternative to Exim's own checking facilities for installations that are
+already making use of \*tcpwrappers*\ for other purposes. To do this, you should
+set \\USE@_TCP@_WRAPPERS\\ in \(Local/Makefile)\, arrange for the file
+\(tcpd.h)\ to be available at compile time, and also ensure that the library
+\(libwrap.a)\ is available at link time, typically by including \-lwrap-\ in
+\\EXTRALIBS@_EXIM\\. For example, if \*tcpwrappers*\ is installed in
+\(/usr/local)\, you might have
+.display
+USE@_TCP@_WRAPPERS=yes
+CFLAGS=-O -I/usr/local/include
+.newline
+EXTRALIBS@_EXIM=-L/usr/local/lib -lwrap
+.endd
+in \(Local/Makefile)\. The name to use in the \*tcpwrappers*\ control files is
+`exim'. For example, the line
+.display
+exim : LOCAL 192.168.1. .friendly.domain.example
+.endd
+in your \(/etc/hosts.allow)\ file allows connections from the local host, from
+the subnet 192.168.1.0/24, and from all hosts in \*friendly.domain.example*\.
+All other connections are denied. Consult the \*tcpwrappers*\ documentation for
+further details.
+
+
+.section Including support for IPv6
+.index IPv6||including support for
+Exim contains code for use on systems that have IPv6 support. Setting
+\\HAVE@_IPV6=YES\\ in \(Local/Makefile)\ causes the IPv6 code to be included;
+it may also be necessary to set \\IPV6@_INCLUDE\\ and \\IPV6@_LIBS\\ on systems
+where the IPv6 support is not fully integrated into the normal include and
+library files.
+
+IPv6 is still changing rapidly. Two different types of DNS record for handling
+IPv6 addresses have been defined. AAAA records are already in use, and are
+currently seen as the `mainstream', but another record type called A6 is being
+argued about. Its status is currently `experimental'. Exim has support for A6
+records, but this is included only if you set \\SUPPORT@_A6=YES\\ in
+\(Local/Makefile)\.
+
+
+.section The building process
+.index build directory
+Once \(Local/Makefile)\ (and \(Local/eximon.conf)\, if required) have been
+created, run \*make*\ at the top level. It determines the architecture and
+operating system types, and creates a build directory if one does not exist.
+For example, on a Sun system running Solaris 8, the directory
+\(build-SunOS5-5.8-sparc)\ is created.
+.index symbolic link||to source files
+Symbolic links to relevant source files are installed in the build directory.
+
+.em
+\**Warning**\: The \-j-\ (parallel) flag must not be used with \*make*\; the
+building process fails if it is set.
+.nem
+
+If this is the first time \*make*\ has been run, it calls a script that builds
+a make file inside the build directory, using the configuration files from the
+\(Local)\ directory. The new make file is then passed to another instance of
+\*make*\. This does the real work, building a number of utility scripts, and
+then compiling and linking the binaries for the Exim monitor (if configured), a
+number of utility programs, and finally Exim itself. The command \*make
+makefile*\ can be used to force a rebuild of the make file in the build
+directory, should this ever be necessary.
+
+If you have problems building Exim, check for any comments there may be in the
+\(README)\ file concerning your operating system, and also take a look at the
+.if ~~html
+[(A HREF="FAQ.html")]
+.fi
+FAQ,
+.if ~~html
+[(/A)]
+.fi
+where some common problems are covered.
+
+
+
+.section Overriding build-time options for Exim
+.index build-time options, overriding
+.rset SECToverride "~~chapter.~~section"
+The main make file that is created at the beginning of the building process
+consists of the concatenation of a number of files which set configuration
+values, followed by a fixed set of \*make*\ instructions. If a value is set
+more than once, the last setting overrides any previous ones. This provides a
+convenient way of overriding defaults. The files that are concatenated are, in
+order:
+.display rm
+\(OS/Makefile-Default)\
+\(OS/Makefile-)\<<ostype>>
+\(Local/Makefile)\
+\(Local/Makefile-)\<<ostype>>
+\(Local/Makefile-)\<<archtype>>
+\(Local/Makefile-)\<<ostype>>-<<archtype>>
+\(OS/Makefile-Base)\
+.endd
+.index \(Local/Makefile)\
+where <<ostype>> is the operating system type and <<archtype>> is the
+.index building Exim||operating system type
+.index building Exim||architecture type
+architecture type. \(Local/Makefile)\ is required to exist, and the building
+process fails if it is absent. The other three \(Local)\ files are optional,
+and are often not needed.
+
+The values used for <<ostype>> and <<archtype>> are obtained from scripts
+called \(scripts/os-type)\ and \(scripts/arch-type)\ respectively. If either of
+the environment variables \\EXIM@_OSTYPE\\ or \\EXIM@_ARCHTYPE\\ is set, their
+values are used, thereby providing a means of forcing particular settings.
+Otherwise, the scripts try to get values from the \uname\ command. If this
+fails, the shell variables \\OSTYPE\\ and \\ARCHTYPE\\ are inspected. A number
+of $it{ad hoc} transformations are then applied, to produce the standard names
+that Exim expects. You can run these scripts directly from the shell in order
+to find out what values are being used on your system.
+
+
+\(OS/Makefile-Default)\ contains comments about the variables that are set
+therein. Some (but not all) are mentioned below. If there is something that
+needs changing, review the contents of this file and the contents of the make
+file for your operating system (\(OS/Makefile-<<ostype>>)\) to see what the
+default values are.
+
+
+.index building Exim||overriding default settings
+If you need to change any of the values that are set in \(OS/Makefile-Default)\
+or in \(OS/Makefile-<<ostype>>)\, or to add any new definitions, you do not
+need to change the original files. Instead, you should make the changes by
+putting the new values in an appropriate \(Local)\ file. For example,
+.index Tru64-Unix build-time settings
+when building Exim in many releases of the Tru64-Unix (formerly Digital UNIX,
+formerly DEC-OSF1) operating system, it is necessary to specify that the C
+compiler is called \*cc*\ rather than \*gcc*\. Also, the compiler must be
+called with the option \-std1-\, to make it recognize some of the features of
+Standard C that Exim uses. (Most other compilers recognize Standard C by
+default.) To do this, you should create a file called \(Local/Makefile-OSF1)\
+containing the lines
+.display
+CC=cc
+CFLAGS=-std1
+.endd
+If you are compiling for just one operating system, it may be easier to put
+these lines directly into \(Local/Makefile)\.
+
+Keeping all your local configuration settings separate from the distributed
+files makes it easy to transfer them to new versions of Exim simply by copying
+the contents of the \(Local)\ directory.
+
+
+.index NIS lookup type||including support for
+.index NIS@+ lookup type||including support for
+.index LDAP||including support for
+.index lookup||inclusion in binary
+Exim contains support for doing LDAP, NIS, NIS+, and other kinds of file
+lookup, but not all systems have these components installed, so the default is
+not to include the relevant code in the binary. All the different kinds of file
+and database lookup that Exim supports are implemented as separate code modules
+which are included only if the relevant compile-time options are set. In the
+case of LDAP, NIS, and NIS+, the settings for \(Local/Makefile)\ are:
+.display asis
+LOOKUP_LDAP=yes
+LOOKUP_NIS=yes
+LOOKUP_NISPLUS=yes
+.endd
+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
+libraries need to be installed before compiling Exim.
+.index cdb||including support for
+However, in the case of cdb, which is included in the binary only if
+.display asis
+LOOKUP_CDB=yes
+.endd
+is set, 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.
+
+.index Perl||including support for
+Exim can be linked with an embedded Perl interpreter, allowing Perl
+subroutines to be called during string expansion. To enable this facility,
+.display asis
+EXIM_PERL=perl.o
+.endd
+must be defined in \(Local/Makefile)\. Details of this facility are given in
+chapter ~~CHAPperl.
+
+.index 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
+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)\:
+.display asis
+X11=/usr/X11R6
+XINCLUDE=-I$(X11)/include
+XLFLAGS=-L$(X11)/lib
+.endd
+These are overridden in some of the operating-system configuration files. For
+example, in \(OS/Makefile-SunOS5)\ there is
+.display asis
+X11=/usr/openwin
+XINCLUDE=-I$(X11)/include
+XLFLAGS=-L$(X11)/lib -R$(X11)/lib
+.endd
+If you need to override the default setting for your operating system, place a
+definition of all three of these variables into your
+\(Local/Makefile-<<ostype>>)\ file.
+
+.index \\EXTRALIBS\\
+If you need to add any extra libraries to the link steps, these can be put in a
+variable called \\EXTRALIBS\\, which appears in all the link commands, but by
+default is not defined. In contrast, \\EXTRALIBS@_EXIM\\ is used only on the
+command for linking the main Exim binary, and not for any associated utilities.
+.index DBM||libraries, configuration for building
+There is also \\DBMLIB\\, which appears in the link commands for binaries that
+use DBM functions (see also section ~~SECTdb). Finally, there is
+\\EXTRALIBS@_EXIMON\\, which appears only in the link step for the Exim monitor
+binary, and which can be used, for example, to include additional X11
+libraries.
+
+.index configuration file||editing
+The make file copes with rebuilding Exim correctly if any of the configuration
+files are edited. However, if an optional configuration file is deleted, it is
+necessary to touch the associated non-optional file (that is, \(Local/Makefile)\
+or \(Local/eximon.conf)\) before rebuilding.
+
+.section OS-specific header files
+.index \(os.h)\
+.index building Exim||OS-specific C header files
+The \(OS)\ directory contains a number of files with names of the form
+\(os.h-<<ostype>>)\. These are system-specific C header files that should not
+normally need to be changed. There is a list of macro settings that are
+recognized in the file \(OS/os.configuring)\, which should be consulted if you
+are porting Exim to a new operating system.
+
+
+.section Overriding build-time options for the monitor
+.index building Eximon||overriding default options
+A similar process is used for overriding things when building the Exim monitor,
+where the files that are involved are
+.display rm
+\(OS/eximon.conf-Default)\
+\(OS/eximon.conf-)\<<ostype>>
+\(Local/eximon.conf)\
+\(Local/eximon.conf-)\<<ostype>>
+\(Local/eximon.conf-)\<<archtype>>
+\(Local/eximon.conf-)\<<ostype>>-<<archtype>>
+.endd
+.index \(Local/eximon.conf)\
+As with Exim itself, the final three files need not exist, and in this case the
+\(OS/eximon.conf-<<ostype>>)\ file is also optional. The default values in
+\(OS/eximon.conf-Default)\ can be overridden dynamically by setting environment
+variables of the same name, preceded by \\EXIMON@_\\. For example, setting
+\\EXIMON@_LOG@_DEPTH\\ in the environment overrides the value of
+\\LOG@_DEPTH\\ at run time.
+
+
+
+.section Installing Exim binaries and scripts
+.index installing Exim
+.index \\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)\.
+
+Exim's run time configuration file is named by the \\CONFIGURE@_FILE\\ setting
+.index \\CONFIGURE@_FILE\\
+in \(Local/Makefile)\. If this names a single file, and the file does not
+exist, the default configuration file \(src/configure.default)\ is copied there
+by the installation script. If a run time configuration file already exists, it
+is left alone. If \\CONFIGURE@_FILE\\ is a colon-separated list, naming several
+alternative files, no default is installed.
+
+.index system aliases file
+.index \(/etc/aliases)\
+One change is made to the default configuration file when it is installed: the
+default configuration contains a router that references a system aliases file.
+The path to this file is set to the value specified by
+\\SYSTEM@_ALIASES@_FILE\\ in \(Local/Makefile)\ (\(/etc/aliases)\ by default).
+If the system aliases file does not exist, the installation script creates it,
+and outputs a comment to the user.
+
+The created file contains no aliases, but it does contain comments about the
+aliases a site should normally have. Mail aliases have traditionally been
+kept in \(/etc/aliases)\. However, some operating systems are now using
+\(/etc/mail/aliases)\. You should check if yours is one of these, and change
+Exim's configuration if necessary.
+
+The default configuration uses the local host's name as the only local domain,
+and is set up to do local deliveries into the shared directory \(/var/mail)\,
+running as the local user. System aliases and \(.forward)\ files in users' home
+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.
+
+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,
+.index setuid||installing Exim with
+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
+.display asis
+make DESTDIR=/some/directory/ install
+.endd
+This has the effect of pre-pending the specified directory to all the file
+paths, except the name of the system aliases file that appears in the default
+configuration. (If a default alias file is created, its name \*is*\ modified.)
+For backwards compatibility, \\ROOT\\ is used if \\DESTDIR\\ is not set,
+but this usage is deprecated.
+
+.index installing Exim||what is not installed
+Running \*make install*\ does not copy the Exim 4 conversion script
+\*convert4r4*\, or the \*pcretest*\ test program. You will probably run the
+first of these only once (if you are upgrading from Exim 3), and the second
+isn't really part of Exim. None of the documentation files in the \(doc)\
+directory are copied, except for the info files when you have set
+\\INFO@_DIRECTORY\\, as described in section ~~SECTinsinfdoc below.
+
+For the utility programs, old versions are renamed by adding the suffix \(.O)\
+to their names. The Exim binary itself, however, is handled differently. It is
+installed under a name that includes the version number and the compile number,
+for example \(exim-~~version-1)\. The script then arranges for a symbolic link
+called \(exim)\ to point to the binary. If you are updating a previous version
+of Exim, the script takes care to ensure that the name \(exim)\ is never absent
+from the directory (as seen by other processes).
+
+.index installing Exim||testing the script
+If you want to see what the \*make install*\ will do before running it for
+real, you can pass the \-n-\ option to the installation script by this command:
+.display asis
+make INSTALL_ARG=-n install
+.endd
+The contents of the variable \\INSTALL@_ARG\\ are passed to the installation
+script. You do not need to be root to run this test. Alternatively, you can run
+the installation script directly, but this must be from within the build
+directory. For example, from the top-level Exim directory you could use this
+command:
+.display
+(cd build-SunOS5-5.5.1-sparc; ../scripts/exim@_install -n)
+.endd
+
+.index installing Exim||install script options
+There are two other options that can be supplied to the installation script.
+.numberpars $.
+\-no@_chown-\ bypasses the call to change the owner of the installed binary
+to root, and the call to make it a setuid binary.
+.nextp
+\-no@_symlink-\ bypasses the setting up of the symbolic link \(exim)\ to the
+installed binary.
+.endp
+\\INSTALL@_ARG\\ can be used to pass these options to the script. For example:
+.display asis
+make INSTALL_ARG=-no_symlink install
+.endd
+
+The installation script can also be given arguments specifying which files are
+to be copied. For example, to install just the Exim binary, and nothing else,
+without creating the symbolic link, you could use:
+.display asis
+make INSTALL_ARG='-no_symlink exim' install
+.endd
+
+
+.section Installing info documentation
+.rset SECTinsinfdoc "~~chapter.~~section"
+.index installing Exim||\*info*\ documentation
+Not all systems use the GNU \*info*\ system for documentation, and for this
+reason, the Texinfo source of Exim's documentation is not included in the main
+distribution. Instead it is available separately from the ftp site (see section
+~~SECTavail).
+
+If you have defined \\INFO@_DIRECTORY\\ in \(Local/Makefile)\ and the Texinfo
+source of the documentation is found in the source tree, running \*make
+install*\ automatically builds the info files and installs them.
+
+
+.section Setting up the spool directory
+.index spool directory||creating
+When it starts up, Exim tries to create its spool directory if it does not
+exist. The Exim uid and gid are used for the owner and group of the spool
+directory. Sub-directories are automatically created in the spool directory as
+necessary.
+
+
+
+.section Testing
+.index testing||installation
+Having installed Exim, you can check that the run time configuration file is
+syntactically valid by running the following command, which assumes that the
+Exim binary directory is within your \\PATH\\ environment variable:
+.display
+exim -bV
+.endd
+If there are any errors in the configuration file, Exim outputs error messages.
+Otherwise it outputs the version number and build date,
+the DBM library that is being used, and information about which drivers and
+other optional code modules are included in the binary.
+Some simple routing tests can be done by using the address testing option. For
+example,
+.display
+exim -bt <<local username>>
+.endd
+should verify that it recognizes a local mailbox, and
+.display
+exim -bt <<remote address>>
+.endd
+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:
+.display
+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
+.endd
+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
+arrival, one for its delivery, and one containing `Completed'.
+
+.index delivery||problems with
+If you encounter problems, look at Exim's log files (\*mainlog*\ and
+\*paniclog*\) to see if there is any relevant information there. Another source
+of information is running Exim with debugging turned on, by specifying the
+\-d-\ option. If a message is stuck on Exim's spool, you can force a delivery
+with debugging turned on by a command of the form
+.display
+exim -d -M <<message-id>>
+.endd
+You must be root or an `admin user' in order to do this. The \-d-\ option
+produces rather a lot of output, but you can cut this down to specific areas.
+For example, if you use \-d-all+route-\ only the debugging information relevant
+to routing is included. (See the \-d-\ option in chapter ~~CHAPcommandline for
+more details.)
+
+.index `sticky' bit
+.index lock files
+One specific problem that has shown up on some sites is the inability to do
+local deliveries into a shared mailbox directory, because it does not have the
+`sticky bit' set on it. By default, Exim tries to create a lock file before
+writing to a mailbox file, and if it cannot create the lock file, the delivery
+is deferred. You can get round this either by setting the `sticky bit' on the
+directory, or by setting a specific group for local deliveries and allowing
+that group to create files in the directory (see the comments above the
+\%local@_delivery%\ transport in the default configuration file). Another
+approach is to configure Exim not to use lock files, but just to rely on
+\*fcntl()*\ locking instead. However, you should do this only if all user
+agents also use \*fcntl()*\ locking. For further discussion of locking issues,
+see chapter ~~CHAPappendfile.
+
+One thing that cannot be tested on a system that is already running an MTA is
+the receipt of incoming SMTP mail on the standard SMTP port. However, the
+\-oX-\ option can be used to run an Exim daemon that listens on some other
+port, or \*inetd*\ can be used to do this. The \-bh-\ option and the
+\*exim@_checkaccess*\ utility can be used to check out policy controls on
+incoming SMTP mail.
+
+Testing a new version on a system that is already running Exim can most easily
+be done by building a binary with a different \\CONFIGURE@_FILE\\ setting. From
+within the run time configuration, all other file and directory names
+that Exim uses can be altered, in order to keep it entirely clear of the
+production version.
+
+.section Replacing another MTA with Exim
+.index replacing another MTA
+Building and installing Exim for the first time does not of itself put it in
+general use. The name by which the system's MTA is called by mail user agents
+is either \(/usr/sbin/sendmail)\, or \(/usr/lib/sendmail)\ (depending on the
+operating system), and it is necessary to make this name point to the \*exim*\
+binary in order to get the user agents to pass messages to Exim. This is
+normally done by renaming any existing file and making \(/usr/sbin/sendmail)\
+or \(/usr/lib/sendmail)\
+.index symbolic link||to \*exim*\ binary
+a symbolic link to the \*exim*\ binary. It is a good idea to remove any setuid
+privilege and executable status from the old MTA. It is then necessary to stop
+and restart the mailer daemon, if one is running.
+
+.index FreeBSD, MTA indirection
+.index \(/etc/mail/mailer.conf)\
+Some operating systems have introduced alternative ways of switching MTAs. For
+example, if you are running FreeBSD, you need to edit the file
+\(/etc/mail/mailer.conf)\ instead of setting up a symbolic link as just
+described. A typical example of the contents of this file for running Exim is
+as follows:
+.display asis
+sendmail /usr/exim/bin/exim
+send-mail /usr/exim/bin/exim
+mailq /usr/exim/bin/exim -bp
+newaliases /usr/bin/true
+.endd
+
+Once you have set up the symbolic link, or edited \(/etc/mail/mailer.conf)\,
+your Exim installation is `live'. Check it by sending a message from your
+favourite user agent.
+
+You should consider what to tell your users about the change of MTA. Exim may
+have different capabilities to what was previously running, and there are
+various operational differences such as the text of messages produced by
+command line options and in bounce messages. If you allow your users to make
+use of Exim's filtering capabilities, you should make the document entitled
+.if ~~html
+[(A HREF="filter.html")]
+.fi
+\*Exim's interface to mail filtering*\
+.if ~~html
+[(/A)]
+.fi
+available to them.
+
+
+.section Upgrading Exim
+.index upgrading Exim
+If you are already running Exim on your host, building and installing a new
+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.
+
+
+.section Stopping the Exim daemon on Solaris
+.index Solaris||stopping Exim on
+The standard command for stopping the mailer daemon on Solaris is
+.display
+/etc/init.d/sendmail stop
+.endd
+If \(/usr/lib/sendmail)\ has been turned into a symbolic link, this script
+fails to stop Exim because it uses the command \*ps -e*\ and greps the output
+for the text `sendmail'; this is not present because the actual program name
+(that is, `exim') is given by the \*ps*\ command with these options. A solution
+is to replace the line that finds the process id with something like
+.display asis
+pid=`cat /var/spool/exim/exim-daemon.pid`
+.endd
+to obtain the daemon's pid directly from the file that Exim saves it in.
+
+Note, however, that stopping the daemon does not `stop Exim'. Messages can
+still be received from local processes, and if automatic delivery is configured
+(the normal case), deliveries will still occur.
+
+
+.
+.
+.
+.
+. ============================================================================
+.chapter The Exim command line
+.set runningfoot "command line"
+.rset CHAPcommandline ~~chapter
+.index command line||options
+.index options||command line
+
+Exim's command line takes the standard Unix form of a sequence of options,
+each starting with a hyphen character, followed by a number of arguments. The
+options are compatible with the main options of Sendmail, and there are also
+some additional options, some of which are compatible with Smail 3. Certain
+combinations of options do not make sense, and provoke an error if used.
+The form of the arguments depends on which options are set.
+
+.section Setting options by program name
+.index \*mailq*\
+If Exim is called under the name \*mailq*\, it behaves as if the option \-bp-\
+were present before any other options.
+The \-bp-\ option requests a listing of the contents of the mail queue on the
+standard output.
+This feature is for compatibility with some systems that contain a command of
+that name in one of the standard libraries, symbolically linked to
+\(/usr/sbin/sendmail)\ or \(/usr/lib/sendmail)\.
+
+.index \*rsmtp*\
+If Exim is called under the name \*rsmtp*\ it behaves as if the option \-bS-\
+were present before any other options, for compatibility with Smail. The \-bS-\
+option is used for reading in a number of messages in batched SMTP format.
+
+.index \*rmail*\
+If Exim is called under the name \*rmail*\ it behaves as if the \-i-\ and
+\-oee-\ options were present before any other options, for compatibility with
+Smail. The name \*rmail*\ is used as an interface by some UUCP systems.
+
+.index \*runq*\
+.index queue runner
+If Exim is called under the name \*runq*\ it behaves as if the option \-q-\ were
+present before any other options, for compatibility with Smail. The \-q-\
+option causes a single queue runner process to be started.
+
+.index \*newaliases*\
+.index alias file||building
+.index Sendmail compatibility||calling Exim as \*newaliases*\
+If Exim is called under the name \*newaliases*\ it behaves as if the option
+\-bi-\ were present before any other options, for compatibility with Sendmail.
+This option is used for rebuilding Sendmail's alias file. Exim does not have
+the concept of a single alias file, but can be configured to run a given
+command if called with the \-bi-\ option.
+
+.section Trusted and admin users
+.rset SECTtrustedadmin "~~chapter.~~section"
+Some Exim options are available only to \*trusted users*\ and others are
+available only to \*admin users*\. In the description below, the phrases `Exim
+user' and `Exim group' mean the user and group defined by \\EXIM@_USER\\ and
+\\EXIM@_GROUP\\ in \(Local/Makefile)\ or set by the \exim@_user\ and
+\exim@_group\ options. These do not necessarily have to use the name `exim'.
+
+.numberpars $.
+.index trusted user||definition of
+.index user||trusted, definition of
+The trusted users are root, the Exim user, any user listed in the
+\trusted@_users\ configuration option, and any user whose current group or any
+supplementary group is one of those listed in the \trusted@_groups\
+configuration option. Note that the Exim group is not automatically trusted.
+
+.index `From' line
+.index envelope sender
+Trusted users are always permitted to use the \-f-\ option or a leading `From '
+line to specify the envelope sender of a message that is passed to Exim through
+the local interface (see the \-bm-\ and \-f-\ options below). See the
+\untrusted@_set@_sender\ option for a way of permitting non-trusted users to
+set envelope senders.
+.index ::From:: header line
+.index ::Sender:: header line
+For a trusted user, there is never any check on the contents of the ::From::
+header line, and a ::Sender:: line is never added. Furthermore, any existing
+::Sender:: line in incoming local (non-TCP/IP) messages is not removed.
+
+Trusted users may also specify a host name, host address, interface address,
+protocol name, ident value, and authentication data when submitting a message
+locally. Thus, they are able to insert messages into Exim's queue locally that
+have the characteristics of messages received from a remote host. Untrusted
+users may in some circumstances use \-f-\, but can never set the other values
+that are available to trusted users.
+.nextp
+.index user||admin, definition of
+.index admin user||definition of
+The admin users are root, the Exim user, and any user that is a member of the
+Exim group or of any group listed in the \admin@_groups\ configuration option.
+The current group does not have to be one of these groups.
+
+Admin users are permitted to list the queue, and to carry out certain
+operations on messages, for example, to force delivery failures. It is also
+necessary to be an admin user in order to see the full information provided by
+the Exim monitor, and full debugging output.
+
+By default, the use of the \-M-\, \-q-\, \-R-\, and \-S-\ options to cause Exim
+to attempt delivery of messages on its queue is restricted to admin users.
+However, this restriction can be relaxed by setting the \prod@_requires@_admin\
+option false (that is, specifying \no@_prod@_requires@_admin\).
+
+Similarly, the use of the \-bp-\ option to list all the messages in the queue
+is restricted to admin users unless \queue@_list@_requires@_admin\ is set
+false.
+.endp
+
+\**Warning**\: If you configure your system so that admin users are able to
+edit Exim's configuration file, you are giving those users an easy way of
+getting root. There is further discussion of this issue at the start of chapter
+~~CHAPconf.
+
+
+
+.section Command line options
+The command options are described in alphabetical order below.
+
+.startoptions
+
+.option @-
+.index options||command line, terminating
+This is a pseudo-option whose only purpose is to terminate the options and
+therefore to cause subsequent command line items to be treated as arguments
+rather than options, even if they begin with hyphens.
+
+.option -help
+This option causes Exim to output a few sentences stating what it is.
+The same output is generated if the Exim binary is called with no options and
+no arguments.
+
+.option B <<type>>
+.index 8-bit characters
+.index Sendmail compatibility||8-bit characters
+This is a Sendmail option for selecting 7 or 8 bit processing. Exim is 8-bit
+clean; it ignores this option.
+
+.option bd
+.index daemon
+.index SMTP listener
+.index queue runner
+This option runs Exim as a daemon, awaiting incoming SMTP connections. Usually
+the \-bd-\ option is combined with the \-q-\<<time>> option, to specify that
+the daemon should also initiate periodic queue runs.
+
+The \-bd-\ option can be used only by an admin user. If either of the \-d-\
+(debugging) or \-v-\ (verifying) options are set, the daemon does not
+disconnect from the controlling terminal. When running this way, it can be
+stopped by pressing ctrl-C.
+
+By default, Exim listens for incoming connections to the standard SMTP port on
+all the host's running interfaces. However, it is possible to listen on other
+ports, on multiple ports, and only on specific interfaces. Chapter
+~~CHAPinterfaces contains a description of the options that control this.
+
+.index daemon||process id (pid)
+.index pid (process id)||of daemon
+When a listening daemon is started without the use of \-oX-\ (that is, without
+overriding the normal configuration), it writes its process id to a file called
+\(exim-daemon.pid)\ in Exim's spool directory. This location can be overridden
+by setting \\PID@_FILE@_PATH\\ in \(Local/Makefile)\. The file is written while
+Exim is still running as root.
+
+When \-oX-\ is used on the command line to start a listening daemon, the
+process id is not written to the normal pid file path. However, \-oP-\ can be
+used to specify a path on the command line if a pid file is required.
+
+.index \\SIGHUP\\
+The \\SIGHUP\\ signal can be used to cause the daemon to re-exec itself. This
+should be done whenever Exim's configuration file, or any file that is
+incorporated into it by means of the \.include\ facility, is changed, and also
+whenever a new version of Exim is installed. It is not necessary to do this
+when other files that are referenced from the configuration (for example, alias
+files) are changed, because these are reread each time they are used.
+
+.option bdf
+This option has the same effect as \-bd-\ except that it never disconnects from
+the controlling terminal, even when no debugging is specified.
+
+.option be
+.index testing||string expansion
+.index expansion||testing
+Run Exim in expansion testing mode. Exim discards its root privilege, to
+prevent ordinary users from using this mode to read otherwise inaccessible
+files. If no arguments are given, Exim runs interactively, prompting for lines
+of data. Long expressions can be split over several lines by using backslash
+continuations.
+As in Exim's run time configuration, whitespace 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 message-specific values
+(such as \$domain$\) are set, because no message is being processed.
+
+.option bF #<<filename>>
+.index system filter||testing
+.index testing||system filter
+This option is the same as \-bf-\ except that it assumes that the filter being
+tested is a system filter. The additional commands that are available only in
+system filters are recognized.
+
+.option bf #<<filename>>
+.index filter||testing
+.index testing||filter file
+.index forward file||testing
+.index testing||forward file
+.index Sieve filter||testing
+This option runs Exim in filter testing mode; the file is the filter file to be
+tested, and a test message must be supplied on the standard input. If there are
+no message-dependent tests in the filter, an empty file can be supplied. If a
+system filter file is being tested, \-bF-\ should be used instead of \-bf-\. If
+the test file does not begin with
+one of the special lines
+.display asis
+# Exim filter
+# Sieve filter
+.endd
+it is taken to be a normal \(.forward)\ file, and is tested for validity under
+that interpretation. See sections ~~SECTitenonfilred to ~~SECTspecitredli for a
+description of the possible contents of non-filter redirection lists.
+
+The result of an Exim command that uses \-bf-\, provided no errors are
+detected, is a list of the actions that Exim would try to take if presented
+with the message for real. More details of filter testing are given in the
+separate document entitled \*Exim's interfaces to mail filtering*\.
+
+.index `From' line
+.index envelope sender
+.index \-f-\ option||for filter testing
+When testing a filter file, the envelope sender can be set by the \-f-\ option,
+or by a `From ' line at the start of the test message. Various parameters that
+would normally be taken from the envelope recipient address of the message can
+be set by means of additional command line options. These are:
+.display rm
+.if ~~sys.fancy
+.tabset 12em 16em
+.else
+.tabset 15em 20em
+.fi
+. The odd alignment here gets it lined up in the man page.
+\-bfd-\ $t <<domain>> $t $rm{default is the qualify domain}
+\-bfl-\ $t <<local@_part>> $t $rm{default is the logged in user}
+\-bfp-\ $t <<local@_part@_prefix>> $t $rm{default is null}
+\-bfs-\ $t <<local@_part@_suffix>> $t $rm{default is null}
+.endd
+The local part should always be set to the incoming address with any prefix or
+suffix stripped, because that is how it appears to the filter when a message is
+actually being delivered.
+
+.option bh #<<IP address>>
+.index testing||incoming SMTP
+.index SMTP||testing incoming
+.index testing||relay control
+.index relaying||testing configuration
+.index policy control||testing
+.index debugging||\-bh-\ option
+This option runs a fake SMTP session as if from the given IP address, using the
+standard input and output. The IP address may include a port number at the end,
+after a full stop. For example:
+.display asis
+exim -bh 10.9.8.7.1234
+exim -bh fe80::a00:20ff:fe86:a061.5678
+.endd
+Comments as to what is going on are written to the standard error file. These
+include lines beginning with `LOG' for anything that would have been logged.
+This facility is provided for testing configuration options for incoming
+messages, to make sure they implement the required policy. For example, you can
+test your relay controls using \-bh-\.
+
+.index RFC 1413
+\**Warning 1**\: You cannot test features of the configuration that rely on
+ident (RFC 1413) callouts. These cannot be done when testing using
+\-bh-\ because there is no incoming SMTP connection.
+
+\**Warning 2**\: Address verification callouts (see section ~~SECTcallver) are
+also skipped when testing using \-bh-\. If you want these callouts to occur,
+use \-bhc-\ instead.
+
+Messages supplied during the testing session are discarded, and nothing is
+written to any of the real log files. There may be pauses when DNS (and other)
+lookups are taking place, and of course these may time out. The \-oMi-\ option
+can be used to specify a specific IP interface and port if this is important.
+
+The \*exim@_checkaccess*\ utility is a `packaged' version of \-bh-\ whose
+output just states whether a given recipient address from a given host is
+acceptable or not. See section ~~SECTcheckaccess.
+
+.option bhc #<<IP address>>
+This option operates in the same way as \-bh-\, except that address
+verification callouts are performed if required. This includes consulting and
+updating the callout cache database.
+
+.option bi
+.index alias file||building
+.index building alias file
+.index Sendmail compatibility||\-bi-\ option
+Sendmail interprets the \-bi-\ option as a request to rebuild its alias file.
+Exim does not have the concept of a single alias file, and so it cannot mimic
+this behaviour. However, calls to \(/usr/lib/sendmail)\ with the \-bi-\ option
+tend to appear in various scripts such as NIS make files, so the option must be
+recognized.
+
+If \-bi-\ is encountered, the command specified by the \bi@_command\
+configuration option is run, under the uid and gid of the caller of Exim. If
+the \-oA-\ option is used, its value is passed to the command as an argument.
+The command set by \bi@_command\ may not contain arguments. The command can use
+the \*exim@_dbmbuild*\ utility, or some other means, to rebuild alias files if
+this is required. If the \bi@_command\ option is not set, calling Exim with
+\-bi-\ is a no-op.
+
+.option bm
+.index local message reception
+This option runs an Exim receiving process that accepts an incoming,
+locally-generated message on the current input. The recipients are given as the
+command arguments (except when \-t-\ is also present -- see below). Each
+argument can be a comma-separated list of RFC 2822 addresses. This is the
+default option for selecting the overall action of an Exim call; it is assumed
+if no other conflicting option is present.
+
+If any addresses in the message are unqualified (have no domain), they are
+qualified by the values of the \qualify@_domain\ or \qualify@_recipient\
+options, as appropriate. The \-bnq-\ option (see below) provides a way of
+suppressing this for special cases.
+
+Policy checks on the contents of local messages can be enforced by means of the
+non-SMTP ACL. See chapter ~~CHAPACL for details.
+.index return code||for \-bm-\
+The return code is zero if the message is successfully accepted. Otherwise, the
+action is controlled by the \-oe$it{x}-\ option setting -- see below.
+
+.index message||format
+.index format||message
+.index `From' line
+.index UUCP||`From' line
+.index Sendmail compatibility||`From' line
+The format of the message must be as defined in RFC 2822, except that, for
+compatibility with Sendmail and Smail, a line in one of the forms
+.display
+From sender Fri Jan 5 12:55 GMT 1997
+From sender Fri, 5 Jan 97 12:55:01
+.endd
+(with the weekday optional, and possibly with additional text after the date)
+is permitted to appear at the start of the message. There appears to be no
+authoritative specification of the format of this line. Exim recognizes it by
+matching against the regular expression defined by the \uucp@_from@_pattern\
+option, which can be changed if necessary.
+.index \-f-\ option||overriding `From' line
+The specified sender is treated as if it were given as the argument to the
+\-f-\ option, but if a \-f-\ option is also present, its argument is used in
+preference to the address taken from the message. The caller of Exim must be a
+trusted user for the sender of a message to be set in this way.
+
+.option bnq
+.index address||qualification, suppressing
+By default, Exim automatically qualifies unqualified addresses (those
+without domains) that appear in messages that are submitted locally (that
+is, not over TCP/IP). This qualification applies both to addresses in
+envelopes, and addresses in header lines. Sender addresses are qualified using
+\qualify@_domain\, and recipient addresses using \qualify@_recipient\ (which
+defaults to the value of \qualify@_domain\).
+
+Sometimes, qualification is not wanted. For example, if \-bS-\ (batch SMTP) is
+being used to re-submit messages that originally came from remote hosts after
+content scanning, you probably do not want to qualify unqualified addresses in
+header lines. (Such lines will be present only if you have not enabled a header
+syntax check in the appropriate ACL.)
+
+The \-bnq-\ option suppresses all qualification of unqualified addresses in
+messages that originate on the local host. When this is used, unqualified
+addresses in the envelope provoke errors (causing message rejection) and
+unqualified addresses in header lines are left alone.
+
+
+.option bP
+.index configuration options, extracting
+.index options||configuration, extracting
+If this option is given with no arguments, it causes the values of all Exim's
+main configuration options to be written to the standard output. The values
+of one or more specific options can be requested by giving their names as
+arguments, for example:
+.display
+exim -bP qualify@_domain hold@_domains
+.endd
+However, any option setting that is preceded by the word `hide' in the
+configuration file is not shown in full, except to an admin user. For other
+users, the output is as in this example:
+.display asis
+mysql_servers = <value not displayable>
+.endd
+If \configure@_file\ is given as an argument, the name of the run time
+configuration file is output.
+If a list of configuration files was supplied, the value that is output here
+is the name of the file that was actually used.
+
+.index daemon||process id (pid)
+.index pid (process id)||of daemon
+If \log__file__path\ or \pid@_file@_path\ are given, the names of the
+directories where log files and daemon pid files are written are output,
+respectively. If these values are unset, log files are written in a
+sub-directory of the spool directory called \log\, and the pid file is written
+directly into the spool directory.
+
+If \-bP-\ is followed by a name preceded by \"+"\, for example,
+.display asis
+exim -bP +local_domains
+.endd
+it searches for a matching named list of any type (domain, host, address, or
+local part) and outputs what it finds.
+
+.index options||router, extracting
+.index options||transport, extracting
+If one of the words \router\, \transport\, or \authenticator\ is given,
+followed by the name of an appropriate driver instance, the option settings for
+that driver are output. For example:
+.display
+exim -bP transport local@_delivery
+.endd
+The generic driver options are output first, followed by the driver's private
+options. A list of the names of drivers of a particular type can be obtained by
+using one of the words \router@_list\, \transport@_list\, or
+\authenticator@_list\, and a complete list of all drivers with their option
+settings can be obtained by using \routers\, \transports\, or \authenticators\.
+
+
+.option bp
+.index queue||listing messages on
+.index listing||messages on the queue
+This option requests a listing of the contents of the mail queue on the
+standard output. If the \-bp-\ option is followed by a list of message ids,
+just those messages are listed. By default, this option can be used only by an
+admin user. However, the \queue__list__requires__admin\ option can be set false
+to allow any user to see the queue.
+
+Each message on the queue is displayed as in the following example:
+.display
+25m 2.9K 0t5C6f-0000c8-00 <alice@@wonderland.fict.example>
+ red.king@@looking-glass.fict.example
+ <<other addresses>>
+.endd
+.index message||size in queue listing
+.index size||of message
+The first line contains the length of time the message has been on the queue
+(in this case 25 minutes), the size of the message (2.9K), the unique local
+identifier for the message, and the message sender, as contained in the
+envelope. For bounce messages, the sender address is empty, and appears as
+`<>'. If the message was submitted locally by an untrusted user who overrode
+the default sender address, the user's login name is shown in parentheses
+before the sender address.
+.index frozen messages||in queue listing
+If the message is frozen (attempts to deliver it are suspended) then the text
+`$*$$*$$*$ frozen $*$$*$$*$' is displayed at the end of this line.
+
+The recipients of the message (taken from the envelope, not the headers) are
+displayed on subsequent lines. Those addresses to which the message has already
+been delivered are marked with the letter D. If an original address gets
+expanded into several addresses via an alias or forward file, the original is
+displayed with a D only when deliveries for all of its child addresses are
+complete.
+
+
+.option bpa
+This option operates like \-bp-\, but in addition it shows delivered addresses
+that were generated from the original top level address(es) in each message by
+alias or forwarding operations. These addresses are flagged with `+D' instead
+of just `D'.
+
+
+.option bpc
+.index queue||count of messages on
+This option counts the number of messages on the queue, and writes the total
+to the standard output. It is restricted to admin users, unless
+\queue__list__requires__admin\ is set false.
+
+
+.option bpr
+This option operates like \-bp-\, but the output is not sorted into
+chronological order of message arrival. This can speed it up when there are
+lots of messages on the queue, and is particularly useful if the output is
+going to be post-processed in a way that doesn't need the sorting.
+
+.option bpra
+This option is a combination of \-bpr-\ and \-bpa-\.
+
+.option bpru
+This option is a combination of \-bpr-\ and \-bpu-\.
+
+
+.option bpu
+This option operates like \-bp-\ but shows only undelivered top-level addresses
+for each message displayed. Addresses generated by aliasing or forwarding are
+not shown, unless the message was deferred after processing by a router with
+the \one@_time\ option set.
+
+
+.option brt
+.index testing||retry configuration
+.index retry||configuration testing
+This option is for testing retry rules, and it must be followed by up to three
+arguments. It causes Exim to look for a retry rule that matches the values
+and to write it to the standard output. For example:
+.display asis
+exim -brt bach.comp.mus.example
+Retry rule: *.comp.mus.example F,2h,15m; F,4d,30m;
+.endd
+See chapter ~~CHAPretry for a description of Exim's retry rules. The first
+argument, which is required, can be a complete address in the form
+\*local@_part@@domain*\, or it can be just a domain name. The second argument is
+an optional second domain name; if no retry rule is found for the first
+argument, the second is tried. This ties in with Exim's behaviour when looking
+for retry rules for remote hosts -- if no rule is found that matches the host,
+one that matches the mail domain is sought. The final argument is the name of a
+specific delivery error, as used in setting up retry rules, for example
+`quota@_3d'.
+
+.option brw
+.index testing||rewriting
+.index rewriting||testing
+This option is for testing address rewriting rules, and it must be followed by
+a single argument, consisting of either a local part without a domain, or a
+complete address with a fully qualified domain. Exim outputs how this address
+would be rewritten for each possible place it might appear. See chapter
+~~CHAPrewrite for further details.
+
+.option bS
+.index SMTP||batched incoming
+.index batched SMTP input
+This option is used for batched SMTP input, which is an alternative interface
+for non-interactive local message submission. A number of messages can be
+submitted in a single run. However, despite its name, this is not really SMTP
+input. Exim reads each message's envelope from SMTP commands on the standard
+input, but generates no responses. If the caller is trusted, or
+\untrusted@_set@_sender\ is set, the senders in the SMTP \\MAIL\\ commands are
+believed; otherwise the sender is always the caller of Exim.
+
+The message itself is read from the standard input, in SMTP format (leading
+dots doubled), terminated by a line containing just a single dot. An error is
+provoked if the terminating dot is missing. A further message may then follow.
+
+As for other local message submissions, the contents of incoming batch SMTP
+messages can be checked using the non-SMTP ACL (see chapter ~~CHAPACL).
+Unqualified addresses are automatically qualified using \qualify@_domain\ and
+\qualify@_recipient\, as appropriate, unless the \-bnq-\ option is used.
+
+Some other SMTP commands are recognized in the input. \\HELO\\ and \\EHLO\\ act
+as \\RSET\\; \\VRFY\\, \\EXPN\\, \\ETRN\\, and \\HELP\\ act as \\NOOP\\;
+\\QUIT\\ quits, ignoring the rest of the standard input.
+
+If any error is encountered, reports are written to the standard output and
+error streams, and Exim gives up immediately.
+.index return code||for \-bS-\
+The return code is 0 if no error was detected; it is 1 if one or more messages
+were accepted before the error was detected; otherwise it is 2.
+
+More details of input using batched SMTP are given in section
+~~SECTincomingbatchedSMTP.
+
+.option bs
+.index SMTP||local input
+.index local SMTP input
+This option causes Exim to accept one or more messages by reading SMTP commands
+on the standard input, and producing SMTP replies on the standard output. SMTP
+policy controls, as defined in ACLs (see chapter ~~CHAPACL) are applied.
+
+Some user agents use this interface as a way of passing locally-generated
+messages to the MTA.
+.index sender||source of
+In this usage, if the caller of Exim is trusted, or \untrusted@_set@_sender\ is
+set, the senders of messages are taken from the SMTP \\MAIL\\ commands.
+Otherwise the content of these commands is ignored and the sender is set up as
+the calling user. Unqualified addresses are automatically qualified using
+\qualify@_domain\ and \qualify@_recipient\, as appropriate, unless the \-bnq-\
+option is used.
+
+.index inetd
+The \-bs-\ option is also used to run Exim from \*inetd*\, as an alternative to
+using a listening daemon. Exim can distinguish the two cases by checking
+whether the standard input is a TCP/IP socket. When Exim is called from
+\*inetd*\, the source of the mail is assumed to be remote, and the comments
+above concerning senders and qualification do not apply. In this situation,
+Exim behaves in exactly the same way as it does when receiving a message via
+the listening daemon.
+
+.option bt
+.index testing||addresses
+.index address||testing
+This option runs Exim in address testing mode, in which each argument is taken
+as an address to be tested for deliverability. The results are written to the
+standard output.
+If a test fails, and the caller is not an admin user, no details of the
+failure are output, because these might contain sensitive information such as
+usernames and passwords for database lookups.
+
+If no arguments are given, Exim runs in an interactive manner, prompting with a
+right angle bracket for addresses to be tested. Each address is handled as if
+it were the recipient address of a message (compare the \-bv-\ option). It is
+passed to the routers and the result is written to the standard output.
+However, any router that has \no@_address@_test\ set is bypassed. This can
+make \-bt-\ easier to use for genuine routing tests if your first router passes
+everything to a scanner program.
+
+.index return code||for \-bt-\
+The return code is 2 if any address failed outright; it is 1 if no address
+failed outright but at least one could not be resolved for some reason. Return
+code 0 is given only when all addresses succeed.
+
+\**Warning**\: \-bt-\ can only do relatively simple testing. If any of the
+routers in the configuration makes any tests on the sender address of a
+message,
+.index \-f-\ option||for address testing
+you can use the \-f-\ option to set an appropriate sender when running
+\-bt-\ tests. Without it, the sender is assumed to be the calling user at the
+default qualifying domain. However, if you have set up (for example) routers
+whose behaviour depends on the contents of an incoming message, you cannot test
+those conditions using \-bt-\. The \-N-\ option provides a possible way of
+doing such tests.
+
+.option bV
+.index version number of Exim, verifying
+This option causes Exim to write the current version number, compilation
+number, and compilation date of the \*exim*\ binary to the standard output.
+It also lists the DBM library this is being used, the optional modules (such as
+specific lookup types), the drivers that are included in the binary, and the
+name of the run time configuration file that is in use.
+
+.option bv
+.index verifying||address, using \-bv-\
+.index address||verification
+This option runs Exim in address verification mode, in which each argument is
+taken as an address to be verified. During normal operation, verification
+happens mostly as a consequence processing a \verify\ condition in an ACL (see
+chapter ~~CHAPACL). If you want to test an entire ACL, see the \-bh-\ option.
+
+If verification fails, and the caller is not an admin user, no details of the
+failure are output, because these might contain sensitive information such as
+usernames and passwords for database lookups.
+
+If no arguments are given, Exim runs in an interactive manner, prompting with a
+right angle bracket for addresses to be verified. Verification differs from
+address testing (the \-bt-\ option) in that routers that have \no@_verify\ set
+are skipped, and if the address is accepted by a router that has \fail@_verify\
+set, verification fails. The address is verified as a recipient if \-bv-\ is
+used; to test verification for a sender address, \-bvs-\ should be used.
+
+If the \-v-\ option is not set, the output consists of a single line for each
+address, stating whether it was verified or not, and giving a reason in the
+latter case. Otherwise, more details are given of how the address has been
+handled, and in the case of address redirection, all the generated addresses
+are also considered. Without \-v-\, generating more than one address by
+redirection causes verification to end sucessfully.
+
+.index return code||for \-bv-\
+The return code is 2 if any address failed outright; it is 1 if no address
+failed outright but at least one could not be resolved for some reason. Return
+code 0 is given only when all addresses succeed.
+
+If any of the routers in the configuration makes any tests on the sender
+address of a message, you should use the \-f-\ option to set an appropriate
+sender when running \-bv-\ tests. Without it, the sender is assumed to be the
+calling user at the default qualifying domain.
+
+.option bvs
+This option acts like \-bv-\, but verifies the address as a sender rather
+than a recipient address. This affects any rewriting and qualification that
+might happen.
+
+.option C #<<filelist>>
+.index configuration file||alternate
+.index \\CONFIGURE@_FILE\\
+.index alternate configuration file
+This option causes Exim to find the run time configuration file from the given
+list instead of from the list specified by the \\CONFIGURE@_FILE\\
+compile-time setting. Usually, the list will consist of just a single file
+name, but it can be a colon-separated list of names. In this case, the first
+file that exists is used. Failure to open an existing file stops Exim from
+proceeding any further along the list, and an error is generated.
+
+When this option is used by a caller other than root or the Exim user,
+and the list is different from the compiled-in list, Exim gives up
+its root privilege immediately, and runs with the real and effective uid and
+gid set to those of the caller.
+However, if \\ALT@_CONFIG@_ROOT@_ONLY\\ is defined in \(Local/Makefile)\, root
+privilege is retained for \-C-\ only if the caller of Exim is root.
+This option is not set by default.
+
+Setting \\ALT@_CONFIG@_ROOT@_ONLY\\ locks out the possibility of testing a
+configuration using \-C-\ right through message reception and delivery, even if
+the caller is root. The reception works, but by that time, Exim is running as
+the Exim user, so when it re-execs to regain privilege for the delivery, the
+use of \-C-\ causes privilege to be lost. However, root can test reception and
+delivery using two separate commands (one to put a message on the queue, using
+\-odq-\, and another to do the delivery, using \-M-\).
+
+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 \"/../"\.
+However, if the value of the \-C-\ option is identical to the value of
+\\CONFIGURE@_FILE\\ in \(Local/Makefile)\, Exim ignores \-C-\ and proceeds as
+usual. There is no default setting for \\ALT@_CONFIG@_PREFIX\\; when it is
+unset, any file name can be used with \-C-\.
+
+\\ALT@_CONFIG@_PREFIX\\ can be used to confine alternative configuration files
+to a directory to which only root has access. This prevents someone who has
+broken into the Exim account from running a privileged Exim with an arbitrary
+configuration file.
+
+The \-C-\ facility is useful for ensuring that configuration files are
+syntactically correct, but cannot be used for test deliveries, unless the
+caller is privileged, or unless it is an exotic configuration that does not
+require privilege. No check is made on the owner or group of the files
+specified by this option.
+
+.option D <<macro>>=<<value>>
+.index macro||setting on command line
+This option can be used to override macro definitions in the configuration file
+(see section ~~SECTmacrodefs). However, like \-C-\, if it is used by an
+unprivileged caller, it causes Exim to give up its root privilege.
+If \\DISABLE@_D@_OPTION\\ is defined in \(Local/Makefile)\, the use of \-D-\ is
+completely disabled, and its use causes an immediate error exit.
+
+The entire option (including equals sign if present) must all be within one
+command line item. \-D-\ can be used to set the value of a macro to the empty
+string, in which case the equals sign is optional. These two commands are
+synonymous:
+.display asis
+exim -DABC ...
+exim -DABC= ...
+.endd
+To include spaces in a macro definition item, quotes must be used. If you use
+quotes, spaces are permitted around the macro name and the equals sign. For
+example:
+.display asis
+exim '-D ABC = something' ...
+.endd
+\-D-\ may be repeated up to 10 times on a command line.
+
+.option d <<debug options>>
+.index debugging||list of selectors
+.index 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
+example, \-d+filter-\ adds filter debugging, whereas \-d-all+filter-\ selects
+only filter debugging. The available debugging categories are:
+.display flow
+.tabs 21
+.
+. The odd formatting of the lines below is deliberate. It does not affect the
+. SGCAL output, but by putting in the space it keeps things aligned in the man
+. page that is automatically generated from this text.
+.
+acl $t $rm{ACL interpretation}
+auth $t $rm{authenticators}
+deliver $t $rm{general delivery logic}
+dns $t $rm{DNS lookups (see also resolver)}
+dnsbl $t $rm{DNS black list (aka RBL) code}
+exec $t $rm{arguments for \execv@(@)\ calls}
+expand $t $rm{detailed debugging for string expansions}
+filter $t $rm{filter handling}
+hints@_lookup $t $rm{hints data lookups}
+host@_lookup $t $rm{all types of name-to-IP address handling}
+ident $t $rm{ident lookup}
+interface $t $rm{lists of local interfaces}
+lists $t $rm{matching things in lists}
+load $t $rm{system load checks}
+local@_scan $t $rm{can be used by \*local@_scan()*\ (see chapter ~~CHAPlocalscan)}
+lookup $t $rm{general lookup code and all lookups}
+memory $t $rm{memory handling}
+pid $t $rm{add pid to debug output lines}
+process@_info $t $rm{setting info for the process log}
+queue@_run $t $rm{queue runs}
+receive $t $rm{general message reception logic}
+resolver $t $rm{turn on the DNS resolver's debugging output}
+retry $t $rm{retry handling}
+rewrite $t $rm{address rewriting}
+route $t $rm{address routing}
+timestamp $t $rm{add timestamp to debug output lines}
+tls $t $rm{TLS logic}
+transport $t $rm{transports}
+uid $t $rm{changes of uid/gid and looking up uid/gid}
+verify $t $rm{address verification logic}
+
+all $t $rm{all of the above, and also \-v-\}
+.endd
+.em
+.index resolver, debugging output
+.index DNS||resolver, debugging output
+The \"resolver"\ option produces output only if the DNS resolver was compiled
+with \\DEBUG\\ enabled. This is not the case in some operating systems. Also,
+unfortunately, debugging output from the DNS resolver is written to stdout
+rather than stderr.
+.nem
+
+The default (\-d-\ with no argument) omits \"expand"\, \"filter"\,
+\"interface"\, \"load"\, \"memory"\, \"pid"\, \"resolver"\, and \"timestamp"\.
+However, the \"pid"\ selector is forced when debugging is turned on for a
+daemon, which then passes it on to any re-executed Exims. Exim also
+automatically adds the pid to debug lines when several remote deliveries are
+run in parallel.
+
+The \"timestamp"\ selector causes the current time to be inserted at the start
+of all debug output lines. This can be useful when trying to track down delays
+in processing.
+
+If the \debug@_print\ option is set in any driver, it produces output whenever
+any debugging is selected, or if \-v-\ is used.
+
+.option dropcr
+This is an obsolete option that is now a no-op. It used to affect the way Exim
+handled CR and LF characters in incoming messages. What happens now is
+described in section ~~SECTlineendings.
+
+
+.option E
+.index bounce message||generating
+This option specifies that an incoming message is a locally-generated delivery
+failure report. It is used internally by Exim when handling delivery failures
+and is not intended for external use. Its only effect is to stop Exim
+generating certain messages to the postmaster, as otherwise message cascades
+could occur in some situations. As part of the same option, a message id may
+follow the characters \-E-\. If it does, the log entry for the receipt of the
+new message contains the id, following `R=', as a cross-reference.
+
+.option e$it{x}
+There are a number of Sendmail options starting with \-oe-\ which seem to be
+called by various programs without the leading \o\ in the option. For example,
+the \vacation\ program uses \-eq-\. Exim treats all options of the form
+\-e$it{x}-\ as synonymous with the corresponding \-oe$it{x}-\ options.
+
+.option F #<<string>>
+.index sender||name
+.index name||of sender
+This option sets the sender's full name for use when a locally-generated
+message is being accepted. In the absence of this option, the user's \*gecos*\
+entry from the password data is used. As users are generally permitted to alter
+their \*gecos*\ entries, no security considerations are involved. White space
+between \-F-\ and the <<string>> is optional.
+
+.option f #<<address>>
+.index sender||address
+.index address||sender
+.index trusted user
+.index envelope sender
+.index user||trusted
+This option sets the address of the envelope sender of a locally-generated
+message (also known as the return path). The option can normally be used only
+by a trusted user, but \untrusted@_set@_sender\ can be set to allow untrusted
+users to use it. In the absence of \-f-\, or if the caller is not allowed to
+use it, the sender of a local message is set to the caller's login name at the
+default qualify domain.
+
+There is one exception to the restriction on the use of \-f-\: an empty sender
+can be specified by any user, to create a message that can never provoke a
+bounce. An empty sender can be specified either as an empty string, or as a
+pair of angle brackets with nothing between them, as in these examples of shell
+commands:
+.display asis
+exim -f '<>' user@domain
+exim -f "" user@domain
+.endd
+In addition, the use of \-f-\ is not restricted when testing a filter file with
+\-bf-\ or when testing or verifying addresses using the \-bt-\ or \-bv-\
+options.
+
+Allowing untrusted users to change the sender address does not of itself make
+it possible to send anonymous mail. Exim still checks that the ::From:: header
+refers to the local user, and if it does not, it adds a ::Sender:: header,
+though this can be overridden by setting \no@_local@_from@_check\.
+
+.index `From' line
+White space between \-f-\ and the <<address>> is optional
+(that is, they can be given as two arguments or one combined argument).
+The sender of a locally-generated message can also be set (when permitted) by
+an initial `From ' line in the message -- see the description of \-bm-\ above
+-- but if \-f-\ is also present, it overrides `From'.
+
+.option G
+.index Sendmail compatibility||\-G-\ option ignored
+This is a Sendmail option which is ignored by Exim.
+
+.option h #<<number>>
+.index Sendmail compatibility||\-h-\ option ignored
+This option is accepted for compatibility with Sendmail, but has no effect. (In
+Sendmail it overrides the `hop count' obtained by counting ::Received::
+headers.)
+
+.option i
+.index Solaris||\*mail*\ command
+.index dot||in incoming, non-SMTP message
+This option, which has the same effect as \-oi-\, specifies that a dot on a
+line by itself should not terminate an incoming, non-SMTP message. I can find
+no documentation for this option in Solaris 2.4 Sendmail, but the \*mailx*\
+command in Solaris 2.4 uses it. See also \-ti-\.
+
+.option M #<<message id>>#<<message id>> ...
+.index forcing delivery
+.index delivery||forcing attempt
+.index frozen messages||forcing delivery
+This option requests Exim to run a delivery attempt on each message in turn. If
+any of the messages are frozen, they are automatically thawed before the
+delivery attempt. The settings of \queue@_domains\, \queue@_smtp@_domains\, and
+\hold@_domains\ are ignored.
+.index hints database||overriding retry hints
+Retry hints for any of the addresses are
+overridden -- Exim tries to deliver even if 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).
+
+
+.option Mar #<<message id>>#<<address>>#<<address>> ...
+.index message||adding recipients
+.index recipient||adding
+This option requests Exim to add the addresses to the list of recipients of the
+message (`ar' for `add recipients'). The first argument must be a message id,
+and the remaining ones must be email addresses. However, if the message is
+active (in the middle of a delivery attempt), it is not altered. This option
+can be used only by an admin user.
+
+.index SMTP||passed connection
+.index SMTP||multiple deliveries
+.index multiple SMTP deliveries
+.option MC #<<transport>>#<<hostname>>#<<sequence number>>#<<message id>>
+This option is not intended for use by external callers. It is used internally
+by Exim to invoke another instance of itself to deliver a waiting message using
+an existing SMTP connection, which is passed as the standard input. Details are
+given in chapter ~~CHAPSMTP. This must be the final option, and the caller must
+be root or the Exim user in order to use it.
+
+.option MCA
+This option is not intended for use by external callers. It is used internally
+by Exim in conjunction with the \-MC-\ option. It signifies that the connection
+to the remote host has been authenticated.
+
+.option MCP
+This option is not intended for use by external callers. It is used internally
+by Exim in conjunction with the \-MC-\ option. It signifies that the server to
+which Exim is connected supports pipelining.
+
+.option MCQ #<<process id>> <<pipe fd>>
+This option is not intended for use by external callers. It is used internally
+by Exim in conjunction with the \-MC-\ option when the original delivery was
+started by a queue runner. It passes on the process id of the queue runner,
+together with the file descriptor number of an open pipe. Closure of the pipe
+signals the final completion of the sequence of processes that are passing
+messages through the same SMTP connection.
+
+.option MCS
+This option is not intended for use by external callers. It is used internally
+by Exim in conjunction with the \-MC-\ option, and passes on the fact that the
+SMTP \\SIZE\\ option should be used on messages delivered down the existing
+connection.
+
+.option MCT
+This option is not intended for use by external callers. It is used internally
+by Exim in conjunction with the \-MC-\ option, and passes on the fact that the
+host to which Exim is connected supports TLS encryption.
+
+.option Mc #<<message id>>#<<message id>> ...
+.index hints database||not overridden by \-Mc-\
+.index delivery||manually started, not forced
+This option requests Exim to run a delivery attempt on each message in turn,
+but unlike the \-M-\ option, it does check for retry hints, and respects any
+that are found. This option is not very useful to external callers. It is
+provided mainly for internal use by Exim when it needs to re-invoke itself in
+order to regain root privilege for a delivery (see chapter ~~CHAPsecurity).
+However, \-Mc-\ can be useful when testing, in order to run a delivery that
+respects retry times and other options such as \hold@_domains\ that are
+overridden when \-M-\ is used. Such a delivery does not count as a queue run.
+If you want to run a specific delivery as if in a queue run, you should use
+\-q-\ with a message id argument. A distinction between queue run deliveries
+and other deliveries is made in one or two places.
+
+.option Mes #<<message id>>#<<address>>
+.index message||changing sender
+.index sender||changing
+This option requests Exim to change the sender address in the message to the
+given address, which must be a fully qualified address or `<>' (`es' for `edit
+sender'). There must be exactly two arguments. The first argument must be a
+message id, and the second one an email address. However, if the message is
+active (in the middle of a delivery attempt), its status is not altered. This
+option can be used only by an admin user.
+
+.option Mf #<<message id>>#<<message id>> ...
+.index freezing messages
+.index message||manually freezing
+This option requests Exim to mark each listed message as `frozen'. This
+prevents any delivery attempts taking place until the message is `thawed',
+either manually or as a result of the \auto@_thaw\ configuration option.
+However, if any of the messages are active (in the middle of a delivery
+attempt), their status is not altered. This option can be used only by an admin
+user.
+
+.option Mg #<<message id>>#<<message id>> ...
+.index giving up on messages
+.index message||abandoning delivery attempts
+.index delivery||abandoning further attempts
+This option requests Exim to give up trying to deliver the listed messages,
+including any that are frozen. However, if any of the messages are active,
+their status is not altered.
+For non-bounce messages, a delivery error message is sent to the sender,
+containing the text `cancelled by administrator'. Bounce messages are just
+discarded.
+This option can be used only by an admin user.
+
+.option Mmad #<<message id>>#<<message id>> ...
+.index delivery||cancelling all
+This option requests Exim to mark all the recipient addresses in the messages
+as already delivered (`mad' for `mark all delivered'). However, if any message
+is active (in the middle of a delivery attempt), its status is not altered.
+This option can be used only by an admin user.
+
+.option Mmd #<<message id>>#<<address>>#<<address>> ...
+.index delivery||cancelling by address
+.index recipient||removing
+.index removing recipients
+This option requests Exim to mark the given addresses as already delivered
+(`md' for `mark delivered'). The first argument must be a message id, and the
+remaining ones must be email addresses. These are matched to recipient
+addresses in the message in a case-sensitive manner. If the message is active
+(in the middle of a delivery attempt), its status is not altered. This option
+can be used only by an admin user.
+
+.option Mrm #<<message id>>#<<message id>> ...
+.index removing messages
+.index abandoning mail
+.index message||manually discarding
+This option requests Exim to remove the given messages from the queue. No
+bounce messages are sent; each message is simply forgotten. However, if any of
+the messages are active, their status is not altered. This option can be used
+only by an admin user or by the user who originally caused the message to be
+placed on the queue.
+
+.option Mt #<<message id>>#<<message id>> ...
+.index thawing messages
+.index unfreezing messages
+.index frozen messages||thawing
+.index message||thawing frozen
+This option requests Exim to `thaw' any of the listed messages that are
+`frozen', so that delivery attempts can resume. However, if any of the messages
+are active, their status is not altered. This option can be used only by an
+admin user.
+
+.option Mvb #<<message id>>
+.index listing||message body
+.index message||listing body of
+This option causes the contents of the message body (-D) spool file to be
+written to the standard output. This option can be used only by an admin user.
+
+.option Mvh #<<message id>>
+.index listing||message headers
+.index header lines||listing
+.index message||listing header lines
+This option causes the contents of the message headers (-H) spool file to be
+written to the standard output. This option can be used only by an admin user.
+
+.option Mvl #<<message id>>
+.index listing||message log
+.index message||listing message log
+This option causes the contents of the message log spool file to be written to
+the standard output. This option can be used only by an admin user.
+
+.option m
+This is apparently a synonym for \-om-\ that is accepted by Sendmail, so Exim
+treats it that way too.
+
+.option N
+.index debugging||\-N-\ option
+.index debugging||suppressing delivery
+This is a debugging option that inhibits delivery of a message at the transport
+level. It implies \-v-\. Exim goes through many of the motions of delivery --
+it just doesn't actually transport the message, but instead behaves as if it
+had successfully done so. However, it does not make any updates to the retry
+database, and the log entries for deliveries are flagged with `$*$>' rather
+than `=>'.
+
+Because \-N-\ discards any message to which it applies, only root or the Exim
+user are allowed to use it with \-bd-\, \-q-\, \-R-\ or \-M-\. In other words,
+an ordinary user can use it only when supplying an incoming message to which it
+will apply. Although transportation never fails when \-N-\ is set, an address
+may be deferred because of a configuration problem on a transport, or a routing
+problem. Once \-N-\ has been used for a delivery attempt, it sticks to the
+message, and applies to any subsequent delivery attempts that may happen for
+that message.
+
+.option n
+.index Sendmail compatibility||\-n-\ option ignored
+This option is interpreted by Sendmail to mean `no aliasing'. It is ignored by
+Exim.
+
+.option O #<<data>>
+This option is interpreted by Sendmail to mean `set option`. It is ignored by
+Exim.
+
+.option oA #<<file name>>
+.index Sendmail compatibility||\-oA-\ option
+This option is used by Sendmail in conjunction with \-bi-\ to specify an
+alternative alias file name. Exim handles \-bi-\ differently; see the
+description above.
+
+.index SMTP||passed connection
+.option oB #<<n>>
+.index SMTP||multiple deliveries
+.index multiple SMTP deliveries
+This is a debugging option which limits the maximum number of messages that can
+be delivered down one SMTP connection, overriding the value set in any \%smtp%\
+transport. If <<n>> is omitted, the limit is set to 1.
+
+.option odb
+.index background delivery
+.index delivery||in the background
+This option applies to all modes in which Exim accepts incoming messages,
+including the listening daemon. It requests `background' delivery of such
+messages, which means that the accepting process automatically starts delivery
+process for each message received, but does not wait for the delivery process
+to complete. This is the default action if none of the \-od-\ options are
+present.
+
+If one of the queueing options in the configuration file
+(\queue@_only\ or \queue@_only@_file\, for example) is in effect, \-odb-\
+overrides it if \queue@_only@_override\ is set true, which is the default
+setting. If \queue@_only@_override\ is set false, \-odb-\ has no effect.
+
+.option odf
+.index foreground delivery
+.index delivery||in the foreground
+This option requests `foreground' (synchronous) delivery when Exim has accepted
+a locally-generated message. (For the daemon it is exactly the same as
+\-odb-\.) A delivery process is automatically started to deliver the
+message, and Exim waits for it to complete before proceeding.
+However, like \-odb-\, this option has no effect if \queue@_only@_override\ is
+false and one of the queueing options in the configuration file is in effect.
+
+.option odi
+This option is synonymous with \-odf-\. It is provided for compatibility with
+Sendmail.
+
+.option odq
+.index non-immediate delivery
+.index delivery||suppressing immediate
+.index queueing incoming messages
+This option applies to all modes in which Exim accepts incoming messages,
+including the listening daemon. It specifies that the accepting process should
+not automatically start a delivery process for each message received. Messages
+are placed on the queue, and remain there until a subsequent queue runner
+process encounters them.
+There are several configuration options (such as \queue@_only\) that can be
+used to queue incoming messages under certain conditions. This option overrides
+all of them and also \-odqs-\. It always forces queueing.
+
+.option odqs
+.index SMTP||delaying delivery
+This option is a hybrid between \-odb-\/\-odi-\ and \-odq-\.
+However, like \-odb-\ and \-odi-\, this option has no effect if
+\queue@_only@_override\ is false and one of the queueing options in the
+configuration file is in effect.
+
+When \-odqs-\ does operate, a delivery process is started for each incoming
+message, in the background by default, but in the foreground if \-odi-\ is also
+present.
+The recipient addresses are routed, and local deliveries are done in the normal
+way. However, if any SMTP deliveries are required, they are not done at this
+time, so the message remains on the queue until a subsequent queue runner
+process encounters it. Because routing was done, Exim knows which messages are
+waiting for which hosts, and so a number of messages for the same host can be
+sent in a single SMTP connection. The \queue@_smtp@_domains\ configuration
+option has the same effect for specific domains. See also the \-qq-\ option.
+
+.option oee
+.index error||reporting
+If an error is detected while a non-SMTP message is being received (for
+example, a malformed address), the error is reported to the sender in a mail
+message.
+.index return code||for \-oee-\
+Provided this error message is successfully sent, the Exim receiving process
+exits with a return code of zero. If not, the return code is 2 if the problem
+is that the original message has no recipients, or 1 any other error. This is
+the default \-oe$it{x}-\ option if Exim is called as \*rmail*\.
+
+.option oem
+.index error||reporting
+.index return code||for \-oem-\
+This is the same as \-oee-\, except that Exim always exits with a non-zero
+return code, whether or not the error message was successfully sent.
+This is the default \-oe$it{x}-\ option, unless Exim is called as \*rmail*\.
+
+.option oep
+.index error||reporting
+If an error is detected while a non-SMTP message is being received, the
+error is reported by writing a message to the standard error file (stderr).
+.index return code||for \-oep-\
+The return code is 1 for all errors.
+
+.option oeq
+.index error||reporting
+This option is supported for compatibility with Sendmail, but has the same
+effect as \-oep-\.
+
+.option oew
+.index error||reporting
+This option is supported for compatibility with Sendmail, but has the same
+effect as \-oem-\.
+
+.option oi
+.index dot||in incoming, non-SMTP message
+This option, which has the same effect as \-i-\, specifies that a dot on a line
+by itself should not terminate an incoming, non-SMTP message.
+.em
+Otherwise, a single dot does terminate, though Exim does no special processing
+for other lines that start with a dot.
+.nem
+This option is set by default if Exim is called as \*rmail*\. See also \-ti-\.
+
+.option oitrue
+This option is treated as synonymous with \-oi-\.
+
+.option oMa #<<host address>>
+.index sender||host address, specifying for local message
+A number of options starting with \-oM-\ can be used to set values associated
+with remote hosts on locally-submitted messages (that is, messages not received
+over TCP/IP). These options can be used by any caller in conjunction with the
+\-bh-\,
+\-be-\,
+\-bf-\, \-bF-\, \-bt-\, or \-bv-\ testing options. In other circumstances, they
+are ignored unless the caller is trusted.
+
+The \-oMa-\ option sets the sender host address. This may include a port number
+at the end, after a full stop (period). For example:
+.display asis
+exim -bs -oMa 10.9.8.7.1234
+.endd
+An alternative syntax is to enclose the IP address in square brackets, followed
+by a colon and the port number:
+.display asis
+exim -bs -oMa [10.9.8.7]:1234
+.endd
+The IP address is placed in the \$sender@_host@_address$\ variable, and the
+port, if present, in \$sender@_host@_port$\.
+
+.option oMaa #<<name>>
+.index authentication||name, specifying for local message
+See \-oMa-\ above for general remarks about the \-oM-\ options. The \-oMaa-\
+option sets the value of \$sender@_host@_authenticated$\ (the authenticator
+name). See chapter ~~CHAPSMTPAUTH for a discussion of SMTP authentication.
+
+.option oMai #<<string>>
+.index authentication||id, specifying for local message
+See \-oMa-\ above for general remarks about the \-oM-\ options. The \-oMai-\
+option sets the
+value of \$authenticated@_id$\ (the id that was authenticated).
+This overrides the default value (the caller's login id) for messages from
+local sources. See chapter ~~CHAPSMTPAUTH for a discussion of authenticated
+ids.
+
+.option oMas #<<address>>
+.index authentication||sender, specifying for local message
+See \-oMa-\ above for general remarks about the \-oM-\ options. The \-oMas-\
+option sets the authenticated sender value
+in \$authenticated@_sender$\.
+It overrides the sender address that is created from the caller's login id for
+messages from local sources. See chapter ~~CHAPSMTPAUTH for a discussion of
+authenticated senders.
+
+.option oMi #<<interface address>>
+.index interface||address, specifying for local message
+See \-oMa-\ above for general remarks about the \-oM-\ options. The \-oMi-\
+option sets the IP interface address value. A port number may be included,
+using the same syntax as for \-oMa-\.
+The interface address is placed in \$interface@_address$\ and the port number,
+if present, in \$interface@_port$\.
+
+.option oMr #<<protocol name>>
+.index protocol||incoming, specifying for local message
+See \-oMa-\ above for general remarks about the \-oM-\ options. The \-oMr-\
+option sets the received protocol value
+in \$received@_protocol$\.
+However, this applies only when \-bs-\ is not used. For interactive SMTP input,
+the protocol is determined by whether \\EHLO\\ or \\HELO\\ is used, and is
+always either `local-esmtp' or `local-smtp'. For \-bS-\ (batch SMTP) however,
+the protocol can be set by \-oMr-\.
+
+.option oMs #<<host name>>
+.index sender||host name, specifying for local message
+See \-oMa-\ above for general remarks about the \-oM-\ options. The \-oMs-\
+option sets the sender host name
+in \$sender@_host@_name$\. When this option is present, Exim does not attempt
+to look up a host name from an IP address; it uses the name it is given.
+
+.option oMt #<<ident string>>
+.index sender||ident string, specifying for local message
+See \-oMa-\ above for general remarks about the \-oM-\ options. The \-oMt-\
+option sets the sender ident value
+in \$sender@_ident$\.
+The default setting for local callers is the login id of the calling process.
+
+.option om
+.index Sendmail compatibility||\-om-\ option ignored
+In Sendmail, this option means `me too', indicating that the sender of a
+message should receive a copy of the message if the sender appears in an alias
+expansion. Exim always does this, so the option does nothing.
+
+.option oo
+.index Sendmail compatibility||\-oo-\ option ignored
+This option is ignored. In Sendmail it specifies `old style headers', whatever
+that means.
+
+.option oP #<<path>>
+.index pid (process id)||of daemon
+.index daemon||process id (pid)
+This option is useful only in conjunction with \-bd-\ or \-q-\ with a time
+value. The option specifies the file to which the process id of the daemon is
+written. When \-oX-\ is used with \-bd-\, or when \-q-\ with a time is used
+without \-bd-\, this is the only way of causing Exim to write a pid file,
+because in those cases, the normal pid file is not used.
+
+.option or #<<time>>
+.index timeout||for non-SMTP input
+This option sets a timeout value for incoming non-SMTP messages. If it is not
+set, Exim will wait forever for the standard input. The value can also be set
+by the \receive@_timeout\ option. The format used for specifying times is
+described in section ~~SECTtimeformat.
+
+.option os #<<time>>
+.index timeout||for SMTP input
+.index SMTP||timeout, input
+This option sets a timeout value for incoming SMTP messages. The timeout
+applies to each SMTP command and block of data. The value can also be set by
+the \smtp@_receive@_timeout\ option; it defaults to 5 minutes. The format used
+for specifying times is described in section ~~SECTtimeformat.
+
+.option ov
+This option has exactly the same effect as \-v-\.
+
+.option oX #<<number or string>>
+.index TCP/IP||setting listening ports
+.index TCP/IP||setting listening interfaces
+.index port||receiving TCP/IP
+This option is relevant only when the \-bd-\ (start listening daemon) option is
+also given. It controls which ports and interfaces the daemon uses. Details of
+the syntax, and how it interacts with configuration file options, are given in
+chapter ~~CHAPinterfaces. When \-oX-\ is used to start a daemon, no pid file is
+written unless \-oP-\ is also present to specify a pid file name.
+
+.option pd
+.index Perl||starting the interpreter
+This option applies when an embedded Perl interpreter is linked with Exim (see
+chapter ~~CHAPperl). It overrides the setting of the \perl@_at@_start\ option,
+forcing the starting of the interpreter to be delayed until it is needed.
+
+.option ps
+.index Perl||starting the interpreter
+This option applies when an embedded Perl interpreter is linked with Exim (see
+chapter ~~CHAPperl). It overrides the setting of the \perl@_at@_start\ option,
+forcing the starting of the interpreter to occur as soon as Exim is started.
+
+.em
+.option p<<rval>>:<<sval>>
+For compatibility with Sendmail, this option
+is equivalent to
+.display
+-oMr <<rval>> -oMs <<sval>>
+.endd
+It sets the incoming protocol and host name (for trusted callers). The
+host name and its colon can be omitted when only the protocol is to be set.
+Note the Exim already has two private options, \-pd-\ and \-ps-\, that refer to
+embedded Perl. It is therefore impossible to set a protocol value of \"p"\ or
+\"s"\ using this option (but that does not seem a real limitation).
+.nem
+
+.option q
+.index queue runner||starting manually
+This option is normally restricted to admin users. However, there is a
+configuration option called \prod@_requires@_admin\ which can be set false to
+relax this restriction (and also the same requirement for the \-M-\, \-R-\, and
+\-S-\ options).
+
+.index queue runner||description of operation
+The \-q-\ option starts one queue runner process. This scans the queue of
+waiting messages, and runs a delivery process for each one in turn. It waits
+for each delivery process to finish before starting the next one. A delivery
+process may not actually do any deliveries if the retry times for the addresses
+have not been reached. Use \-qf-\ (see below) if you want to override this.
+.index SMTP||passed connection
+.index SMTP||multiple deliveries
+.index multiple SMTP deliveries
+If the delivery process spawns other processes to deliver other messages down
+passed SMTP connections, the queue runner waits for these to finish before
+proceeding.
+
+When all the queued messages have been considered, the original queue runner
+process terminates. In other words, a single pass is made over the waiting
+mail, one message at a time. Use \-q-\ with a time (see below) if you want this
+to be repeated periodically.
+
+Exim processes the waiting messages in an unpredictable order. It isn't very
+random, but it is likely to be different each time, which is all that matters.
+If one particular message screws up a remote MTA, other messages to the same
+MTA have a chance of getting through if they get tried first.
+
+It is possible to cause the messages to be processed in lexical message id
+order, which is essentially the order in which they arrived, by setting the
+\queue@_run@_in@_order\ option, but this is not recommended for normal use.
+
+.option q <<qflags>>
+The \-q-\ option may be followed by one or more flag letters that change its
+behaviour. They are all optional, but if more than one is present, they must
+appear in the correct order. Each flag is described in a separate item below.
+
+.option qq...
+.index queue||double scanning
+.index queue||routing
+.index routing||whole queue before delivery
+An option starting with \-qq-\ requests a two-stage queue run. In the first
+stage, the queue is scanned as if the \queue@_smtp@_domains\ option matched
+every domain. Addresses are routed, local deliveries happen, but no remote
+transports are run.
+.index hints database||remembering routing
+The hints database that remembers which messages are
+waiting for specific hosts is updated, as if delivery to those hosts had been
+deferred. After this is complete, a second, normal queue scan happens, with
+routing and delivery taking place as normal. Messages that are routed to the
+same host should mostly be delivered down a single SMTP
+.index SMTP||passed connection
+.index SMTP||multiple deliveries
+.index multiple SMTP deliveries
+connection because of the hints that were set up during the first queue scan.
+This option may be useful for hosts that are connected to the Internet
+intermittently.
+
+.option q[q]i...
+.index queue||initial delivery
+If the \*i*\ flag is present, the queue runner runs delivery processes only for
+those messages that haven't previously been tried. (\*i*\ stands for `initial
+delivery'.) This can be helpful if you are putting messages on the queue using
+\-odq-\ and want a queue runner just to process the new messages.
+
+.option q[q][i]f...
+.index queue||forcing delivery
+.index delivery||forcing in queue run
+If one \*f*\ flag is present, a delivery attempt is forced for each non-frozen
+message, whereas without \f\ only those non-frozen addresses that have passed
+their retry times are tried.
+
+.option q[q][i]ff...
+.index frozen messages||forcing delivery
+If \*ff*\ is present, a delivery attempt is forced for every message, whether
+frozen or not.
+
+.option q[q][i][f[f]]l
+.index queue||local deliveries only
+The \*l*\ (the letter `ell') flag specifies that only local deliveries are to be
+done. If a message requires any remote deliveries, it remains on the queue for
+later delivery.
+
+.option q <<qflags>>#<<start id>>#<<end id>>
+.index queue||delivering specific messages
+When scanning the queue, Exim can be made to skip over messages whose ids are
+lexically less than a given value by following the \-q-\ option with a starting
+message id. For example:
+.display
+exim -q 0t5C6f-0000c8-00
+.endd
+Messages that arrived earlier than \"0t5C6f-0000c8-00"\ are not inspected. If a
+second message id is given, messages whose ids are lexically greater than it
+are also skipped. If the same id is given twice, for example,
+.display
+exim -q 0t5C6f-0000c8-00 0t5C6f-0000c8-00
+.endd
+just one delivery process is started, for that message. This differs from \-M-\
+in that retry data is respected, and it also differs from \-Mc-\ in that it
+counts as a delivery from a queue run. Note that the selection mechanism does
+not affect the order in which the messages are scanned. There are also other
+ways of selecting specific sets of messages for delivery in a queue run -- see
+\-R-\ and \-S-\.
+
+.option q <<qflags>><<time>>
+.index queue runner||starting periodically
+.index periodic queue running
+When a time value is present, the \-q-\ option causes Exim to run as a daemon,
+starting a queue runner process at intervals specified by the given time value
+(whose format is described in section ~~SECTtimeformat). This form of the \-q-\
+option is commonly combined with the \-bd-\ option, in which case a single
+daemon process handles both functions. A common way of starting up a combined
+daemon at system boot time is to use a command such as
+.display
+/usr/exim/bin/exim -bd -q30m
+.endd
+Such a daemon listens for incoming SMTP calls, and also starts a queue runner
+process every 30 minutes.
+
+When a daemon is started by \-q-\ with a time value, but without \-bd-\, no pid
+file is written unless one is explicitly requested by the \-oP-\ option.
+
+.option qR <<rsflags>>#<<string>>
+This option is synonymous with \-R-\. It is provided for Sendmail
+compatibility.
+
+.option qS <<rsflags>>#<<string>>
+This option is synonymous with \-S-\.
+
+.option R <<rsflags>>#<<string>>
+.index queue runner||for specific recipients
+.index delivery||to given domain
+.index domain||delivery to
+The <<rsflags>> may be empty, in which case the white space before the string
+is optional, unless the string is \*f*\, \*ff*\, \*r*\, \*rf*\, or \*rff*\,
+which are the possible values for <<rsflags>>. White space is required if
+<<rsflags>> is not empty.
+
+This option is similar to \-q-\ with no time value, that is, it causes Exim to
+perform a single queue run, except that, when scanning the messages on the
+queue, Exim processes only those that have at least one undelivered recipient
+address containing the given string, which is checked in a case-independent
+way. If the <<rsflags>> start with \*r*\, <<string>> is interpreted as a regular
+expression; otherwise it is a literal string.
+
+Once a message is selected, all its addresses are processed. For the first
+selected message, Exim overrides any retry information and forces a delivery
+attempt for each undelivered address. This means that if delivery of any
+address in the first message is successful, any existing retry information is
+deleted, and so delivery attempts for that address in subsequently selected
+messages (which are processed without forcing) will run. However, if delivery
+of any address does not succeed, the retry information is updated, and in
+subsequently selected messages, the failing address will be skipped.
+
+If the <<rsflags>> contain \*f*\ or \*ff*\, the delivery forcing applies to all
+selected messages, not just the first;
+.index frozen messages||forcing delivery
+frozen messages are included when \*ff*\ is present.
+
+The \-R-\ option makes it straightforward to initiate delivery of all messages
+to a given domain after a host has been down for some time. When the SMTP
+command \\ETRN\\ is accepted by its ACL (see chapter ~~CHAPACL), its default
+effect is to run Exim with the \-R-\ option, but it can be configured to run an
+arbitrary command instead.
+
+.option r
+This is a documented (for Sendmail) obsolete alternative name for \-f-\.
+
+.index delivery||from given sender
+.option S <<rsflags>>#<<string>>
+.index queue runner||for specific senders
+This option acts like \-R-\ except that it checks the string against each
+message's sender instead of against the recipients. If \-R-\ is also set, both
+conditions must be met for a message to be selected. If either of the options
+has \*f*\ or \*ff*\ in its flags, the associated action is taken.
+
+.em
+.option Tqt#<<times>>
+This an option that is exclusively for use by the Exim testing suite.
+It is not recognized when Exim is run normally. It allows for the setting up
+of explicit `queue times' so that various warning/retry features can be
+tested.
+.nem
+
+.option t
+.index recipient||extracting from header lines
+.index ::Bcc:: header line
+.index ::Cc:: header line
+.index ::To:: header line
+When Exim is receiving a locally-generated, non-SMTP message on its standard
+input, the \-t-\ option causes the recipients of the message to be obtained
+from the ::To::, ::Cc::, and ::Bcc:: header lines in the message instead of from
+the command arguments. The addresses are extracted before any rewriting takes
+place.
+
+.index Sendmail compatibility||\-t-\ option
+If the command has any arguments, they specify addresses to which the message
+is $it{not} to be delivered. That is, the argument addresses are removed from
+the recipients list obtained from the headers. This is compatible with Smail 3
+and in accordance with the documented behaviour of several versions of
+Sendmail, as described in man pages on a number of operating systems (e.g.
+Solaris 8, IRIX 6.5, HP-UX 11). However, some versions of Sendmail $it{add}
+argument addresses to those obtained from the headers, and the O'Reilly
+Sendmail book documents it that way. Exim can be made to add argument addresses
+instead of subtracting them by setting the option
+\extract__addresses__remove__arguments\ false.
+
+If a ::Bcc:: header line is present, it is removed from the message unless
+there is no ::To:: or ::Cc::, in which case a ::Bcc:: line with no data is
+created. This is necessary for conformity with the original RFC 822 standard;
+the requirement has been removed in RFC 2822, but that is still very new.
+
+.index \Resent@-\ header lines||with \-t-\
+If there are any \Resent@-\ header lines in the message, Exim extracts
+recipients from all ::Resent-To::, ::Resent-Cc::, and ::Resent-Bcc:: header
+lines instead of from ::To::, ::Cc::, and ::Bcc::. This is for compatibility
+with Sendmail and other MTAs. (Prior to release 4.20, Exim gave an error if
+\-t-\ was used in conjunction with \Resent@-\ header lines.)
+
+RFC 2822 talks about different sets of \Resent@-\ header lines (for when a
+message is resent several times). The RFC also specifies that they should be
+added at the front of the message, and separated by ::Received:: lines. It is
+not at all clear how \-t-\ should operate in the present of multiple sets,
+nor indeed exactly what constitutes a `set'.
+In practice, it seems that MUAs do not follow the RFC. The \Resent@-\ lines are
+often added at the end of the header, and if a message is resent more than
+once, it is common for the original set of \Resent@-\ headers to be renamed as
+\X-Resent@-\ when a new set is added. This removes any possible ambiguity.
+
+.option ti
+This option is exactly equivalent to \-t-\ \-i-\. It is provided for
+compatibility with Sendmail.
+
+.option tls-on-connect
+.index TLS||use without STARTTLS
+.index TLS||automatic start
+This option is available when Exim is compiled with TLS support. It makes it
+possible to support legacy clients that do not support the \\STARTTLS\\
+command, but instead expect to start up a TLS session as soon as a connection
+to the server is established. These clients use a special port (usually called
+the `ssmtp' port) instead of the normal SMTP port 25. The \-tls-on-connect-\
+option can be used to run Exim in this way from \*inetd*\, and it can also be
+used to run a special daemon that operates in this manner (use \-oX-\ to
+specify the port). However, although it is possible to run one daemon that
+listens on several ports, it is not possible to have some of them operate one
+way and some the other. With only a few clients that need the legacy support, a
+convenient approach is to use a daemon for normal SMTP (with or without
+\\STARTTLS\\) and \*inetd*\ with \-tls-on-connect-\ for the legacy clients.
+
+.option U
+.index Sendmail compatibility||\-U-\ option ignored
+Sendmail uses this option for `initial message submission', and its
+documentation states that in future releases, it may complain about
+syntactically invalid messages rather than fixing them when this flag is not
+set. Exim ignores this option.
+
+.option v
+This option causes Exim to write information to the standard error stream,
+describing what it is doing. In particular, it shows the log lines for
+receiving and delivering a message, and if an SMTP connection is made, the SMTP
+dialogue is shown. Some of the log lines shown may not actually be written to
+the log if the setting of \log@_selector\ discards them. Any relevant selectors
+are shown with each log line. If none are shown, the logging is unconditional.
+
+.option x
+AIX uses \-x-\ for a private purpose (`mail from a local mail program has
+National Language Support extended characters in the body of the mail item').
+It sets \-x-\ when calling the MTA from its \mail\ command. Exim ignores this
+option.
+
+.endoptions
+
+
+
+.
+.
+.
+.
+. ============================================================================
+.chapter The Exim run time configuration file
+.set runningfoot "configuration file"
+.rset CHAPconf ~~chapter
+
+.index run time configuration
+.index configuration file||general description
+.index \\CONFIGURE@_FILE\\
+Exim uses a single run time configuration file that is read whenever an Exim
+binary is executed. Note that in normal operation, this happens frequently,
+because Exim is designed to operate in a distributed manner, without central
+control.
+
+The name of the configuration file is compiled into the binary for security
+reasons, and is specified by the \\CONFIGURE@_FILE\\ compilation option. In
+most configurations, this specifies a single file. However, it is permitted to
+give a colon-separated list of file names, in which case Exim uses the first
+existing file in the list.
+
+.index \\EXIM@_USER\\
+.index \\EXIM@_GROUP\\
+.index configuration file||ownership
+.index ownership||configuration file
+The run time configuration file must be owned by root or by the user that
+is specified at compile time by the \\EXIM@_USER\\ option,
+.em
+or by the user that is specified at compile time by the \\CONFIGURE@_OWNER\\
+option (if set).
+.nem
+The configuration file must not be world-writeable or group-writeable, unless
+its group is the one specified at compile time by the \\EXIM@_GROUP\\ option.
+
+\**Warning**\: In a conventional configuration, where the Exim binary is setuid
+to root, anybody who is able to edit the run time configuration file has an
+easy way to run commands as root. If you make your mail administrators members
+of the Exim group, but do not trust them with root, make sure that the run time
+configuration is not group writeable.
+
+
+A default configuration file, which will work correctly in simple situations,
+is provided in the file \(src/configure.default)\.
+If \\CONFIGURE@_FILE\\ defines just one file name, the installation process
+copies the default configuration to a new file of that name if it did not
+previously exist. If \\CONFIGURE@_FILE\\ is a list, no default is automatically
+installed. Chapter ~~CHAPdefconfil is a `walk-through' discussion of the
+default configuration.
+
+.index configuration file||errors in
+.index error||in configuration file
+.index return code||for bad configuration
+If a syntax error is detected while reading the configuration file, Exim
+writes a message on the standard error, and exits with a non-zero return code.
+The message is also written to the panic log.
+
+
+.section Using a different configuration file
+.index configuration file||alternate
+A one-off alternate configuration can be specified by the \-C-\ command line
+option, which may specify a single file or a list of files. However, when \-C-\
+is used, Exim gives up its root privilege, unless called by root or the Exim
+user (or unless the argument for \-C-\ is identical to the built-in value from
+\\CONFIGURE@_FILE\\). \-C-\ is useful mainly for checking the syntax of
+configuration files before installing them. No owner or group checks are done
+on a configuration file specified by \-C-\.
+
+The privileged use of \-C-\ by the Exim user can be locked out by setting
+\\ALT@_CONFIG@_ROOT@_ONLY\\ in \(Local/Makefile)\ when building Exim. However,
+if you do this, you also lock out the possibility of testing a
+configuration using \-C-\ right through message reception and delivery, even if
+the caller is root. The reception works, but by that time, Exim is running as
+the Exim user, so when it re-execs to regain privilege for the delivery, the
+use of \-C-\ causes privilege to be lost. However, root can test reception and
+delivery using two separate commands (one to put a message on the queue, using
+\-odq-\, and another to do the delivery, using \-M-\).
+
+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
+name can be used with \-C-\.
+
+One-off changes to a configuration can be specified by the \-D-\ command line
+option, which defines and overrides values for macros used inside the
+configuration file. However, like \-C-\, the use of this option by a
+non-privileged user causes Exim to discard its root privilege.
+If \\DISABLE@_D@_OPTION\\ is defined in \(Local/Makefile)\, the use of \-D-\ is
+completely disabled, and its use causes an immediate error exit.
+
+Some sites may wish to use the same Exim binary on different machines that
+share a file system, but to use different configuration files on each machine.
+If \\CONFIGURE@_FILE@_USE@_NODE\\ is defined in \(Local/Makefile)\, Exim first
+looks for a file whose name is the configuration file name followed by a dot
+and the machine's node name, as obtained from the \*uname()*\ function. If this
+file does not exist, the standard name is tried. This processing occurs for
+each file name in the list given by \\CONFIGURE@_FILE\\ or \-C-\.
+
+In some esoteric situations different versions of Exim may be run under
+different effective uids and the \\CONFIGURE@_FILE@_USE@_EUID\\ is defined to
+help with this. See the comments in \(src/EDITME)\ for details.
+
+
+.section Configuration file format
+.rset SECTconffilfor "~~chapter.~~section"
+.index configuration file||format of
+.index format||configuration file
+Exim's configuration file is divided into a number of different parts. General
+option settings must always appear at the start of the file. The other parts
+are all optional, and may appear in any order. Each part other than the first
+is introduced by the word `begin' followed by the name of the part. The
+optional parts are:
+
+.numberpars $.
+\*ACL*\: Access control lists for controlling incoming SMTP mail.
+.nextp
+.index \\AUTH\\||configuration
+\*authenticators*\: Configuration settings for the authenticator drivers. These
+are concerned with the SMTP \\AUTH\\ command (see chapter ~~CHAPSMTPAUTH).
+.nextp
+\*routers*\: Configuration settings for the router drivers. Routers process
+addresses and determine how the message is to be delivered.
+.nextp
+\*transports*\: Configuration settings for the transport drivers. Transports
+define mechanisms for copying messages to destinations.
+.nextp
+\*retry*\: Retry rules, for use when a message cannot be immediately delivered.
+.nextp
+\*rewrite*\: Global address rewriting rules, for use when a message arrives and
+when new addresses are generated during delivery.
+.nextp
+\*local@_scan*\: Private options for the \*local@_scan()*\ function. If you
+want to use this feature, you must set
+.display asis
+LOCAL_SCAN_HAS_OPTIONS=yes
+.endd
+in \(Local/Makefile)\ before building Exim. Full details of the
+\*local@_scan()*\ facility are given in chapter ~~CHAPlocalscan.
+.endp
+Blank lines in the file, and lines starting with a @# character (ignoring
+leading white space) are treated as comments and are ignored. \**Note**\: a
+@# character other than at the beginning of a line is not treated specially,
+and does not introduce a comment.
+
+Any non-comment line can be continued by ending it with a backslash. 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 appear in the middle
+of a sequence of continuation lines.
+
+A convenient way to create a configuration file is to start from the
+default, which is supplied in \(src/configure.default)\, and add, delete, or
+change settings as required.
+
+The ACLs, retry rules, and rewriting rules have their own syntax which is
+described in chapters ~~CHAPACL, ~~CHAPretry, and ~~CHAPrewrite, respectively.
+The other parts of the configuration file have some syntactic items in common,
+and these are described below, from section ~~SECTcos onwards. Before that, the
+inclusion, macro, and conditional facilities are described.
+
+
+.section File inclusions in the configuration file
+.index inclusions in configuration file
+.index configuration file||including other files
+.index .include in configuration file
+.index .include@_if@_exists in configuration file
+You can include other files inside Exim's run time configuration file by
+using this syntax:
+.display
+@.include <<file name>>
+.endd
+or
+.display
+@.include@_if@_exists <<file name>>
+.endd
+on a line by itself. Double quotes round the file name are optional. If you use
+the first form, a configuration error occurs if the file does not exist; the
+second form does nothing for non-existent files.
+
+Includes may be nested to any depth, but remember that Exim reads its
+configuration file often, so it is a good idea to keep them to a minimum.
+If you change the contents of an included file, you must HUP the daemon,
+because an included file is read only when the configuration itself is read.
+
+The processing of inclusions happens early, at a physical line level, so, like
+comment lines, an inclusion can be used in the middle of an option setting,
+for example:
+.display asis
+hosts_lookup = a.b.c \
+ .include /some/file
+.endd
+Include processing happens
+after
+macro processing (see below). Its effect is to process the lines of the file as
+if they occurred inline where the inclusion appears.
+
+
+.section Macros in the configuration file
+.rset SECTmacrodefs "~~chapter.~~section"
+.index macro||description of
+.index configuration file||macros
+If a line in the main part of the configuration (that is, before the first
+`begin' line) begins with an upper case letter, it is taken as a macro
+definition, and must be of the form
+.display
+<<name>> = <<rest of line>>
+.endd
+The name must consist of letters, digits, and underscores, and need not all be
+in upper case, though that is recommended. The rest of the line, including any
+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.
+
+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
+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,
+define
+.display asis
+ABCD_XYZ = <<something>>
+ABCD = <<something else>>
+.endd
+but putting the definitions in the opposite order would provoke a configuration
+error.
+
+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.
+
+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:
+.display asis
+ALIAS_QUERY = select mailbox from user where \
+ login=${quote_mysql:$local_part};
+.endd
+This can then be used in a \%redirect%\ router setting like this:
+.display asis
+data = ${lookup mysql{ALIAS_QUERY}}
+.endd
+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.
+
+
+.section Conditional skips in the configuration file
+.index configuration file||conditional skips
+.index .ifdef
+You can use the directives \".ifdef"\, \".ifndef"\, \".elifdef"\,
+\".elifndef"\, \".else"\, and \".endif"\ to dynamically include or exclude
+portions of the configuration file. The processing happens whenever the file is
+read (that is, when an Exim binary starts to run).
+
+The implementation is very simple. Instances of the first four directives must
+be followed by text that includes the names of one or macros. The condition
+that is tested is whether or not any macro substitution has taken place in the
+line. Thus:
+.display
+@.ifdef AAA
+message@_size@_limit = 50M
+@.else
+message@_size@_limit = 100M
+@.endif
+.endd
+sets a message size limit of 50M if the macro \"AAA"\ is defined, and 100M
+otherwise. If there is more than one macro named on the line, the condition
+is true if any of them are defined. That is, it is an `or' condition. To
+obtain an `and' condition, you need to use nested \".ifdef"\s.
+
+Although you can use a macro expansion to generate one of these directives,
+it is not very useful, because the condition `there was a macro substitution
+in this line' will always be true.
+
+Text following \".else"\ and \".endif"\ is ignored, and can be used as comment
+to clarify complicated nestings.
+
+
+.section Common option syntax
+.rset SECTcos "~~chapter.~~section"
+.index common option syntax
+.index syntax of common options
+.index configuration file||common option syntax
+For the main set of options, driver options, and \*local@_scan()*\ options,
+each setting is on a line by itself, and starts with a name consisting of
+lower-case letters and underscores. Many options require a data value, and in
+these cases the name must be followed by an equals sign (with optional white
+space) and then the value. For example:
+.display asis
+qualify_domain = mydomain.example.com
+.endd
+Some option settings may contain sensitive data, for example, passwords for
+accessing databases. To stop non-admin users from using the \-bP-\ command line
+option to read these values, you can precede the option settings with the word
+`hide'. For example:
+.display asis
+hide mysql_servers = localhost/users/admin/secret-password
+.endd
+For non-admin users, such options are displayed like this:
+.display asis
+mysql_servers = <value not displayable>
+.endd
+If `hide' is used on a driver option, it hides the value of that option on all
+instances of the same driver.
+
+The following sections describe the syntax used for the different data types
+that are found in option settings.
+
+.section Boolean options
+.index format||boolean
+.index boolean configuration values
+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,
+the following two settings have exactly the same effect:
+.display asis
+queue_only
+queue_only = true
+.endd
+The following two lines also have the same (opposite) effect:
+.display asis
+no_queue_only
+queue_only = false
+.endd
+You can use whichever syntax you prefer.
+
+
+
+.section Integer values
+.index integer configuration values
+.index format||integer
+If an integer data item starts with the characters `0x', the remainder of it
+is interpreted as a hexadecimal number. Otherwise, it is treated as octal if it
+starts with the digit 0, and decimal if not. If an integer value is followed by
+the letter K, it is multiplied by 1024; if it is followed by the letter M, it
+is multiplied by 1024x1024.
+
+When the values of integer option settings are output, values which are an
+exact multiple of 1024 or 1024x1024 are
+sometimes, but not always,
+printed using the letters K and M. The printing style is independent of the
+actual input format that was used.
+
+.section Octal integer values
+.index integer format
+.index format||octal integer
+The value of an option specified as an octal integer is always interpreted in
+octal, whether or not it starts with the digit zero. Such options are always
+output in octal.
+
+
+.section Fixed point number values
+.index fixed point configuration values
+.index format||fixed point
+A fixed point number consists of a decimal integer, optionally followed by a
+decimal point and up to three further digits.
+
+
+.section Time interval values
+.index time interval||specifying in configuration
+.index format||time interval
+.rset SECTtimeformat "~~chapter.~~section"
+A time interval is specified as a sequence of numbers, each followed by one of
+the following letters, with no intervening white space:
+.display rm
+.tabs 5
+\s\ $t seconds
+\m\ $t minutes
+\h\ $t hours
+\d\ $t days
+\w\ $t weeks
+.endd
+For example, `3h50m' specifies 3 hours and 50 minutes. The values of time
+intervals are output in the same format.
+Exim does not restrict the values; it is perfectly acceptable, for example, to
+specify `90m' instead of `1h30m'.
+
+
+.section String values
+.index string||format of configuration values
+.index format||string
+.rset SECTstrings "~~chapter.~~section"
+If a string data item does not start with a double-quote character, it is taken
+as consisting of the remainder of the line plus any continuation lines,
+starting at the first character after any leading white space, with trailing
+white space characters removed, and with no interpretation of the characters in
+the string. Because Exim removes comment lines (those beginning with @#) at an
+early stage, they can appear in the middle of a multi-line string. The
+following settings are therefore equivalent:
+.display asis
+trusted_users = uucp:mail
+
+trusted_users = uucp:\
+ # This comment line is ignored
+ mail
+.endd
+.index string||quoted
+.index escape characters in quoted strings
+If a string does start with a double-quote, it must end with a closing
+double-quote, and any backslash characters other than those used for line
+continuation are interpreted as escape characters, as follows:
+.display
+.tabs 15
+@\@\ $t $rm{single backslash}
+@\n $t $rm{newline}
+@\r $t $rm{carriage return}
+@\t $t $rm{tab}
+@\<<octal digits>> $t $rm{up to 3 octal digits specify one character}
+@\x<<hex digits>> $t $rm{up to 2 hexadecimal digits specify one character}
+.endd
+If a backslash is followed by some other character, including a double-quote
+character, that character replaces the pair.
+
+Quoting is necessary only if you want to make use of the backslash escapes to
+insert special characters, or if you need to specify a value with leading or
+trailing spaces. These cases are rare, so quoting is almost never needed in
+current versions of Exim. In versions of Exim before 3.14, quoting was required
+in order to continue lines, so you may come across older configuration files
+and examples that apparently quote unnecessarily.
+
+.section Expanded strings
+.index string||expansion, definition of
+.index expansion||definition of
+Some strings in the configuration file are subjected to \*string expansion*\,
+by which means various parts of the string may be changed according to the
+circumstances (see chapter ~~CHAPexpand). The input syntax for such strings is
+as just described; in particular, the handling of backslashes in quoted strings
+is done as part of the input process, before expansion takes place. However,
+backslash is also an escape character for the expander, so any backslashes that
+are required for that reason must be doubled if they are within a quoted
+configuration string.
+
+.section User and group names
+.index user name||format of
+.index format||user name
+.index group||name format
+.index format||group name
+User and group names are specified as strings, using the syntax described
+above, but the strings are interpreted specially. A user or group name must
+either consist entirely of digits, or be a name that can be looked up using the
+\*getpwnam()*\ or \*getgrnam()*\ function, as appropriate.
+
+.section List construction
+.index list||syntax of in configuration
+.index format||list item in configuration
+.index string list, definition
+.rset SECTlistconstruct "~~chapter.~~section"
+The data for some configuration options is a colon-separated list of items.
+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.
+
+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
+~~SECTstrings above is an example. If a colon is actually needed in an item in
+a list, it must be entered as two colons. Leading and trailing white space on
+each item in a list is ignored. This makes it possible to include items that
+start with a colon, and in particular, certain forms of IPv6 address. For
+example, the list
+.display asis
+local_interfaces = 127.0.0.1 : ::::1
+.endd
+contains two IP addresses, the IPv4 address 127.0.0.1 and the IPv6 address
+@:@:1. IPv6 addresses are going to become more and more common as the new
+protocol gets more widely deployed.
+.index list||separator, changing
+.index IPv6||addresses in lists
+Doubling their colons is an unwelcome chore, so a mechanism was introduced to
+allow the separator character to be changed. If a list begins with a left angle
+bracket, followed by any punctuation character, that character is used instead
+of colon as the list separator. For example, the list above can be rewritten to
+use a semicolon separator like this:
+.display asis
+local_interfaces = <; 127.0.0.1 ; ::1
+.endd
+This facility applies to all lists, with the exception of the list in
+\log@_file@_path\. It is recommended that the use of non-colon separators be
+confined to circumstances where they really are needed.
+
+
+.section Format of driver configurations
+.rset SECTfordricon "~~chapter.~~section"
+.index drivers||configuration format
+There are separate parts in the configuration for defining routers, transports,
+and authenticators. In each part, you are defining a number of driver
+instances, each with its own set of options. Each driver instance is defined by
+a sequence of lines like this:
+.display
+<<instance name>>:
+ <<option>>
+ ...
+ <<option>>
+.endd
+In the following example, the instance name is \%localuser%\, and it is
+followed by three options settings:
+.display asis
+localuser:
+ driver = accept
+ check_local_user
+ transport = local_delivery
+.endd
+For each driver instance, you specify which Exim code module it uses -- by the
+setting of the \driver\ option -- and (optionally) some configuration settings.
+For example, in the case of transports, if you want a transport to deliver with
+SMTP you would use the \%smtp%\ driver; if you want to deliver to a local file
+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 order in which routers are defined is important, because addresses are
+passed to individual routers one by one, in order. The order in which
+transports are defined does not matter at all. The order in which
+authenticators are defined is used only when Exim, as a client, is searching
+them to find one that matches an authentication mechanism offered by the
+server.
+
+.index generic options
+.index options||generic, definition of
+Within a driver instance definition, there are two kinds of option:
+$it{generic} and $it{private}. The generic options are those that apply to all
+drivers of the same type (that is, all routers, all transports or all
+authenticators).
+The \driver\ option is a generic option that must appear in every definition.
+.index private options
+The private options are special for each driver, and none need appear, because
+they all have default values.
+
+The options may appear in any order, except that the \driver\ option must
+precede any private options, since these depend on the particular driver. For
+this reason, it is recommended that \driver\ always be the first option.
+
+Driver instance names, which are used for reference in log entries and
+elsewhere, can be any sequence of letters, digits, and underscores (starting
+with a letter) and must be unique among drivers of the same type. A router and
+a transport (for example) can each have the same name, but no two router
+instances can have the same name. The name of a driver instance should not be
+confused with the name of the underlying driver module. For example, the
+configuration lines:
+.display asis
+remote_smtp:
+ driver = smtp
+.endd
+create an instance of the \%smtp%\ transport driver whose name is
+\%remote@_smtp%\. The same driver code can be used more than once, with
+different instance names and different option settings each time. A second
+instance of the \%smtp%\ transport, with different options, might be defined
+thus:
+.display asis
+special_smtp:
+ driver = smtp
+ port = 1234
+ command_timeout = 10s
+.endd
+The names \%remote@_smtp%\ and \%special@_smtp%\ would be used to reference
+these transport instances from routers, and these names would appear in log
+lines.
+
+Comment lines may be present in the middle of driver specifications. The full
+list of option settings for any particular driver instance, including all the
+defaulted values, can be extracted by making use of the \-bP-\ command line
+option.
+
+
+
+
+
+
+.
+.
+.
+.
+. ============================================================================
+.chapter The default configuration file
+.set runningfoot "default configuration"
+.rset CHAPdefconfil "~~chapter"
+.index configuration file||default, `walk through'
+.index default||configuration file `walk through'
+The default configuration file supplied with Exim as \(src/configure.default)\
+is sufficient for a host with simple mail requirements. As an introduction to
+the way Exim is configured, this chapter `walks through' the default
+configuration, giving brief explanations of the settings. Detailed descriptions
+of the options are given in subsequent chapters. The default configuration file
+itself contains extensive comments about ways you might want to modify the
+initial settings. However, note that there are many options that are not
+mentioned at all in the default configuration.
+
+
+.section Main configuration settings
+The main (global) configuration option settings must always come first in the
+file. The first thing you'll see in the file, after some initial comments, is
+the line
+.display asis
+# primary_hostname =
+.endd
+This is a commented-out setting of the \primary@_hostname\ option. Exim needs
+to know the official, fully qualified name of your host, and this is where you
+can specify it. However, in most cases you do not need to set this option. When
+it is unset, Exim uses the \*uname()*\ system function to obtain the host name.
+
+The first three non-comment configuration lines are as follows:
+.display asis
+domainlist local_domains = @
+domainlist relay_to_domains =
+hostlist relay_from_hosts = 127.0.0.1
+.endd
+These are not, in fact, option settings. They are definitions of two named
+domain lists and one named host list. Exim allows you to give names to lists of
+domains, hosts, and email addresses, in order to make it easier to manage the
+configuration file (see section ~~SECTnamedlists).
+
+The first line defines a domain list called \*local@_domains*\; this is used
+later in the configuration to identify domains that are to be delivered
+on the local host.
+.index @@ in a domain list
+There is just one item in this list, the string `@@'. This is a special form of
+entry which means `the name of the local host'. Thus, if the local host is
+called \*a.host.example*\, mail to \*any.user@@a.host.example*\ is expected to
+be delivered locally. Because the local host's name is referenced indirectly,
+the same configuration file can be used on different hosts.
+
+The second line defines a domain list called \*relay@_to@_domains*\, but the
+list itself is empty. Later in the configuration we will come to the part that
+controls mail relaying through the local host; it allows relaying to any
+domains in this list. By default, therefore, no relaying on the basis of a mail
+domain is permitted.
+
+The third line defines a host list called \*relay@_from@_hosts*\. This list is
+used later in the configuration to permit relaying from any host or IP address
+that matches the list. The default contains just the IP address of the IPv4
+loopback interface, which means that processes on the local host are able to
+submit mail for relaying by sending it over TCP/IP to that interface. No other
+hosts are permitted to submit messages for relaying.
+
+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:
+.display asis
+acl_smtp_rcpt = acl_check_rcpt
+.endd
+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
+configuration does not provide an ACL to check recipients, no SMTP mail can be
+accepted.
+
+Two commented-out options settings are next:
+.display asis
+# qualify_domain =
+# qualify_recipient =
+.endd
+The first of these specifies a domain that Exim uses when it constructs a
+complete email address from a local login name. This is often needed when Exim
+receives a message from a local process. If you do not set \qualify@_domain\,
+the value of \primary@_hostname\ is used. If you set both of these options, you
+can have different qualification domains for sender and recipient addresses. If
+you set only the first one, its value is used in both cases.
+
+.index 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.
+.display asis
+# allow_domain_literals
+.endd
+.em
+The RFCs still require this form, but many people think that in the modern
+Internet it makes little sense to permit mail to be sent to specific hosts by
+quoting their IP addresses. This ancient format has been used by people who
+try to abuse hosts by using them for unwanted relaying. However, some
+people believe there are circumstances (for example, messages addressed to
+\*postmaster*\) where domain literals are still useful.
+.nem
+
+The next configuration line is a kind of trigger guard:
+.display asis
+never_users = root
+.endd
+It specifies that no delivery must ever be run as the root user. The normal
+convention is to set up \*root*\ as an alias for the system administrator. This
+setting is a guard against slips in the configuration.
+The list of users specified by \never@_users\ is not, however, the complete
+list; the build-time configuration in \(Local/Makefile)\ has an option called
+\\FIXED@_NEVER@_USERS\\ specifying a list that cannot be overridden. The
+contents of \never@_users\ are added to this list. By default
+\\FIXED@_NEVER@_USERS\\ also specifies root.
+
+When a remote host connects to Exim in order to send mail, the only information
+Exim has about the host's identity is its IP address. The next configuration
+line,
+.display asis
+host_lookup = *
+.endd
+specifies that Exim should do a reverse DNS lookup on all incoming connections,
+in order to get a host name. This improves the quality of the logging
+information, but if you feel it is too expensive, you can remove it entirely,
+or restrict the lookup to hosts on `nearby' networks.
+Note that it is not always possible to find a host name from an IP address,
+because not all DNS reverse zones are maintained, and sometimes DNS servers are
+unreachable.
+
+The next two lines are concerned with \*ident*\ callbacks, as defined by RFC
+1413 (hence their names):
+.display asis
+rfc1413_hosts = *
+rfc1413_query_timeout = 30s
+.endd
+These settings cause Exim to make ident callbacks for all incoming SMTP calls.
+You can limit the hosts to which these calls are made, or change the timeout
+that is used. If you set the timeout to zero, all ident calls are disabled.
+Although they are cheap and can provide useful information for tracing problem
+messages, some hosts and firewalls have problems with ident calls. This can
+result in a timeout instead of an immediate refused connection, leading to
+delays on starting up an incoming SMTP session.
+
+When Exim receives messages over SMTP connections, it expects all addresses to
+be fully qualified with a domain, as required by the SMTP definition. However,
+if you are running a server to which simple clients submit messages, you may
+find that they send unqualified addresses. The two commented-out options:
+.display asis
+# sender_unqualified_hosts =
+# recipient_unqualified_hosts =
+.endd
+show how you can specify hosts that are permitted to send unqualified sender
+and recipient addresses, respectively.
+
+The \percent@_hack@_domains\ option is also commented out:
+.display asis
+# percent_hack_domains =
+.endd
+It provides a list of domains for which the `percent hack' is to operate. This
+is an almost obsolete form of explicit email routing. If you do not know
+anything about it, you can safely ignore this topic.
+
+The last two settings in the main part of the default configuration are
+concerned with messages that have been `frozen' on Exim's queue. When a message
+is frozen, Exim no longer continues to try to deliver it. Freezing occurs when
+a bounce message encounters a permanent failure because the sender address of
+the original message that caused the bounce is invalid, so the bounce cannot be
+delivered. This is probably the most common case, but there are also other
+conditions that cause freezing, and frozen messages are not always bounce
+messages.
+.display asis
+ignore_bounce_errors_after = 2d
+timeout_frozen_after = 7d
+.endd
+The first of these options specifies that failing bounce messages are to be
+discarded after 2 days on the queue. The second specifies that any frozen
+message (whether a bounce message or not) is to be timed out (and discarded)
+after a week. In this configuration, the first setting ensures that no failing
+bounce message ever lasts a week.
+
+
+.section ACL configuration
+.index default||ACLs
+.index ~~ACL||default configuration
+In the default configuration, the ACL section follows the main configuration.
+It starts with the line
+.display asis
+begin acl
+.endd
+and it contains the definition of one ACL called \*acl@_check@_rcpt*\ that was
+referenced in the setting of \acl@_smtp@_rcpt\ above.
+.index \\RCPT\\||ACL for
+This 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
+result of the ACL processing.
+.display asis
+acl_check_rcpt:
+.endd
+This line, consisting of a name terminated by a colon, marks the start of the
+ACL, and names it.
+.display asis
+accept hosts = :
+.endd
+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.
+
+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.
+.display asis
+deny domains = +local_domains
+ local_parts = ^[.] : ^.*[@%!/|]
+
+deny domains = !+local_domains
+ local_parts = ^[./|] : ^.*[@%!] : ^.*/\\.\\./
+.endd
+These statements are concerned with local parts that contain any of the
+characters `@@', `%', `!', `/', `|', or dots in unusual places. Although these
+characters are entirely legal in local parts (in the case of `@@' and leading
+dots, only if correctly quoted), they do not commonly occur in Internet mail
+addresses.
+
+The first three have in the past been associated with explicitly routed
+addresses (percent is still sometimes used -- see the \percent@_hack@_domains\
+option). Addresses containing these characters are regularly tried by spammers
+in an attempt to bypass relaying restrictions, and also by open relay testing
+programs. Unless you really need them it is safest to reject these characters
+at this early stage. This configuration is heavy-handed in rejecting these
+characters for all messages it accepts from remote hosts. This is a deliberate
+policy of being as safe as possible.
+
+The first rule above is stricter, and is applied to messages that are addressed
+to one of the local domains handled by this host. This is implemented by the
+first condition, which restricts it to domains that are listed in the
+\*local@_domains*\ domain list. The `+' character is used to indicate a
+reference to a named list. In this configuration, there is just one domain in
+\*local@_domains*\, but in general there may be many.
+
+The second condition on the first statement uses two regular expressions to
+block local parts that begin with a dot or contain `@@', `%', `!', `/', or `|'.
+If you have local accounts that include these characters, you will have to
+modify this rule.
+
+Empty components (two dots in a row) are not valid in RFC 2822, but Exim
+allows them because they have been encountered in practice. (Consider local
+parts constructed as `first-initial.second-initial.family-name' when applied to
+someone like the author of Exim, who has no second initial.) However, a local
+part starting with a dot or containing `/../' can cause trouble if it is used
+as part of a file name (for example, for a mailing list). This is also true for
+local parts that contain slashes. A pipe symbol can also be troublesome if the
+local part is incorporated unthinkingly into a shell command line.
+
+The second rule above applies to all other domains, and is less strict. This
+allows your own users to send outgoing messages to sites that use slashes
+and vertical bars in their local parts. It blocks local parts that begin
+with a dot, slash, or vertical bar, but allows these characters within the
+local part. However, the sequence `/../' is barred. The use of `@@', `%', and
+`!' is blocked, as before. The motivation here is to prevent your users (or
+your users' viruses) from mounting certain kinds of attack on remote sites.
+
+.display asis
+accept local_parts = postmaster
+ domains = +local_domains
+.endd
+This statement, which has two conditions, accepts an incoming address if the
+local part is \*postmaster*\ and the domain is one of those listed in the
+\*local@_domains*\ domain list. The `+' character is used to indicate a
+reference to a named list. In this configuration, there is just one domain in
+\*local@_domains*\, but in general there may be many.
+
+The presence of this statement means that mail to postmaster is never blocked
+by any of the subsequent tests. This can be helpful while sorting out problems
+in cases where the subsequent tests are incorrectly denying access.
+.display asis
+require verify = sender
+.endd
+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.
+
+.display asis
+# deny message = rejected because $sender_host_address is \
+# in a black list at $dnslist_domain\n\
+# $dnslist_text
+# dnslists = black.list.example
+#
+# warn message = X-Warning: $sender_host_address is \
+# in a black list at $dnslist_domain
+# log_message = found in $dnslist_domain
+# dnslists = black.list.example
+.endd
+These commented-out lines are examples of how you could configure Exim to check
+sending hosts against a DNS black list. The first statement rejects messages
+from blacklisted hosts, whereas the second merely inserts a warning header
+line.
+
+.display asis
+accept domains = +local_domains
+ endpass
+ message = unknown user
+ verify = recipient
+.endd
+This statement accepts the incoming recipient address if its domain is one of
+the local domains, but only if the address can be verified. Verification of
+local addresses normally checks both the local part and the domain. The
+\endpass\ line needs some explanation: if the condition above \endpass\ fails,
+that is, if the address is not in a local domain, control is passed to the next
+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.
+.index customizing||ACL failure message
+The \message\ modifier provides a customized error message for the failure.
+.display asis
+accept domains = +relay_to_domains
+ endpass
+ message = unrouteable address
+ verify = recipient
+.endd
+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.
+.display asis
+accept hosts = +relay_from_hosts
+.endd
+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.
+.display asis
+accept authenticated = *
+.endd
+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.
+.display asis
+deny message = relay not permitted
+.endd
+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'.
+
+
+.section Router configuration
+.index default||routers
+.index routers||default
+The router configuration comes next in the default configuration, introduced
+by the line
+.display asis
+begin routers
+.endd
+Routers are the modules in Exim that make decisions about where to send
+messages. An address is passed to each router in turn, until it is either
+accepted, or failed. This means that the order in which you define the routers
+matters. Each router is fully described in its own chapter later in this
+manual. Here we give only brief overviews.
+
+.index domain literal||default router
+.display asis
+# domain_literal:
+# driver = ipliteral
+# domains = !+local_domains
+# transport = remote_smtp
+.endd
+This router is commented out because the majority of sites do not want to
+support domain literal addresses (those of the form \*user@@[10.9.8.7]*\). If
+you uncomment this router, you also need to uncomment the setting of
+\allow@_domain@_literals\ in the main part of the configuration.
+
+.display asis
+dnslookup:
+ driver = dnslookup
+ domains = ! +local_domains
+ transport = remote_smtp
+.newline
+ ignore_target_hosts = 0.0.0.0 : 127.0.0.0/8
+.newline
+ no_more
+.endd
+The first uncommented router handles addresses that do not involve any local
+domains. This is specified by the line
+.display asis
+domains = ! +local_domains
+.endd
+The \domains\ option lists the domains to which this router applies, but the
+exclamation mark is a negation sign, so the router is used only for domains
+that are not in the domain list called \*local@_domains*\ (which was defined at
+the start of the configuration). The plus sign before \*local@_domains*\
+indicates that it is referring to a named list. Addresses in other domains are
+passed on to the following routers.
+
+The name of the router driver is \%dnslookup%\,
+and is specified by the \driver\ option. Do not be confused by the fact that
+the name of this router instance is the same as the name of the driver. The
+instance name is arbitrary, but the name set in the \driver\ option must be one
+of the driver modules that is in the Exim binary.
+
+The \%dnslookup%\ router routes addresses by looking up their domains in the
+DNS in order to obtain a list of hosts to which the address is routed. If the
+router succeeds, the address is queued for the \%remote@_smtp%\ transport, as
+specified by the \transport\ option. If the router does not find the domain in
+the DNS, no further routers are tried because of the \no@_more\ setting, so the
+address fails and is bounced.
+
+The \ignore@_target@_hosts\ option specifies a list of IP addresses that are to
+be entirely ignored. This option is present because a number of cases have been
+encountered where MX records in the DNS point to host names
+whose IP addresses are 0.0.0.0 or are in the 127 subnet (typically 127.0.0.1).
+Completely ignoring these IP addresses causes Exim to fail to route the
+email address, so it bounces. Otherwise, Exim would log a routing problem, and
+continue to try to deliver the message periodically until the address timed
+out.
+.display asis
+system_aliases:
+ driver = redirect
+ allow_fail
+ allow_defer
+ data = ${lookup{$local_part}lsearch{/etc/aliases}}
+# user = exim
+ file_transport = address_file
+ pipe_transport = address_pipe
+.endd
+Control reaches this and subsequent routers only for addresses in the local
+domains. This router checks to see whether the local part is defined as an
+alias in the \(/etc/aliases)\ file, and if so, redirects it according to the
+data that it looks up from that file. If no data is found for the local part,
+the value of the \data\ option is empty, causing the address to be passed to
+the next router.
+
+\(/etc/aliases)\ is a conventional name for the system aliases file that is
+often used. That is why it is referenced by from the default configuration
+file. However, you can change this by setting \\SYSTEM@_ALIASES@_FILE\\ in
+\(Local/Makefile)\ before building Exim.
+
+.display asis
+userforward:
+ driver = redirect
+ check_local_user
+ file = $home/.forward
+ no_verify
+ no_expn
+ check_ancestor
+# allow_filter
+ file_transport = address_file
+ pipe_transport = address_pipe
+ reply_transport = address_reply
+.endd
+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).
+
+.index Sieve filter||enabling in default router
+Traditional \(.forward)\ files contain just a list of addresses, pipes, or
+files. Exim supports this by default. However, if \allow@_filter\ is set (it is
+commented out by default), the contents of the file are interpreted as a set of
+Exim or Sieve filtering instructions, provided the file begins with `@#Exim
+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.
+There are two reasons for doing this:
+.numberpars
+Whether or not a local user has a \(.forward)\ file is not really relevant when
+checking an address for validity; it makes sense not to waste resources doing
+unnecessary work.
+.nextp
+More importantly, when Exim is verifying addresses or handling an \\EXPN\\
+command during an SMTP session, it is running as the Exim user, not as root.
+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.
+.endp
+
+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
+forwarding -- see section ~~SECTredlocmai).
+
+The final three option settings specify the transports that are to be used when
+forwarding generates a direct delivery to a file, or to a pipe, or sets up an
+auto-reply, respectively. For example, if a \(.forward)\ file contains
+.display asis
+a.nother@elsewhere.example, /home/spqr/archive
+.endd
+the delivery to \(/home/spqr/archive)\ is done by running the \address@_file\
+transport.
+.display asis
+localuser:
+ driver = accept
+ check_local_user
+ transport = local_delivery
+.endd
+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
+the \%local@_delivery%\ transport. Otherwise, we have reached the end of the
+routers, so the address is bounced.
+
+
+.section Transport configuration
+.index default||transports
+.index transports||default
+Transports define mechanisms for actually delivering messages. They operate
+only when referenced from routers, so the order in which they are defined does
+not matter. The transports section of the configuration starts with
+.display asis
+begin transports
+.endd
+One remote transport and four local transports are defined.
+.display asis
+remote_smtp:
+ driver = smtp
+.endd
+This transport is used for delivering messages over SMTP connections. All its
+options are defaulted. The list of remote hosts comes from the router.
+.display asis
+local_delivery:
+ driver = appendfile
+ file = /var/mail/$local_part
+ delivery_date_add
+ envelope_to_add
+ return_path_add
+# group = mail
+# mode = 0660
+.endd
+This \%appendfile%\ transport is used for local delivery to user mailboxes in
+traditional BSD mailbox format. By default it runs under the uid and gid of the
+local user, which requires the sticky bit to be set on the \(/var/mail)\
+directory. Some systems use the alternative approach of running mail deliveries
+under a particular group instead of using the sticky bit. The commented options
+show how this can be done.
+
+Exim adds three headers to the message as it delivers it: ::Delivery-date::,
+::Envelope-to:: and ::Return-path::. This action is requested by the three
+similarly-named options above.
+.display asis
+address_pipe:
+ driver = pipe
+ return_output
+.endd
+This transport is used for handling deliveries to pipes that are generated by
+redirection (aliasing or users' \(.forward)\ files). The \return@_output\
+option specifies that any output generated by the pipe is to be returned to the
+sender.
+.display asis
+address_file:
+ driver = appendfile
+ delivery_date_add
+ envelope_to_add
+ return_path_add
+.endd
+This transport is used for handling deliveries to files that are generated by
+redirection. The name of the file is not specified in this instance of
+\%appendfile%\, because it comes from the \%redirect%\ router.
+.display asis
+address_reply:
+ driver = autoreply
+.endd
+This transport is used for handling automatic replies generated by users'
+filter files.
+
+
+.section Default retry rule
+.index retry||default rule
+.index default||retry rule
+The retry section of the configuration file contains rules which affect the way
+Exim retries deliveries that cannot be completed at the first attempt. It is
+introduced by the line
+.display asis
+begin retry
+.endd
+In the default configuration, there is just one rule, which applies to all
+errors:
+.display asis
+* * F,2h,15m; G,16h,1h,1.5; F,4d,6h
+.endd
+This causes any temporarily failing address to be retried every 15 minutes for
+2 hours, then at intervals starting at one hour and increasing by a factor of
+1.5 until 16 hours have passed, then every 6 hours up to 4 days. If an address
+is not delivered after 4 days of failure, it is bounced.
+
+
+.section Rewriting configuration
+The rewriting section of the configuration, introduced by
+.display asis
+begin rewrite
+.endd
+contains rules for rewriting addresses in messages as they arrive. There are no
+rewriting rules in the default configuration file.
+
+
+.section Authenticators configuration
+.index \\AUTH\\||configuration
+The authenticators section of the configuration, introduced by
+.display asis
+begin authenticators
+.endd
+defines mechanisms for the use of the SMTP \\AUTH\\ command. No authenticators
+are specified in the default configuration file.
+
+
+
+.
+.
+.
+.
+. ============================================================================
+.chapter Regular expressions
+.set runningfoot "regular expressions"
+.rset CHAPregexp ~~chapter
+
+.index regular expressions||library
+.index PCRE
+Exim supports the use of regular expressions in many of its options. It
+uses the PCRE regular expression library; this provides regular expression
+matching that is compatible with Perl 5. The syntax and semantics of
+regular expressions is discussed in many Perl reference books, and also in
+Jeffrey Friedl's
+.if ~~html
+[(A HREF="http://www.oreilly.com/catalog/regex/")]
+.fi
+$it{Mastering Regular Expressions}
+.if ~~html
+[(/A)]
+.fi
+(O'Reilly, ISBN 0-596-00289-0).
+
+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
+.if ~~html
+[(A HREF="http://www.uit.co.uk/exim-book/")]
+.fi
+Exim book.
+.if ~~html
+[(/A)]
+.fi
+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.
+
+.em
+In most cases, when a regular expression is required in an Exim configuration,
+it has to start with a circumflex, in order to distinguish it from plain text
+or an `ends with' wildcard. In this example of a configuration setting, the
+second item in the colon-separated list is a regular expression.
+.display asis
+domains = a.b.c : ^\\d{3} : *.y.z : ...
+.endd
+The doubling of the backslash is required because of string expansion that
+precedes interpretation -- see section ~~SECTlittext for more discussion of
+this issue, and a way of avoiding the need for doubling backslashes. The
+regular expression that is eventually used in this example contains just one
+backslash. The circumflex is included in the regular expression, and has the
+normal effect of `anchoring' it to the start of the string that is being
+matched.
+
+There are, however, two cases where a circumflex is not required for the
+recognition of a regular expression: these are the \match\ condition in a
+string expansion, and the \matches\ condition in an Exim filter file. In these
+cases, the relevant string is always treated as a regular expression; if it
+does not start with a circumflex, the expression is not anchored, and can match
+anywhere in the subject string.
+
+In all cases, if you want a regular expression to match at the end of a string,
+you must code the @$ metacharacter to indicate this. For example:
+.display asis
+domains = ^\\d{3}\\.example
+.endd
+matches the domain \*123.example*\, but it also matches \*123.example.com*\.
+You need to use:
+.display asis
+domains = ^\\d{3}\\.example\$
+.endd
+if you want \*example*\ to be the top-level domain. (The backslash before the
+@$ is another artefact of string expansion.)
+.nem
+
+
+.section Testing regular expressions
+.index testing||regular expressions
+.index regular expressions||testing
+.index \*pcretest*\
+A program called \*pcretest*\ forms part of the PCRE distribution and is built
+with PCRE during the process of building Exim. It is primarily intended for
+testing PCRE itself, but it can also be used for experimenting with regular
+expressions. After building Exim, the binary can be found in the build
+directory (it is not installed anywhere automatically). There is documentation
+of various options in \(doc/pcretest.txt)\, but for simple testing, none are
+needed. This is the output of a sample run of \*pcretest*\:
+.display
+ re> $cb{/^([^@@]+)@@.+@\.(ac|edu)@\.(?!kr)[a-z]@{2@}@$/}
+data> $cb{x@@y.ac.uk}
+ 0: x@@y.ac.uk
+ 1: x
+ 2: ac
+data> $cb{x@@y.ac.kr}
+No match
+data> $cb{x@@y.edu.com}
+No match
+data> $cb{x@@y.edu.co}
+ 0: x@@y.edu.co
+ 1: x
+ 2: edu
+.endd
+.if ~~sys.fancy
+Input typed by the user is shown in bold face.
+.fi
+After the `re>' prompt, a regular expression enclosed in delimiters is
+expected. If this compiles without error, `data>' prompts are given for strings
+against which the expression is matched. An empty data line causes a new
+regular expression to be read. If the match is successful, the captured
+substring values (that is, what would be in the variables \$0$\, \$1$\, \$2$\,
+etc.) are shown. The above example tests for an email address whose domain ends
+with either `ac' or `edu' followed by a two-character top-level domain that is
+not `kr'. The local part is captured in \$1$\ and the `ac' or `edu' in \$2$\.
+
+
+
+
+
+
+.
+.
+.
+.
+. ============================================================================
+.chapter File and database lookups
+.set runningfoot "file/database lookups"
+.rset CHAPfdlookup "~~chapter"
+.index file||lookup
+.index database lookups
+.index lookup||description of
+Exim can be configured to look up data in files or databases as it processes
+messages. Two different kinds of syntax are used:
+.numberpars
+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.
+.nextp
+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
+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.
+.endp
+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.
+Be careful to distinguish between the following two examples:
+.display asis
+domains = ${lookup{$sender_host_address}lsearch{/some/file}}
+domains = lsearch;/some/file
+.endd
+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:
+.display asis
+192.168.3.4: domain1 : domain2 : ...
+192.168.1.9: domain3 : domain4 : ...
+.endd
+Thus, the result of the expansion 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
+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:
+.display asis
+domain1:
+domain2:
+.endd
+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:
+.display asis
+192.168.5.6: lsearch;/another/file
+.endd
+If the value of \$sender@_host@_address$\ is 192.168.5.6, expansion of the
+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.
+
+.section Lookup types
+.index lookup||types of
+.index single-key lookup||definition of
+Two different styles of data lookup are implemented:
+.numberpars $.
+The \*single-key*\ style requires the specification of a file in which to look,
+and a single key to search for. The lookup type determines how the file is
+searched.
+.nextp
+.index 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.
+.endp
+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
+default settings in \(src/EDITME)\ are:
+.display asis
+LOOKUP_DBM=yes
+LOOKUP_LSEARCH=yes
+.endd
+which means that only linear searching and DBM lookups are included by default.
+For some types of lookup (e.g. SQL databases), you need to install appropriate
+libraries and header files before building Exim.
+
+
+
+.section Single-key lookup types
+.rset SECTsinglekeylookups "~~chapter.~~section"
+.index lookup||single-key types
+.index single-key lookup||list of types
+The following single-key lookup types are implemented:
+.numberpars $.
+.index cdb||description of
+.index lookup||cdb
+.index binary zero||in lookup key
+\%cdb%\: The given file is searched as a Constant DataBase file, using the key
+string without a terminating binary zero. The cdb format is designed for
+indexed files that are read frequently and never updated, except by total
+re-creation. As such, it is particulary suitable for large files containing
+aliases or other indexed data referenced by an MTA. Information about cdb can
+be found in several places:
+.display rm
+\?http://www.pobox.com/@~djb/cdb.html?\
+\?ftp://ftp.corpit.ru/pub/tinycdb/?\
+\?http://packages.debian.org/stable/utils/freecdb.html?\
+.endd
+A cdb distribution is not needed in order to build Exim with cdb support,
+because the code for reading cdb files is included directly in Exim itself.
+However, no means of building or testing cdb files is provided with Exim, so
+you need to obtain a cdb distribution in order to do this.
+.nextp
+.index DBM||lookup type
+.index lookup||dbm
+.index binary zero||in lookup key
+\%dbm%\: Calls to DBM library functions are used to extract data from the given
+DBM file by looking up the record with the given key. A terminating binary
+zero is included in the key that is passed to the DBM library. See section
+~~SECTdb for a discussion of DBM libraries.
+.index Berkeley DB library||file format
+For all versions of Berkeley DB, Exim uses the \\DB@_HASH\\ style of database
+when building DBM files using the \exim@_dbmbuild\ utility. However, when using
+Berkeley DB versions 3 or 4, it opens existing databases for reading with the
+\\DB@_UNKNOWN\\ option. This enables it to handle any of the types of database
+that the library supports, and can be useful for accessing DBM files created by
+other applications. (For earlier DB versions, \\DB@_HASH\\ is always used.)
+
+.nextp
+.index lookup||dbmnz
+.index lookup||dbm, terminating zero
+.index binary zero||in lookup key
+.index Courier
+.index \(/etc/userdbshadow.dat)\
+.index dmbnz lookup type
+\%dbmnz%\: This is the same as \%dbm%\, except that a terminating binary zero
+is not included in the key that is passed to the DBM library. You may need this
+if you want to look up data in files that are created by or shared with some
+other application that does not use terminating zeros. For example, you need to
+use \%dbmnz%\ rather than \%dbm%\ if you want to authenticate incoming SMTP
+calls using the passwords from Courier's \(/etc/userdbshadow.dat)\ file. Exim's
+utility program for creating DBM files (\*exim@_dbmbuild*\) includes the zeros
+by default, but has an option to omit them (see section ~~SECTdbmbuild).
+.nextp
+.index lookup||dsearch
+.index dsearch lookup type
+\%dsearch%\: The given file must be a directory; this is searched for a file
+whose name is the key. The key may not contain any forward slash characters.
+The result of a successful lookup is the name of the file. An example of how
+this lookup can be used to support virtual domains is given in section
+~~SECTvirtualdomains.
+.nextp
+.index lookup||iplsearch
+.index iplsearch lookup type
+.em
+\%iplsearch%\: The given file is a text file containing keys and data. A key is
+terminated by a colon or white space or the end of the line. The keys in the
+file must be IP addresses, or IP addresses with CIDR masks. Keys that involve
+IPv6 addresses must be enclosed in quotes to prevent the first internal colon
+being interpreted as a key terminator. For example:
+.display asis
+1.2.3.4: data for 1.2.3.4
+192.168.0.0/16 data for 192.168.0.0/16
+"abcd::cdab": data for abcd::cdab
+"abcd:abcd::/32" data for abcd:abcd::/32
+.endd
+The key for an \%iplsearch%\ lookup must be an IP address (without a mask). The
+file is searched linearly, using the CIDR masks where present, until a matching
+key is found. The first key that matches is used; there is no attempt to find a
+`best' match. Apart from the way the keys are matched, the processing for
+\%iplsearch%\ is the same as for \%lsearch%\.
+
+\**Warning 1**\: Unlike most other single-key lookup types, a file of data for
+\%iplsearch%\ can \*not*\ be turned into a DBM or cdb file, because those
+lookup types support only literal keys.
+
+\**Warning 2**\: In a host list, you must always use \%net-iplsearch%\ so that
+the implicit key is the host's IP address rather than its name (see section
+~~SECThoslispatsikey).
+.nem
+
+.nextp
+.index linear search
+.index lookup||lsearch
+.index lsearch lookup type
+\%lsearch%\: The given file is a text file that is searched linearly for a
+line beginning with the search key, terminated by a colon or white space or the
+end of the line. The first occurrence that is found in the file is used. White
+space between the key and the colon is permitted. The remainder of the line,
+with leading and trailing white space removed, is the data. This can be
+continued onto subsequent lines by starting them with any amount of white
+space, but only a single space character is included in the data at such a
+junction. If the data begins with a colon, the key must be terminated by a
+colon, for example:
+.display
+baduser: :fail:
+.endd
+Empty lines and lines beginning with @# are ignored, even if they occur in the
+middle of an item. This is the traditional textual format of alias files. Note
+that the keys in an \%lsearch%\ file are literal strings. There is no
+wildcarding of any kind.
+
+.index lookup||lsearch, colons in keys
+In most \%lsearch%\ files, keys are not required to contain colons
+.em
+or @# characters, or
+.nem
+whitespace. 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 quoted keys (exactly as
+for unquoted keys). There is no special handling of quotes for the data part of
+an \%lsearch%\ line.
+.nextp
+.index NIS lookup type
+.index lookup||NIS
+.index binary zero||in lookup key
+\%nis%\: The given file is the name of a NIS map, and a NIS lookup is done with
+the given key, without a terminating binary zero. There is a variant called
+\%nis0%\ which does include the terminating binary zero in the key. This is
+reportedly needed for Sun-style alias files. Exim does not recognize NIS
+aliases; the full map names must be used.
+.nextp
+.index wildlsearch lookup type
+.index lookup||wildlsearch
+.index nwildlsearch lookup type
+.index lookup||nwildlsearch
+\%wildlsearch%\ or \%nwildlsearch%\: These search a file linearly, like
+\%lsearch%\, but instead of being interpreted as a literal string, each key may
+be wildcarded. The difference between these two lookup types is that for
+\%wildlsearch%\, each key in the file is string-expanded before being used,
+whereas for \%nwildlsearch%\, no expansion takes place.
+
+Like \%lsearch%\, the testing is done case-insensitively. The following forms
+of wildcard are recognized:
+.numberpars "$*$"
+The string may begin with an asterisk to mean `begins with'. For example:
+.display asis
+*.a.b.c data for anything.a.b.c
+*fish data for anythingfish
+.endd
+.nextp
+The string may begin with a circumflex to indicate a regular expression. For
+example, for \%wildlsearch%\:
+.display asis
+^\N\d+\.a\.b\N data for <digits>.a.b
+.endd
+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:
+.display asis
+^\d+\.a\.b data for <digits>.a.b
+.endd
+
+If the regular expression contains white space or colon characters, you must
+either quote it (see \%lsearch%\ above), or represent these characters in other
+ways. For example, \"@\s"\ can be used for white space and \"@\x3A"\ for a
+colon. This may be easier than quoting, because if you quote, you have to
+escape all the backslashes inside the quotes.
+.nextp
+Although I cannot see it being of much use, the general matching function
+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:
+.display asis
+cdb;/some/file data for keys that match the file
+.endd
+The data that is obtained from the nested lookup is discarded.
+.endp
+Keys that do not match any of these patterns are interpreted literally. The
+continuation rules for the data are the same as for \%lsearch%\, and keys may
+be followed by optional colons.
+
+\**Warning**\: Unlike most other single-key lookup types, a file of data for
+\%(n)wildlsearch%\ can \*not*\ be turned into a DBM or cdb file, because those
+lookup types support only literal keys.
+.endp
+
+.section Query-style lookup types
+.index lookup||query-style types
+.index query-style lookup||list of types
+The supported query-style lookup types are listed below. Further details about
+many of them are given in later sections.
+.numberpars $.
+.index DNS||as a lookup type
+.index lookup||DNS
+\%dnsdb%\: This does a DNS search for a record whose domain name is the supplied
+query. The resulting data is the contents of the record. See section
+~~SECTdnsdb.
+.nextp
+.index Interbase lookup type
+.index lookup||Interbase
+\%ibase%\: This does a lookup in an Interbase database.
+.nextp
+.index LDAP||lookup type
+.index lookup||LDAP
+\%ldap%\: This does an LDAP lookup using a query in the form of a URL, and
+returns attributes from a single entry. There is a variant called \%ldapm%\
+that permits values from multiple entries to be returned. A third variant
+called \%ldapdn%\ returns the Distinguished Name of a single entry instead of
+any attribute values. See section ~~SECTldap.
+.nextp
+.index MySQL||lookup type
+.index lookup||MySQL
+\%mysql%\: The format of the query is an SQL statement that is passed to a MySQL
+database. See section ~~SECTsql.
+.nextp
+.index NIS@+ lookup type
+.index lookup||NIS+
+\%nisplus%\: This does a NIS+ lookup using a query that can specify the name of
+the field to be returned. See section ~~SECTnisplus.
+.nextp
+.index Oracle||lookup type
+.index lookup||Oracle
+\%oracle%\: The format of the query is an SQL statement that is passed to an
+Oracle database. See section ~~SECTsql.
+.nextp
+.index lookup||passwd
+.index passwd lookup type
+\%passwd%\ is a query-style lookup with queries that are just user names. The
+lookup calls \*getpwnam()*\ to interrogate the system password data, and on
+success, the result string is the same as you would get from an \%lsearch%\
+lookup on a traditional \(/etc/passwd file)\, though with \"*"\ for the
+password value. For example:
+.display asis
+*:42:42:King Rat:/home/kr:/bin/bash
+.endd
+.nextp
+.index PostgreSQL lookup type
+.index lookup||PostgreSQL
+\%pgsql%\: The format of the query is an SQL statement that is passed to a
+PostgreSQL database. See section ~~SECTsql.
+.nextp
+\%testdb%\: This is a lookup type that is used for testing Exim. It is
+not likely to be useful in normal operation.
+.nextp
+.index whoson lookup type
+.index lookup||whoson
+\%whoson%\: \*Whoson*\ (\?http://whoson.sourceforge.net?\) is a proposed
+Internet protocol that allows Internet server programs to check whether a
+particular (dynamically allocated) IP address is currently allocated to a known
+(trusted) user and, optionally, to obtain the identity of the said user. In
+Exim, this can be used to implement `POP before SMTP' checking using ACL
+statements such as
+.display asis
+require condition = \
+ ${lookup whoson {$sender_host_address}{yes}{no}}
+.endd
+The query consists of a single IP address. The value returned is the name of
+the authenticated user.
+.endp
+
+.section Temporary errors in lookups
+.index 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
+reason, it is not advisable to use a lookup that might do this for critical
+options such as a list of local domains.
+
+When a lookup cannot be completed in a router or transport, delivery
+of the message (to the relevant address) is deferred, as for any other
+temporary error. In other circumstances Exim may assume the lookup has failed,
+or may give up altogether.
+
+
+.section Default values in single-key lookups
+.rset SECTdefaultvaluelookups "~~chapter.~~section"
+.index wildcard lookups
+.index lookup||default values
+.index lookup||wildcard
+.index lookup||$*$ added to type
+.index default||in single-key lookups
+In this context, a `default value' is a value specified by the administrator
+that is to be used if a lookup fails.
+
+If `$*$' is added to a single-key lookup type (for example, \lsearch$*$\) and
+the initial lookup fails, the key `$*$' is looked up in the file to provide
+a default value. See also the section on partial matching below.
+
+.index @*@@ with single-key lookup
+.index lookup||$*$@@ added to type
+.index alias file||per-domain default
+Alternatively, if `$*$@@' is added to a single-key lookup type (for example
+\dbm$*$@@\) then, if the initial lookup fails and the key contains an @@
+character, a second lookup is done with everything before the last @@ replaced
+by $*$. This makes it possible to provide per-domain defaults in alias files
+that include the domains in the keys. If the second lookup fails (or doesn't
+take place because there is no @@ in the key), `$*$' is looked up.
+For example, a \%redirect%\ router might contain:
+.display asis
+data = ${lookup{$local_part@$domain}lsearch*@{/etc/mixed-aliases}}
+.endd
+Suppose the address that is being processed is \*jane@@eyre.example*\. Exim
+looks up these keys, in this order:
+.display asis
+jane@eyre.example
+*@eyre.example
+*
+.endd
+The data is taken from whichever key it finds first. \**Note**\: in an
+\%lsearch%\ file, this does not mean the first of these keys in the file. A
+complete scan is done for each key, and only if it is not found at all does
+Exim move on to try the next key.
+
+
+.section Partial matching in single-key lookups
+.rset SECTpartiallookup "~~chapter.~~section"
+.index partial matching
+.index wildcard lookups
+.index lookup||partial matching
+.index lookup||wildcard
+.index asterisk||in search type
+The normal operation of a single-key lookup is to search the file for an exact
+match with the given key. However, in a number of situations where domains are
+being looked up, it is useful to be able to do partial matching. In this case,
+information in the file that has a key starting with `$*$.' is matched by any
+domain that ends with the components that follow the full stop. For example, if
+a key in a DBM file is
+.display
+*.dates.fict.example
+.endd
+then when partial matching is enabled this is matched by (amongst others)
+\*2001.dates.fict.example*\ and \*1984.dates.fict.example*\. It is also matched
+by \*dates.fict.example*\, if that does not appear as a separate key in the
+file.
+
+\**Note**\: Partial matching is not available for query-style lookups. It is
+also not available for any lookup items in address lists (see section
+~~SECTaddresslist).
+
+Partial matching is implemented by doing a series of separate lookups using
+keys constructed by modifying the original subject key. This means that it can
+be used with any of the single-key lookup types, provided that
+partial matching keys
+beginning with a special prefix (default `$*$.') are included in the data file.
+Keys in the file that do not begin with the prefix are matched only by
+unmodified subject keys when partial matching is in use.
+
+Partial matching is requested by adding the string `partial-' to the front of
+the name of a single-key lookup type, for example, \partial-dbm\. When this is
+done, the subject key is first looked up unmodified; if that fails, `$*$.'
+is added at the start of the subject key, and it is looked up again. If that
+fails, further lookups are tried with dot-separated components removed
+from the start of the subject key, one-by-one, and `$*$.' added on the front of
+what remains.
+
+A minimum number of two non-$*$ components are required. This can be adjusted
+by including a number before the hyphen in the search type. For example,
+\partial3-lsearch\ specifies a minimum of three non-$*$ components in the
+modified keys. Omitting the number is equivalent to `partial2-'. If the subject
+key is \*2250.dates.fict.example*\ then the following keys are looked up when
+the minimum number of non-$*$ components is two:
+.display asis
+2250.dates.fict.example
+*.2250.dates.fict.example
+*.dates.fict.example
+*.fict.example
+.endd
+As soon as one key in the sequence is successfully looked up, the lookup
+finishes.
+
+.index lookup||partial matching, changing prefix
+.index prefix||for partial matching
+The use of `$*$.' as the partial matching prefix is a default that can be
+changed. The motivation for this feature is to allow Exim to operate with file
+formats that are used by other MTAs. A different prefix can be supplied in
+parentheses instead of the hyphen after `partial'. For example:
+.display asis
+domains = partial(.)lsearch;/some/file
+.endd
+In this example, if the domain is \*a.b.c*\, the sequence of lookups is
+\"a.b.c"\, \".a.b.c"\, and \".b.c"\ (the default minimum of 2 non-wild
+components is unchanged). The prefix may consist of any punctuation characters
+other than a closing parenthesis. It may be empty, for example:
+.display asis
+domains = partial1()cdb;/some/file
+.endd
+For this example, if the domain is \*a.b.c*\, the sequence of lookups is
+\"a.b.c"\, \"b.c"\, and \"c"\.
+
+If `partial0' is specified, what happens at the end (when the lookup with just
+one non-wild component has failed, and the original key is shortened right down
+to the null string) depends on the prefix:
+.numberpars $.
+If the prefix has zero length, the whole lookup fails.
+.nextp
+If the prefix has length 1, a lookup for just the prefix is done. For
+example, the final lookup for `partial0(.)' is for \"."\ alone.
+.nextp
+Otherwise, if the prefix ends in a dot, the dot is removed, and the
+remainder is looked up. With the default prefix, therefore, the final lookup is
+for `$*$' on its own.
+.nextp
+Otherwise, the whole prefix is looked up.
+.endp
+
+If the search type ends in `$*$' or `$*$@@' (see section
+~~SECTdefaultvaluelookups above), the search for an ultimate default that this
+implies happens after all partial lookups have failed. If `partial0' is
+specified, adding `$*$' to the search type has no effect with the default
+prefix, because the `$*$' key is already included in the sequence of partial
+lookups. However, there might be a use for lookup types such as
+`partial0(.)lsearch$*$'.
+
+The use of `$*$' in lookup partial matching differs from its use as a wildcard
+in domain lists and the like. Partial matching works only in terms of
+dot-separated components; a key such as \"*fict.example"\
+in a database file is useless, because the asterisk in a partial matching
+subject key is always followed by a dot.
+
+
+
+.section Lookup caching
+.index lookup||caching
+.index caching||lookup data
+An Exim process
+caches the most recent lookup result on a per-file basis for single-key
+lookup types, and keeps the relevant files open. In some types of configuration
+this can lead to many files being kept open for messages with many recipients.
+To avoid hitting the operating system limit on the number of simultaneously
+open files, Exim closes the least recently used file when it needs to open more
+files than its own internal limit, which can be changed via the
+\lookup@_open@_max\ option.
+
+For query-style lookups, a single data cache per lookup type is kept. The files
+are closed and the caches flushed at strategic points during delivery -- for
+example, after all routing is complete.
+
+
+.section Quoting lookup data
+.index lookup||quoting
+.index quoting||in lookups
+When data from an incoming message is included in a query-style lookup, there
+is the possibility of special characters in the data messing up the syntax of
+the query. For example, a NIS+ query that contains
+.display asis
+[name=$local_part]
+.endd
+will be broken if the local part happens to contain a closing square bracket.
+For NIS+, data can be enclosed in double quotes like this:
+.display asis
+[name="$local_part"]
+.endd
+but this still leaves the problem of a double quote in the data. The rule for
+NIS+ is that double quotes must be doubled. Other lookup types have different
+rules, and to cope with the differing requirements, an expansion operator
+of the following form is provided:
+.display
+@$@{quote@_<<lookup-type>>:<<string>>@}
+.endd
+For example, the safest way to write the NIS+ query is
+.display asis
+[name="${quote_nisplus:$local_part}"]
+.endd
+See chapter ~~CHAPexpand for full coverage of string expansions. The quote
+operator can be used for all lookup types, but has no effect for single-key
+lookups, since no quoting is ever needed in their key strings.
+
+
+
+.section More about dnsdb
+.rset SECTdnsdb "~~chapter.~~section"
+.index dnsdb lookup
+.index lookup||dnsdb
+.index DNS||as a lookup type
+The \%dnsdb%\ lookup type uses the DNS as its database. A query consists of a
+record type and a domain name, separated by an equals sign. For example, an
+expansion string could contain:
+.display asis
+${lookup dnsdb{mx=a.b.example}{$value}fail}
+.endd
+.em
+The supported record types are A, CNAME, MX, NS, PTR, SRV, and TXT,
+.nem
+and, when Exim is compiled with IPv6 support, AAAA (and A6 if that is also
+configured). If no type is given, TXT is assumed. When the type is PTR, the
+address should be given as normal; it is converted to the necessary inverted
+format internally. For example:
+.display asis
+${lookup dnsdb{ptr=192.168.4.5}{$value}fail}
+.endd
+
+.index MX record||in \%dnsdb%\ lookup
+For MX records, both the preference value and the host name are returned,
+separated by a space.
+.em
+.index SRV record||in \%dnsdb%\ lookup
+For SRV records, the priority, weight, port, and host name are returned,
+separated by spaces. For any record type,
+.nem
+if multiple records are found (or, for A6 lookups, if a single record leads to
+multiple addresses), the data is returned as a concatenation, separated by
+newlines. The order, of course, depends on the DNS resolver.
+
+
+
+
+.section More about LDAP
+.rset SECTldap "~~chapter.~~section"
+.index LDAP lookup
+.index lookup||LDAP
+.index Solaris||LDAP
+The original LDAP implementation came from the University of Michigan; this has
+become `Open LDAP', and there are now two different releases. Another
+implementation comes from Netscape, and Solaris 7 and subsequent releases
+contain inbuilt LDAP support. Unfortunately, though these are all compatible at
+the lookup function level, their error handling is different. For this reason
+it is necessary to set a compile-time variable when building Exim with LDAP, to
+indicate which LDAP library is in use. One of the following should appear in
+your \(Local/Makefile)\:
+.display asis
+LDAP_LIB_TYPE=UMICHIGAN
+LDAP_LIB_TYPE=OPENLDAP1
+LDAP_LIB_TYPE=OPENLDAP2
+LDAP_LIB_TYPE=NETSCAPE
+LDAP_LIB_TYPE=SOLARIS
+.endd
+If \\LDAP@_LIB@_TYPE\\ is not set, Exim assumes \"OPENLDAP1"\, which has the
+same interface as the University of Michigan version.
+
+There are three LDAP lookup types in Exim. These behave slightly differently in
+the way they handle the results of a query:
+.numberpars $.
+\%ldap%\ requires the result to contain just one entry; if there are more, it
+gives an error.
+.nextp
+\%ldapdn%\ also requires the result to contain just one entry, but it is the
+Distinguished Name that is returned rather than any attribute values.
+.nextp
+\%ldapm%\ permits the result to contain more than one entry; the attributes from
+all of them are returned.
+.endp
+
+For \%ldap%\ and \%ldapm%\, if a query finds only entries with no attributes,
+Exim behaves as if the entry did not exist, and the lookup fails. The format of
+the data returned by a successful lookup is described in the next section.
+First we explain how LDAP queries are coded.
+
+.section Format of LDAP queries
+.rset SECTforldaque "~~chapter.~~section"
+.index LDAP||query format
+An LDAP query takes the form of a URL as defined in RFC 2255. For example, in
+the configuration of a \%redirect%\ router one might have this setting:
+.display asis
+data = ${lookup ldap \
+ {ldap:///cn=$local_part,o=University%20of%20Cambridge,\
+ c=UK?mailbox?base?}}
+.endd
+.index LDAP||with TLS
+The URL may begin with \"ldap"\ or \"ldaps"\ if your LDAP library supports
+secure (encrypted) LDAP connections. The second of these ensures that an
+encrypted TLS connection is used.
+
+.section LDAP quoting
+.index LDAP||quoting
+Two levels of quoting are required in LDAP queries, the first for LDAP itself
+and the second because the LDAP query is represented as a URL. Furthermore,
+within an LDAP query, two different kinds of quoting are required. For this
+reason, there are two different LDAP-specific quoting operators.
+
+The \quote@_ldap\ operator is designed for use on strings that are part of
+filter specifications. Conceptually, it first does the following conversions on
+the string:
+.display asis
+* => \2A
+( => \28
+) => \29
+\ => \5C
+.endd
+in accordance with RFC 2254. The resulting string is then quoted according
+to the rules for URLs, that is, all characters except
+.display asis
+! $ ' - . _ ( ) * +
+.endd
+are converted to their hex values, preceded by a percent sign. For example:
+.display asis
+${quote_ldap: a(bc)*, a<yz>; }
+.endd
+yields
+.display asis
+%20a%5C28bc%5C29%5C2A%2C%20a%3Cyz%3E%3B%20
+.endd
+Removing the URL quoting, this is (with a leading and a trailing space):
+.display asis
+a\28bc\29\2A, a<yz>;
+.endd
+
+The \quote@_ldap@_dn\ operator is designed for use on strings that are part of
+base DN specifications in queries. Conceptually, it first converts the string
+by inserting a backslash in front of any of the following characters:
+.display asis
+, + " \ < > ;
+.endd
+It also inserts a backslash before any leading spaces or @# characters, and
+before any trailing spaces. (These rules are in RFC 2253.) The resulting string
+is then quoted according to the rules for URLs. For example:
+.display asis
+${quote_ldap_dn: a(bc)*, a<yz>; }
+.endd
+yields
+.display asis
+%5C%20a(bc)*%5C%2C%20a%5C%3Cyz%5C%3E%5C%3B%5C%20
+.endd
+Removing the URL quoting, this is (with a trailing space):
+.display asis
+\ a(bc)*\, a\<yz\>\;\
+.endd
+There are some further comments about quoting in the section on LDAP
+authentication below.
+
+.section LDAP connections
+.index LDAP||connections
+The connection to an LDAP server may either be over TCP/IP, or, when OpenLDAP
+is in use, via a Unix domain socket. The example given above does not specify
+an LDAP server. A server that is reached by TCP/IP can be specified in a query
+by starting it with
+.display
+ldap://<<hostname>>:<<port>>/...
+.endd
+If the port (and preceding colon) are omitted, the standard LDAP port (389) is
+used. When no server is specified in a query, a list of default servers is
+taken from the \ldap@_default@_servers\ configuration option. This supplies a
+colon-separated list of servers which are tried in turn until one successfully
+handles a query, or there is a serious error. Successful handling either
+returns the requested data, or indicates that it does not exist. Serious errors
+are syntactical, or multiple values when only a single value is expected.
+Errors which cause the next server to be tried are connection failures, bind
+failures, and timeouts.
+
+For each server name in the list, a port number can be given. The standard way
+of specifing a host and port is to use a colon separator (RFC 1738). Because
+\ldap@_default@_servers\ is a colon-separated list, such colons have to be
+doubled. For example
+.display asis
+ldap_default_servers = ldap1.example.com::145:ldap2.example.com
+.endd
+If \ldap@_default@_servers\ is unset, a URL with no server name is passed
+to the LDAP library with no server name, and the library's default (normally
+the local host) is used.
+
+If you are using the OpenLDAP library, you can connect to an LDAP server using
+a Unix domain socket instead of a TCP/IP connection. This is specified by using
+\"ldapi"\ instead of \"ldap"\ in LDAP queries. What follows here applies only
+to OpenLDAP. If Exim is compiled with a different LDAP library, this feature is
+not available.
+
+For this type of connection, instead of a host name for the server, a pathname
+for the socket is required, and the port number is not relevant. The pathname
+can be specified either as an item in \ldap@_default@_servers\, or inline in
+the query. In the former case, you can have settings such as
+.display asis
+ldap_default_servers = /tmp/ldap.sock : backup.ldap.your.domain
+.endd
+When the pathname is given in the query, you have to escape the slashes as
+\"%2F"\ to fit in with the LDAP URL syntax. For example:
+.display asis
+${lookup ldap {ldapi://%2Ftmp%2Fldap.sock/o=...
+.endd
+When Exim processes an LDAP lookup and finds that the `hostname' is really
+a pathname, it uses the Unix domain socket code, even if the query actually
+specifies \"ldap"\ or \"ldaps"\. In particular, no encryption is used for a
+socket connection. This behaviour means that you can use a setting of
+\ldap@_default@_servers\ such as in the example above with traditional \"ldap"\
+or \"ldaps"\ queries, and it will work. First, Exim tries a connection via
+the Unix domain socket; if that fails, it tries a TCP/IP connection to the
+backup host.
+
+If an explicit \"ldapi"\ type is given in a query when a host name is
+specified, an error is diagnosed. However, if there are more items in
+\ldap@_default@_servers\, they are tried. In other words:
+.numberpars $.
+Using a pathname with \"ldap"\ or \"ldaps"\ forces the use of the Unix domain
+interface.
+.nextp
+Using \"ldapi"\ with a host name causes an error.
+.endp
+
+Using \"ldapi"\ with no host or path in the query, and no setting of
+\ldap@_default@_servers\, does whatever the library does by default.
+
+
+.section LDAP authentication and control information
+.index LDAP||authentication
+The LDAP URL syntax provides no way of passing authentication and other control
+information to the server. To make this possible, the URL in an LDAP query may
+be preceded by any number of `<<name>>=<<value>>' settings, separated by
+spaces. If a value contains spaces it must be enclosed in double quotes, and
+when double quotes are used, backslash is interpreted in the usual way inside
+them.
+
+The following names are recognized:
+.display
+CONNECT $rm{set a connection timeout}
+.newline
+DEREFERENCE $rm{set the dereferencing parameter}
+USER $rm{set the DN, for authenticating the LDAP bind}
+PASS $rm{set the password, likewise}
+SIZE $rm{set the limit for the number of entries returned}
+TIME $rm{set the maximum waiting time for a query}
+.endd
+The value of the \\DEREFERENCE\\ parameter must be one of the words `never',
+`searching', `finding', or `always'.
+
+Here is an example of an LDAP query in an Exim lookup that uses some of these
+values. This is a single line, folded for ease of reading:
+.display asis
+.indent 0
+${lookup ldap
+ {user="cn=manager,o=University of Cambridge,c=UK" pass=secret
+ ldap:///o=University%20of%20Cambridge,c=UK?sn?sub?(cn=foo)}
+ {$value}fail}
+.endd
+The encoding of spaces as %20 is a URL thing which should not be done for any
+of the auxiliary data. Exim configuration settings that include lookups which
+contain password information should be preceded by `hide' to prevent non-admin
+users from using the \-bP-\ option to see their values.
+
+The auxiliary data items may be given in any order. The default is no
+connection timeout (the system timeout is used), no user or password, no limit
+on the number of entries returned, and no time limit on queries.
+
+The time limit for connection is given in seconds; zero means use the default.
+This facility is available in Netscape SDK 4.1; it may not be available in
+other LDAP implementations. Exim uses the given value if
+\\LDAP@_X@_OPT@_CONNECT@_TIMEOUT\\ is defined in the LDAP headers.
+
+When a DN is quoted in the \\USER=\\ setting for LDAP authentication, Exim
+removes any URL quoting that it may contain before passing it LDAP. Apparently
+some libraries do this for themselves, but some do not. Removing the URL
+quoting has two advantages:
+.numberpars $.
+It makes it possible to use the same \quote@_ldap@_dn\ expansion for \\USER=\\
+DNs as with DNs inside actual queries.
+.nextp
+It permits spaces inside \\USER=\\ DNs.
+.endp
+For example, a setting such as
+.display asis
+USER=cn=${quote_ldap_dn:$1}
+.endd
+should work even if \$1$\ contains spaces.
+
+Expanded data for the \\PASS=\\ value should be quoted using the \quote\
+expansion operator, rather than the LDAP quote operators. The only reason this
+field needs quoting is to ensure that it conforms to the Exim syntax, which
+does not allow unquoted spaces. For example:
+.display asis
+PASS=${quote:$3}
+.endd
+
+The LDAP authentication mechanism can be used to check passwords as part of
+SMTP authentication. See the \ldapauth\ expansion string condition in chapter
+~~CHAPexpand.
+
+
+.section Format of data returned by LDAP
+.index LDAP||returned data formats
+The \%ldapdn%\ lookup type returns the Distinguished Name from a single entry as
+a sequence of values, for example
+.display asis
+cn=manager, o=University of Cambridge, c=UK
+.endd
+
+The \%ldap%\ lookup type generates an error if more than one entry matches the
+search filter, whereas \%ldapm%\ permits this case, and inserts a newline in the
+result between the data from different entries. It is possible for multiple
+values to be returned for both \%ldap%\ and \%ldapm%\, but in the former case you
+know that whatever values are returned all came from a single entry in the
+directory.
+
+In the common case where you specify a single attribute in your LDAP query, the
+result is not quoted, and does not contain the attribute name. If the attribute
+has multiple values, they are separated by commas.
+
+If you specify multiple attributes, the result contains space-separated, quoted
+strings, each preceded by the attribute name and an equals sign. Within the
+quotes, the quote character, backslash, and newline are escaped with
+backslashes, and commas are used to separate multiple values for the attribute.
+Apart from the escaping, the string within quotes takes the same form as the
+output when a single attribute is requested. Specifying no attributes is the
+same as specifying all of an entry's attributes.
+
+Here are some examples of the output format. The first line of each pair is an
+LDAP query, and the second is the data that is returned. The attribute called
+\attr1\ has two values, whereas \attr2\ has only one value:
+.display asis
+ldap:///o=base?attr1?sub?(uid=fred)
+value1.1, value1.2
+
+ldap:///o=base?attr2?sub?(uid=fred)
+value two
+
+ldap:///o=base?attr1,attr2?sub?(uid=fred)
+attr1="value1.1, value1.2" attr2="value two"
+
+ldap:///o=base??sub?(uid=fred)
+objectClass="top" attr1="value1.1, value1.2" attr2="value two"
+.endd
+The \extract\ operator in string expansions can be used to pick out individual
+fields from data that consists of $it{key}=$it{value} pairs. You can make use
+of Exim's \-be-\ option to run expansion tests and thereby check the results of
+LDAP lookups.
+
+
+
+.section More about NIS+
+.rset SECTnisplus "~~chapter.~~section"
+.index NIS@+ lookup type
+.index lookup||NIS+
+NIS+ queries consist of a NIS+ \*indexed name*\ followed by an optional colon
+and field name. If this is given, the result of a successful query is the
+contents of the named field; otherwise the result consists of a concatenation
+of \*field-name=field-value*\ pairs, separated by spaces. Empty values and
+values containing spaces are quoted. For example, the query
+.display asis
+[name=mg1456],passwd.org_dir
+.endd
+might return the string
+.display asis
+name=mg1456 passwd="" uid=999 gid=999 gcos="Martin Guerre"
+home=/home/mg1456 shell=/bin/bash shadow=""
+.endd
+(split over two lines here to fit on the page), whereas
+.display asis
+[name=mg1456],passwd.org_dir:gcos
+.endd
+would just return
+.display asis
+Martin Guerre
+.endd
+with no quotes. A NIS+ lookup fails if NIS+ returns more than one table entry
+for the given indexed key. The effect of the \quote@_nisplus\ expansion
+operator is to double any quote characters within the text.
+
+
+.section More about MySQL, PostgreSQL, Oracle, and Interbase
+.rset SECTsql "~~chapter.~~section"
+.index MySQL||lookup type
+.index PostgreSQL lookup type
+.index lookup||MySQL
+.index lookup||PostgreSQL
+.index Oracle||lookup type
+.index lookup||Oracle
+.index Interbase lookup type
+.index 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:
+.display asis
+hide oracle_servers = oracle.plc.example//ph10/abcdwxyz
+.endd
+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-\
+option. Here is an example where two MySQL servers are listed:
+.display asis
+hide mysql_servers = localhost/users/root/secret:\
+ otherhost/users/root/othersecret
+.endd
+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
+.display asis
+.indent 0
+${lookup mysql{select mailbox from users where id='ph10'}{$value}fail}
+.endd
+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
+.display asis
+.indent 0
+${lookup pgsql{select home,name from users where id='ph10'}{$value}}
+.endd
+might be
+.display asis
+home=/home/ph10 name="Philip Hazel"
+.endd
+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:
+.display asis
+Philip Hazel
+.endd
+If the result of the query yields more than one row, it is all concatenated,
+with a newline between the data for each row.
+
+The \quote@_mysql\, \quote@_pgsql\, and \quote@_oracle\ expansion operators
+convert newline, tab, carriage return, and backspace to @\n, @\t, @\r, and @\b
+respectively, and the characters single-quote, double-quote, and backslash
+itself are escaped with backslashes. The \quote@_pgsql\ expansion operator, in
+addition, escapes the percent and underscore characters. This cannot be done
+for MySQL because these escapes are not recognized in contexts where these
+characters are not special.
+
+
+.section Special MySQL features
+For MySQL, an empty host name or the use of `localhost' in \mysql@_servers\
+causes a connection to the server on the local host by means of a Unix domain
+socket. An alternate socket can be specified in parentheses. The full syntax of
+each item in \mysql@_servers\ is:
+.display
+<<hostname>>@:@:<<port>>(<<socket name>>)/<<database>>/<<user>>/<<password>>
+.endd
+Any of the three sub-parts of the first field can be omitted. For normal use on
+the local host it can be left blank or set to just `localhost'.
+
+No database need be supplied -- but if it is absent here, it must be given in
+the queries.
+
+If a MySQL 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.
+
+
+
+.section Special PostgreSQL features
+PostgreSQL lookups can also use Unix domain socket connections to the database.
+This is usually faster and costs less CPU time than a TCP/IP connection.
+However it can be used only if the mail server runs on the same machine as the
+database server. A configuration line for PostgreSQL via Unix domain sockets
+looks like this:
+.display asis
+hide pgsql_servers = (/tmp/.s.PGSQL.5432)/db/user/password : ...
+.endd
+In other words, instead of supplying a host name, a path to the socket is
+given. The path name is enclosed in parentheses so that its slashes aren't
+visually confused with the delimiters for the other server parameters.
+
+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.
+
+
+
+
+.
+.
+.
+.
+. ============================================================================
+.chapter Domain, host, address, and local part lists
+.set runningfoot "domain, host, and address lists"
+.rset CHAPdomhosaddlists "~~chapter"
+.index 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).
+
+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
+different types of pattern for each case are described, but first we cover some
+general facilities that apply to all four kinds of list.
+
+
+.section Expansion of lists
+.index expansion||of lists
+Each list is expanded as a single string before it is used. If the expansion is
+forced to fail, Exim behaves as if the item it is testing (domain, host,
+address, or local part) is not in the list. Other expansion failures cause
+temporary errors.
+
+If an item in a list is a regular expression, backslashes, dollars and possibly
+other special characters in the expression must be protected against
+misinterpretation by the string expander. The easiest way to do this is to use
+the \"@\N"\ expansion feature to indicate that the contents of the regular
+expression should not be expanded. For example, in an ACL you might have:
+.display asis
+deny senders = \N^\d{8}\w@.*\.baddomain\.example$\N :
+ ${lookup{$domain}lsearch{/badsenders/bydomain}}
+.endd
+The first item is a regular expression that is protected from expansion by
+\"@\N"\, whereas the second uses the expansion to obtain a list of unwanted
+senders based on the receiving domain.
+
+After expansion, the list is split up into separate items for matching.
+Normally, colon is used as the separator character, but this can be varied if
+necessary, as described in section ~~SECTlistconstruct.
+
+
+.section Negated items in lists
+.index list||negation
+.index negation in lists
+Items in a list may be positive or negative. Negative items are indicated by a
+leading exclamation mark, which may be followed by optional white space. A list
+defines a set of items (domains, etc). When Exim processes one of these lists,
+it is trying to find out whether a domain, host, address, or local part
+(respectively) is in the set that is defined by the list. It works like this:
+
+The list is scanned from left to right. If a positive item is matched, the
+subject that is being checked is in the set; if a negative item is matched, the
+subject is not in the set. If the end of the list is reached without the
+subject having matched any of the patterns, it is in the set if the last item
+was a negative one, but not if it was a positive one. For example, the list in
+.display asis
+domainlist relay_domains = !a.b.c : *.b.c
+.endd
+matches any domain ending in \*.b.c*\ except for \*a.b.c*\. Domains that match
+neither \*a.b.c*\ nor \*@*.b.c*\ do not match, because the last item in the
+list is positive. However, if the setting were
+.display asis
+domainlist relay_domains = !a.b.c
+.endd
+then all domains other than \*a.b.c*\ would match because the last item in the
+list is negative. In other words, a list that ends with a negative item behaves
+as if it had an extra item \":*"\ on the end.
+
+Another way of thinking about positive and negative items in lists is to read
+the connector as `or' after a positive item and as `and' after a negative
+item.
+
+
+.section File names in lists
+.rset SECTfilnamlis "~~chapter.~~section"
+.index list||file name in
+If an item in a domain, host, address, or local part list is an absolute file
+name (beginning with a slash character), each line of the file is read and
+processed as if it were an independent item in the list, except that further
+file names are not allowed,
+and no expansion of the data from the file takes place.
+Empty lines in the file are ignored, and the file may also contain comment
+lines:
+.numberpars $.
+For domain and host lists, if a @# character appears anywhere in a line of the
+file, it and all following characters are ignored.
+.nextp
+Because local parts may legitimately contain @# characters, a comment in an
+address list or local part list file is recognized only if @# is preceded by
+white space or the start of the line. For example:
+.display asis
+not#comment@x.y.z # but this is a comment
+.endd
+.endp
+Putting a file name in a list has the same effect as inserting each line of the
+file as an item in the list (blank lines and comments excepted). However, there
+is one important difference: the file is read each time the list is processed,
+so if its contents vary over time, Exim's behaviour changes.
+
+If a file name is preceded by an exclamation mark, the sense of any match
+within the file is inverted. For example, if
+.display asis
+hold_domains = !/etc/nohold-domains
+.endd
+and the file contains the lines
+.display asis
+!a.b.c
+*.b.c
+.endd
+then \*a.b.c*\ is in the set of domains defined by \hold@_domains\, whereas any
+domain matching \"*.b.c"\ is not.
+
+
+.section An lsearch file is not an out-of-line list
+As will be described in the sections that follow, lookups can be used in lists
+to provide indexed methods of checking list membership. There has been some
+confusion about the way \%lsearch%\ lookups work in lists. Because
+an \%lsearch%\ file contains plain text and is scanned sequentially, it is
+sometimes thought that it is allowed to contain wild cards and other kinds of
+non-constant pattern. This is not the case. The keys in an \%lsearch%\ file are
+always fixed strings, just as for any other single-key lookup type.
+
+If you want to use a file to contain wild-card patterns that form part of a
+list, just give the file name on its own, without a search type, as described
+in the previous section.
+
+
+
+.section Named lists
+.rset SECTnamedlists "~~chapter.~~section"
+.index named lists
+.index list||named
+A list of domains, hosts, email addresses, or local parts can be given a name
+which is then used to refer to the list elsewhere in the configuration. This is
+particularly convenient if the same list is required in several different
+places. It also allows lists to be given meaningful names, which can improve
+the readability of the configuration. For example, it is conventional to define
+a domain list called \*local@_domains*\ for all the domains that are handled
+locally on a host, using a configuration line such as
+.display asis
+domainlist local_domains = localhost:my.dom.example
+.endd
+Named lists are referenced by giving their name preceded by a plus sign, so,
+for example, a router that is intended to handle local domains would be
+configured with the line
+.display asis
+domains = +local_domains
+.endd
+The first router in a configuration is often one that handles all domains
+except the local ones, using a configuration with a negated item like this:
+.display asis
+dnslookup:
+ driver = dnslookup
+ domains = ! +local_domains
+ transport = remote_smtp
+ no_more
+.endd
+The four kinds of named list are created by configuration lines starting with
+the words \domainlist\, \hostlist\, \addresslist\, or \localpartlist\,
+respectively. Then there follows the name that you are defining, followed by an
+equals sign and the list itself. For example:
+.display asis
+hostlist relay_hosts = 192.168.23.0/24 : my.friend.example
+addresslist bad_senders = cdb;/etc/badsenders
+.endd
+A named list may refer to other named lists:
+.display asis
+domainlist dom1 = first.example : second.example
+domainlist dom2 = +dom1 : third.example
+domainlist dom3 = fourth.example : +dom2 : fifth.example
+.endd
+
+\**Warning**\: If the last item in a referenced list is a negative one, the
+effect may not be what you intended, because the negation does not propagate
+out to the higher level. For example, consider:
+.display asis
+domainlist dom1 = !a.b
+domainlist dom2 = +dom1 : *.b
+.endd
+The second list specifies `either in the \dom1\ list or \*@*.b*\'. The first
+list specifies just `not \*a.b*\', so the domain \*x.y*\ matches it. That means
+it matches the second list as well. The effect is not the same as
+.display asis
+domainlist dom2 = !a.b : *.b
+.endd
+where \*x.y*\ does not match. It's best to avoid negation altogether in
+referenced lists if you can.
+
+Named lists may have a performance advantage. When Exim is routing an
+address or checking an incoming message, it caches the result of tests on named
+lists. So, if you have a setting such as
+.display asis
+domains = +local_domains
+.endd
+on several of your routers
+or in several ACL statements,
+the actual test is done only for the first one. However, the caching works only
+if there are no expansions within the list itself or any sublists that it
+references. In other words, caching happens only for lists that are known to be
+the same each time they are referenced.
+
+By default, there may be up to 16 named lists of each type. This limit can be
+extended by changing a compile-time variable. The use of domain and host lists
+is recommended for concepts such as local domains, relay domains, and relay
+hosts. The default configuration is set up like this.
+
+
+.section Named lists compared with macros
+.index list||named compared with macro
+.index macro||compared with named list
+At first sight, named lists might seem to be no different from macros in the
+configuration file. However, macros are just textual substitutions. If you
+write
+.display asis
+ALIST = host1 : host2
+auth_advertise_hosts = !ALIST
+.endd
+it probably won't do what you want, because that is exactly the same as
+.display asis
+auth_advertise_hosts = !host1 : host2
+.endd
+Notice that the second host name is not negated. However, if you use a host
+list, and write
+.display asis
+hostlist alist = host1 : host2
+auth_advertise_hosts = ! +alist
+.endd
+the negation applies to the whole list, and so that is equivalent to
+.display asis
+auth_advertise_hosts = !host1 : !host2
+.endd
+
+
+.em
+.section Named list caching
+.index list||caching of named
+.index caching||named lists
+While processing a message, Exim caches the result of checking a named list if
+it is sure that the list is the same each time. In practice, this means that
+the cache operates only if the list contains no @$ characters, which guarantees
+that it will not change when it is expanded. Sometimes, however, you may have
+an expanded list that you know will be the same each time within a given
+message. For example:
+.display asis
+domainlist special_domains = \
+ ${lookup{$sender_host_address}cdb{/some/file}}
+.endd
+This provides a list of domains that depends only on the sending host's IP
+address. If this domain list is referenced a number of times (for example,
+in several ACL lines, or in several routers) the result of the check is not
+cached by default, because Exim does not know that it is going to be the
+same list each time.
+
+By appending \"@_cache"\ to \"domainlist"\ you can tell Exim to go ahead and
+cache the result anyway. For example:
+.display asis
+domainlist_cache special_domains = ${lookup{...
+.endd
+If you do this, you should be absolutely sure that caching is going to do
+the right thing in all cases. When in doubt, leave it out.
+.nem
+
+
+.section Domain lists
+.rset SECTdomainlist "~~chapter.~~section"
+.index domain list||patterns for
+.index list||domain list
+Domain lists contain patterns that are to be matched against a mail domain.
+The following types of item may appear in domain lists:
+.numberpars $.
+.index primary host name
+.index host||name, matched in domain list
+.index \primary@_hostname\
+.index domain list||matching primary host name
+.index @@ in a domain list
+If a pattern consists of a single @@ character, it matches the local host name,
+as set by the \primary@_hostname\ option (or defaulted). This makes it possible
+to use the same configuration file on several different hosts that differ only
+in their names.
+.nextp
+.index @@[] in a domain list
+.index domain list||matching local IP interfaces
+.index domain literal
+If a pattern consists of the string \"@@[]"\ it matches any local IP interface
+address, enclosed in square brackets, as in an email address that contains a
+domain literal.
+.em
+In today's Internet, the use of domain literals is controversial.
+.nem
+.nextp
+.index @@mx@_any
+.index @@mx@_primary
+.index @@mx@_secondary
+.index domain list||matching MX pointers to local host
+If a pattern consists of the string \"@@mx@_any"\ it matches any domain that
+has an MX record pointing to the local host or to any host that is listed in
+.index \hosts@_treat@_as@_local\
+\hosts@_treat@_as@_local\. The items \"@@mx@_primary"\ and \"@@mx@_secondary"\
+are similar, except that the first matches only when a primary MX target is the
+local host, and the second only when no primary MX target is the local host,
+but a secondary MX target is. `Primary' means an MX record with the lowest
+preference value -- there may of course be more than one of them.
+
+.em
+The MX lookup that takes place when matching a pattern of this type is
+performed with the resolver options for widening names turned off. Thus, for
+example, a single-component domain will \*not*\ be expanded by adding the
+resolver's default domain. See the \qualify@_single\ and \search@_parents\
+options of the \%dnslookup%\ router for a discussion of domain widening.
+
+Sometimes you may want to ignore certain IP addresses when using one of these
+patterns. You can specify this by following the pattern with \"/ignore=<<ip
+list>>"\, where <<ip list>> is a list of IP addresses. These addresses are
+ignored when processing the pattern (compare the \ignore@_target@_hosts\ option
+on a router). For example:
+.display asis
+domains = @mx_any/ignore=127.0.0.1
+.endd
+This example matches any domain that has an MX record pointing to one of
+the local host's IP addresses other than 127.0.0.1.
+
+The list of IP addresses is in fact processed by the same code that processes
+host lists, so it may contain CIDR-coded network specifications and it may also
+contain negative items.
+
+Because the list of IP addresses is a sublist within a domain list, you have to
+be careful about delimiters if there is more than one address. Like any other
+list, the default delimiter can be changed. Thus, you might have:
+.display asis
+domains = @mx_any/ignore=<;127.0.0.1;0.0.0.0 : \
+ an.other.domain : ...
+.endd
+so that the sublist uses semicolons for delimiters. When IPv6 addresses are
+involved, it is easiest to change the delimiter for the main list as well:
+.display asis
+domains = <? @mx_any/ignore=<;127.0.0.1;::1 ? \
+ an.other.domain ? ...
+.endd
+.nem
+
+.nextp
+.index asterisk||in domain list
+.index domain list||asterisk in
+.index domain list||matching `ends with'
+If a pattern starts with an asterisk, the remaining characters of the pattern
+are compared with the terminating characters of the domain. The use of `$*$' in
+domain lists differs from its use in partial matching lookups. In a domain
+list, the character following the asterisk need not be a dot, whereas partial
+matching works only in terms of dot-separated components. For example, a domain
+list item such as \"*key.ex"\ matches \*donkey.ex*\ as well as
+\*cipher.key.ex*\.
+.nextp
+.index regular expressions||in domain list
+.index domain list||matching regular expression
+If a pattern starts with a circumflex character, it is treated as a regular
+expression, and matched against the domain using a regular expression matching
+function. The circumflex is treated as part of the regular expression.
+References to descriptions of the syntax of regular expressions are given in
+chapter ~~CHAPregexp.
+
+\**Warning**\: Because domain lists are expanded before being processed, you
+must escape any backslash and dollar characters in the regular expression, or
+use the special \"@\N"\ sequence (see chapter ~~CHAPexpand) to specify that it
+is not to be expanded (unless you really do want to build a regular expression
+by expansion, of course).
+.nextp
+.index lookup||in domain list
+.index domain list||matching by lookup
+If a pattern starts with the name of a single-key lookup type followed by a
+semicolon (for example, `dbm;' or `lsearch;'), the remainder of the pattern
+must be a file name in a suitable format for the lookup type. For example, for
+`cdb;' it must be an absolute path:
+.display asis
+domains = cdb;/etc/mail/local_domains.cdb
+.endd
+The appropriate type of lookup is done on the file using the domain name as the
+key. In most cases, the data that is looked up is not used; Exim is interested
+only in whether or not the key is present in the file. However, when a lookup
+is used for the \domains\ option on a router
+or a \domains\ condition in an ACL statement, the data is preserved in the
+\$domain@_data$\ variable and can be referred to in other router options or
+other statements in the same ACL.
+.nextp
+Any of the single-key lookup type names may be preceded by `partial<<n>>-',
+where the <<n>> is optional, for example,
+.display asis
+domains = partial-dbm;/partial/domains
+.endd
+This causes partial matching logic to be invoked; a description of how this
+works is given in section ~~SECTpartiallookup.
+.nextp
+.index asterisk||in lookup type
+Any of the single-key lookup types may be followed by an asterisk. This causes
+a default lookup for a key consisting of a single asterisk to be done if the
+original lookup fails. This is not a useful feature when using a domain list to
+select particular domains (because any domain would match), but it might have
+value if the result of the lookup is being used via the \$domain@_data$\
+expansion variable.
+.nextp
+If the pattern starts with the name of a query-style lookup type followed by a
+semicolon (for example, `nisplus;' or `ldap;'), the remainder of the pattern
+must be an appropriate query for the lookup type, as described in chapter
+~~CHAPfdlookup. For example:
+.display asis
+hold_domains = mysql;select domain from holdlist \
+ where domain = '$domain';
+.endd
+In most cases, the data that is looked up is not used (so for an SQL query, for
+example, it doesn't matter what field you select). Exim is interested only in
+whether or not the query succeeds. However, when a lookup is used for the
+\domains\ option on a router, the data is preserved in the \$domain@_data$\
+variable and can be referred to in other options.
+.nextp
+.index domain list||matching literal domain name
+If none of the above cases apply, a caseless textual comparison is made between
+the pattern and the domain.
+.endp
+
+Here is an example that uses several different kinds of pattern:
+.display asis
+domainlist funny_domains = \
+ @ : \
+ lib.unseen.edu : \
+ *.foundation.fict.example : \
+ \N^[1-2]\d{3}\.fict\.example$\N : \
+ partial-dbm;/opt/data/penguin/book : \
+ nis;domains.byname : \
+ nisplus;[name=$domain,status=local],domains.org_dir
+.endd
+There are obvious processing trade-offs among the various matching modes. Using
+an asterisk is faster than a regular expression, and listing a few names
+explicitly probably is too. The use of a file or database lookup is expensive,
+but may be the only option if hundreds of names are required. Because the
+patterns are tested in order, it makes sense to put the most commonly matched
+patterns earlier.
+
+
+.section Host lists
+.rset SECThostlist "~~chapter.~~section"
+.index host list||patterns in
+.index list||host list
+Host lists are used to control what remote hosts are allowed to do. For
+example, some hosts may be allowed to use the local host as a relay, and some
+may be permitted to use the SMTP \\ETRN\\ command. Hosts can be identified in
+two different ways, by name or by IP address. In a host list, some types of
+pattern are matched to a host name, and some are matched to an IP address.
+You need to be particularly careful with this when single-key lookups are
+involved, to ensure that the right value is being used as the key.
+
+.section Special host list patterns
+.index empty item in hosts list
+.index host list||empty string in
+If a host list item is the empty string, it matches only when no remote host is
+involved. This is the case when a message is being received from a local
+process using SMTP on the standard input, that is, when a TCP/IP connection is
+not used.
+
+.index asterisk||in host list
+The special pattern `$*$' in a host list matches any host or no host. Neither
+the IP address nor the name is actually inspected.
+
+
+.section Host list patterns that match by IP address
+.rset SECThoslispatip "~~chapter.~~section"
+.index host list||matching IP addresses
+If an IPv4 host calls an IPv6 host and the call is accepted on an IPv6 socket,
+the incoming address actually appears in the IPv6 host as
+`@:@:$tt{ffff}:<<v4address>>'. When such an address is tested against a host
+list, it is converted into a traditional IPv4 address first. (Not all operating
+systems accept IPv4 calls on IPv6 sockets, as there have been some security
+concerns.)
+
+The following types of pattern in a host list check the remote host by
+inspecting its IP address:
+.numberpars $.
+If the pattern is a plain domain name (not a regular expression, not starting
+with $*$, not a lookup of any kind), Exim calls the operating system function
+to find the associated IP address(es). Exim uses the newer
+\*getipnodebyname()*\ function when available, otherwise \*gethostbyname()*\.
+This typically causes a forward DNS lookup of the name. The result is compared
+with the IP address of the subject host.
+
+.em
+If there is a temporary problem (such as a DNS timeout) with the host name
+lookup, a temporary error occurs. For example, if the list is being used in an
+ACL condition, the ACL gives a `defer' response, usually leading to a temporary
+SMTP error code. If no IP address can be found for the host name, what happens
+is described in section ~~SECTbehipnot below.
+.nem
+
+.nextp
+.index @@ in a host list
+If the pattern is `@@', the primary host name is substituted and used as a
+domain name, as just described.
+.nextp
+If the pattern is an IP address, it is matched against the IP address of the
+subject host. IPv4 addresses are given in the normal `dotted-quad' notation.
+IPv6 addresses can be given in colon-separated format, but the colons have to
+be doubled so as not to be taken as item separators when the default list
+separator is used. IPv6 addresses are recognized even when Exim is compiled
+without IPv6 support. This means that if they appear in a host list on an
+IPv4-only host, Exim will not treat them as host names. They are just addresses
+that can never match a client host.
+.nextp
+.index @@[] in a host list
+If the pattern is `@@[]', it matches the IP address of any IP interface on
+the local host. For example, if the local host is an IPv4 host with one
+interface address 10.45.23.56, these two ACL statements have the same effect:
+.display asis
+accept hosts = 127.0.0.1 : 10.45.23.56
+accept hosts = @[]
+.endd
+.nextp
+If the pattern is an IP address followed by a slash and a mask length (for
+example 10.11.42.0/24), it is matched against the IP address of the subject
+host under the given mask.
+This allows, an entire network of hosts to be included (or excluded) by a
+single item.
+.index CIDR notation
+The mask uses CIDR notation; it specifies the number of address bits that must
+match, starting from the most significant end of the address.
+
+\**Note**\: the mask is \*not*\ a count of addresses, nor is it the high number
+of a range of addresses. It is the number of bits in the network portion of the
+address. The above example specifies a 24-bit netmask, so it matches all 256
+addresses in the 10.11.42.0 network. An item such as
+.display asis
+192.168.23.236/31
+.endd
+matches just two addresses, 192.168.23.236 and 192.168.23.237. A mask value of
+32 for an IPv4 address is the same as no mask at all; just a single address
+matches.
+
+Here is another example which shows an IPv4 and an IPv6 network:
+.display asis
+recipient_unqualified_hosts = 192.168.0.0/16: \
+ 3ffe::ffff::836f::::/48
+.endd
+The doubling of list separator characters applies only when these items
+appear inline in a host list. It is not required when indirecting via a file.
+For example,
+.display asis
+recipient_unqualified_hosts = /opt/exim/unqualnets
+.endd
+could make use of a file containing
+.display asis
+172.16.0.0/12
+3ffe:ffff:836f::/48
+.endd
+to have exactly the same effect as the previous example. When listing IPv6
+addresses inline, it is usually more convenient to use the facility for
+changing separator characters. This list contains the same two networks:
+.display asis
+recipient_unqualified_hosts = <; 172.16.0.0/12; \
+ 3ffe:ffff:836f::/48
+.endd
+The separator is changed to semicolon by the leading `<;' at the start of the
+list.
+.endp
+
+
+.section Host list patterns for single-key lookups by host address
+.rset SECThoslispatsikey "~~chapter.~~section"
+.index host list||lookup of IP address
+When a host is to be identified by a single-key lookup of its complete IP
+address, the pattern takes this form:
+.display
+net-<<single-key-search-type>>;<<search-data>>
+.endd
+For example:
+.display asis
+hosts_lookup = net-cdb;/hosts-by-ip.db
+.endd
+The text form of the IP address of the subject host is used as the lookup key.
+IPv6 addresses are converted to an unabbreviated form, using lower case
+letters, with dots as separators because colon is the key terminator in
+\%lsearch%\ files. [Colons can in fact be used in keys in \%lsearch%\ files by
+quoting the keys, but this is a facility that was added later.] The data
+returned by the lookup is not used.
+
+.index IP address||masking
+.index host list||masked IP address
+Single-key lookups can also be performed using masked IP addresses, using
+patterns of this form:
+.display
+net<<number>>-<<single-key-search-type>>;<<search-data>>
+.endd
+For example:
+.display asis
+net24-dbm;/networks.db
+.endd
+The IP address of the subject host is masked using <<number>> as the mask
+length. A textual string is constructed from the masked value, followed by the
+mask, and this is used as the lookup key. For example, if the host's IP address
+is 192.168.34.6, the key that is looked up for the above example is
+`192.168.34.0/24'. IPv6 addresses are converted to a text value using lower
+case letters and dots as separators instead of the more usual colon, because
+colon is the key terminator in \%lsearch%\ files. Full, unabbreviated IPv6
+addresses are always used.
+
+\**Warning**\: Specifing \net32@-\ (for an IPv4 address) or \net128@-\ (for an
+IPv6 address) is not the same as specifing just \net@-\ without a number. In
+the former case the key strings include the mask value, whereas in the latter
+case the IP address is used on its own.
+
+
+.section Host list patterns that match by host name
+.rset SECThoslispatnam "~~chapter.~~section"
+.index host||lookup failures
+.index unknown host name
+.index host list||matching host name
+There are several types of pattern that require Exim to know the name of the
+remote host. These are either wildcard patterns or lookups by name. (If a
+complete hostname is given without any wildcarding, it is used to find an IP
+address to match against, as described in the section ~~SECThoslispatip above.)
+
+If the remote host name is not already known when Exim encounters one of these
+patterns, it has to be found from the IP address.
+.em
+Although many sites on the Internet are conscientious about maintaining reverse
+DNS data for their hosts, there are also many that do not do this.
+Consequently, a name cannot always be found, and this may lead to unwanted
+effects. Take care when configuring host lists with wildcarded name patterns.
+Consider what will happen if a name cannot be found.
+
+Because of the problems of determining host names from IP addresses, matching
+against host names is not as common as matching against IP addresses.
+
+By default, in order to find a host name, Exim first does a reverse DNS lookup;
+if no name is found in the DNS, the system function (\*gethostbyaddr()*\ or
+\*getipnodebyaddr()*\ if available) is tried. The order in which these lookups
+are done can be changed by setting the \host@_lookup@_order\ option.
+
+There are some options that control what happens if a host name cannot be
+found. These are described in section ~~SECTbehipnot below.
+.nem
+
+
+.index host||alias for
+.index alias for host
+As a result of aliasing, hosts may have more than one name. When processing any
+of the following types of pattern, all the host's names are checked:
+.numberpars $.
+.index asterisk||in host list
+If a pattern starts with `$*$' the remainder of the item must match the end of
+the host name. For example, \"*.b.c"\ matches all hosts whose names end in
+\*.b.c*\. This special simple form is provided because this is a very common
+requirement. Other kinds of wildcarding require the use of a regular
+expression.
+.nextp
+.index regular expressions||in host list
+.index host list||regular expression in
+If the item starts with `@^' it is taken to be a regular expression which is
+matched against the host name. For example,
+.display asis
+^(a|b)\.c\.d$
+.endd
+is a regular expression that matches either of the two hosts \*a.c.d*\ or
+\*b.c.d*\. When a regular expression is used in a host list, you must take care
+that backslash and dollar characters are not misinterpreted as part of the
+string expansion. The simplest way to do this is to use \"@\N"\ to mark that
+part of the string as non-expandable. For example:
+.display asis
+sender_unqualified_hosts = \N^(a|b)\.c\.d$\N : ....
+.endd
+.em
+\**Warning**\: If you want to match a complete host name, you must include the
+\"@$"\ terminating metacharacter in the regular expression, as in the above
+example. Without it, a match at the start of the host name is all that is
+required.
+.nem
+.endp
+
+
+.em
+.section Behaviour when an IP address or name cannot be found
+.rset SECTbehipnot "~~chapter.~~section"
+.index host||lookup failures
+While processing a host list, Exim may need to look up an IP address from a
+name (see section ~~SECThoslispatip), or it may need to look up a host name
+from an IP address (see section ~~SECThoslispatnam). In either case, the
+behaviour when it fails to find the information it is seeking is the same.
+
+.index \"+include@_unknown"\
+.index \"+ignore@_unknown"\
+By default, Exim behaves as if the host does not match the list. This may not
+always be what you want to happen. To change Exim's behaviour, the special
+items \"+include@_unknown"\ or \"+ignore@_unknown"\ may appear in the list (at
+top level -- they are not recognized in an indirected file).
+.numberpars $.
+If any item that follows \"+include@_unknown"\ requires information that
+cannot found, Exim behaves as if the host does match the list. For example,
+.display asis
+host_reject_connection = +include_unknown:*.enemy.ex
+.endd
+rejects connections from any host whose name matches \"*.enemy.ex"\, and also
+any hosts whose name it cannot find.
+.nextp
+If any item that follows \"+ignore@_unknown"\ requires information that cannot
+be found, Exim ignores that item and proceeds to the rest of the list. For
+example:
+.display asis
+accept hosts = +ignore_unknown : friend.example : \
+ 192.168.4.5
+.endd
+accepts from any host whose name is \*friend.example*\ and from 192.168.4.5,
+whether or not its host name can be found. Without \"+ignore@_unknown"\, if no
+name can be found for 192.168.4.5, it is rejected.
+.endp
+Both \"+include@_unknown"\ and \"+ignore@_unknown"\ may appear in the same
+list. The effect of each one lasts until the next, or until the end of the
+list.
+
+\**Note**\: This section applies to permanent lookup failures. It does \*not*\
+apply to temporary DNS errors. They always cause a defer action.
+.nem
+
+
+.section Host list patterns for single-key lookups by host name
+.rset SECThoslispatnamsk "~~chapter.~~section"
+.index host||lookup failures
+.index unknown host name
+.index host list||matching host name
+If a pattern is of the form
+.display
+<<single-key-search-type>>;<<search-data>>
+.endd
+for example
+.display asis
+dbm;/host/accept/list
+.endd
+a single-key lookup is performend, using the host name as its key. If the
+lookup succeeds, the host matches the item. The actual data that is looked up
+is not used.
+
+\**Reminder**\: With this kind of pattern, you must have host $it{names} as
+keys in the file, not IP addresses. If you want to do lookups based on IP
+addresses, you must precede the search type with `net-' (see section
+~~SECThoslispatsikey). There is, however, no reason why you could not use two
+items in the same list, one doing an address lookup and one doing a name
+lookup, both using the same file.
+
+
+.section Host list patterns for query-style lookups
+If a pattern is of the form
+.display
+<<query-style-search-type>>;<<query>>
+.endd
+the query is obeyed, and if it succeeds, the host matches the item. The actual
+data that is looked up is not used. The variables \$sender@_host@_address$\ and
+\$sender@_host@_name$\ can be used in the query. For example:
+.display asis
+hosts_lookup = pgsql;\
+ select ip from hostlist where ip='$sender_host_address'
+.endd
+The value of \$sender@_host@_address$\ for an IPv6 address uses colon
+separators. You can use the \sg\ expansion item to change this if you need to.
+If you want to use masked IP addresses in database queries, you can use the
+\mask\ expansion operator.
+
+If the query contains a reference to \$sender@_host@_name$\, Exim automatically
+looks up the host name if has not already done so. (See section
+~~SECThoslispatnam for comments on finding host names.)
+
+Historical note: prior to release 4.30, Exim would always attempt to find a
+host name before running the query, unless the search type was preceded by
+\"net-"\. This is no longer the case. For backwards compatibility, \"net-"\ is
+still recognized for query-style lookups, but its presence or absence has no
+effect. (Of course, for single-key lookups, \"net-"\ $it{is} important.)
+
+
+.section Mixing wildcarded host names and addresses in host lists
+.rset SECTmixwilhos "~~chapter.~~section"
+.index host list||mixing names and addresses in
+If you have name lookups or wildcarded host names and IP addresses in the same
+host list, you should normally put the IP addresses first. For example, in an
+ACL you could have:
+.display asis
+accept hosts = 10.9.8.7 : *.friend.example
+.endd
+The reason for this lies in the left-to-right way that Exim processes lists.
+It can test IP addresses without doing any DNS lookups, but when it reaches an
+item that requires a host name, it fails if it cannot find a host name to
+compare with the pattern. If the above list is given in the opposite order, the
+\accept\ statement fails for a host whose name cannot be found, even if its
+IP address is 10.9.8.7.
+
+If you really do want to do the name check first, and still recognize the IP
+address, you can rewrite the ACL like this:
+.display asis
+accept hosts = *.friend.example
+accept hosts = 10.9.8.7
+.endd
+If the first \accept\ fails, Exim goes on to try the second one. See chapter
+~~CHAPACL for details of ACLs.
+
+
+
+
+.section Address lists
+.index list||address list
+.index address list||empty item
+.index address list||patterns
+.rset SECTaddresslist "~~chapter.~~section"
+Address lists contain patterns that are matched against mail addresses. There
+is one special case to be considered: the sender address of a bounce message is
+always empty. You can test for this by providing an empty item in an address
+list. For example, you can set up a router to process bounce messages by
+using this option setting:
+.display asis
+senders = :
+.endd
+The presence of the colon creates an empty item. If you do not provide any
+data, the list is empty and matches nothing. The empty sender can also be
+detected by a regular expression that matches an empty string.
+
+The following kinds of pattern are supported in address lists:
+.numberpars $.
+.index regular expressions||in address list
+.index address list||regular expression in
+If (after expansion) a pattern starts with `@^', a regular expression match is
+done against the complete address, with the pattern as the regular expression.
+You must take care that backslash and dollar characters are not misinterpreted
+as part of the string expansion. The simplest way to do this is to use \"@\N"\
+to mark that part of the string as non-expandable. For example:
+.display asis
+deny senders = \N^\d{8}.+@spamhaus.example$\N : ...
+.endd
+The \"@\N"\ sequences are removed by the expansion, so the item does start
+with `@^' by the time it is being interpreted as an address pattern.
+.nextp
+.index @@@@ with single-key lookup
+.index address list||@@@@ lookup type
+.index address list||split local part and domain
+If a pattern starts with `@@@@' followed by a single-key lookup item
+(for example, \"@@@@lsearch;/some/file"\), the address that is being checked is
+split into a local part and a domain. The domain is looked up in the file. If
+it is not found, there is no match. If it is found, the data that is looked up
+from the file is treated as a colon-separated list of local part patterns, each
+of which is matched against the subject local part in turn.
+
+.index asterisk||in address list
+The lookup may be a partial one, and/or one involving a search for a default
+keyed by `$*$' (see section ~~SECTdefaultvaluelookups). The local part patterns
+that are looked up can be regular expressions or begin with `$*$', or even be
+further lookups. They may also be independently negated. For example, with
+.display asis
+deny senders = @@dbm;/etc/reject-by-domain
+.endd
+the data from which the DBM file is built could contain lines like
+.display asis
+baddomain.com: !postmaster : *
+.endd
+to reject all senders except \postmaster\ from that domain.
+.index local part||starting with !
+If a local part that actually begins with an exclamation mark is required, it
+has to be specified using a regular expression. In \%lsearch%\ files, an entry
+may be split over several lines by indenting the second and subsequent lines,
+but the separating colon must still be included at line breaks. White space
+surrounding the colons is ignored. For example:
+.display asis
+aol.com: spammer1 : spammer2 : ^[0-9]+$ :
+ spammer3 : spammer4
+.endd
+As in all colon-separated lists in Exim, a colon can be included in an item by
+doubling.
+
+If the last item in the list starts with a right angle-bracket, the remainder
+of the item is taken as a new key to look up in order to obtain a continuation
+list of local parts. The new key can be any sequence of characters. Thus one
+might have entries like
+.display asis
+aol.com: spammer1 : spammer 2 : >*
+xyz.com: spammer3 : >*
+*: ^\d{8}$
+.endd
+in a file that was searched with \@@@@dbm$*$\, to specify a match for 8-digit
+local parts for all domains, in addition to the specific local parts listed for
+each domain. Of course, using this feature costs another lookup each time a
+chain is followed, but the effort needed to maintain the data is reduced.
+.index loop||in lookups
+It is possible to construct loops using this facility, and in order to catch
+them, the chains may be no more than fifty items long.
+.nextp
+The @@@@<<lookup>> style of item can also be used with a query-style
+lookup, but in this case, the chaining facility is not available. The lookup
+can only return a single list of local parts.
+.nextp
+.index address list||lookup for complete address
+Complete addresses can be looked up by using a pattern that
+starts with a lookup type terminated by a semicolon, follwed by the data for
+the lookup.
+For example:
+.display asis
+deny senders = cdb;/etc/blocked.senders : \
+ mysql;select address from blocked where \
+ address='${quote_mysql:$sender_address}'
+.endd
+For a single-key lookup type, Exim uses the complete address as the key.
+Partial matching (section ~~SECTpartiallookup) cannot be used, and is ignored
+if specified, with an entry being written to the panic log.
+
+.index @*@@ with single-key lookup
+You can configure lookup defaults, as described in section
+~~SECTdefaultvaluelookups, but this is useful only for the `$*$@@' type of
+default. For example, with this lookup:
+.display asis
+accept senders = lsearch*@;/some/file
+.endd
+the file could contains lines like this:
+.display asis
+user1@domain1.example
+*@domain2.example
+.endd
+and for the sender address \*nimrod@@jaeger.example*\, the sequence of keys
+that are tried is:
+.display asis
+nimrod@jaeger.example
+*@jaeger.example
+*
+.endd
+\**Warning 1**\: Do not include a line keyed by `$*$' in the file, because that
+would mean that every address matches, thus rendering the test useless.
+
+\**Warning 2**\: Do not confuse these two kinds of item:
+.display asis
+deny recipients = dbm*@;/some/file
+deny recipients = *@dbm;/some/file
+.endd
+The first does a whole address lookup, with defaulting, as just described,
+because it starts with a lookup type. The second matches the local part and
+domain independently, as described in the next paragraph.
+.nextp
+If a pattern contains an @@ character, but is not a regular expression
+and does not begin with a lookup type
+as described above, the local part of the subject address is compared with the
+local part of the pattern, which may start with an asterisk. If the local parts
+match, the domain is checked in exactly the same way as for a pattern in a
+domain list. For example, the domain can be wildcarded, refer to a named list,
+or be a lookup:
+.display asis
+deny senders = *@*.spamming.site:\
+ *@+hostile_domains:\
+ bozo@partial-lsearch;/list/of/dodgy/sites:\
+.newline
+ *@dbm;/bad/domains.db
+.endd
+.index local part||starting with !
+.index address list||local part starting with !
+If a local part that begins with an exclamation mark is required, it has to be
+specified using a regular expression, because otherwise the exclamation mark is
+treated as a sign of negation.
+.nextp
+If a pattern is not one of the above syntax forms, that is, if a pattern which
+is not a regular expression or a lookup does not contain an @@ character, it is
+matched against the domain part of the subject address. The only two formats
+that are recognized this way are a literal domain, or a domain pattern that
+starts with $*$. In both these cases, the effect is the same as if \"*@@"\
+preceded the pattern.
+.endp
+
+\**Warning**\: there is an important difference between the address list items
+in these two examples:
+.display asis
+senders = +my_list
+senders = *@+my_list
+.endd
+In the first one, \"my@_list"\ is a named address list, whereas in the second
+example it is a named domain list.
+
+
+
+.section Case of letters in address lists
+.rset SECTcasletadd "~~chapter.~~section"
+.index case of local parts
+.index address list||case forcing
+.index case forcing in address lists
+Domains in email addresses are always handled caselessly, but for local parts
+case may be significant on some systems (see \caseful@_local@_part\ for how
+Exim deals with this when routing addresses). However, RFC 2505 ($it{Anti-Spam
+Recommendations for SMTP MTAs}) suggests that matching of addresses to blocking
+lists should be done in a case-independent manner. Since most address lists in
+Exim are used for this kind of control, Exim attempts to do this by default.
+
+The domain portion of an address is always lowercased before matching it to an
+address list. The local part is lowercased by default, and any string
+comparisons that take place are done caselessly. This means that the data in
+the address list itself, in files included as plain file names, and in any file
+that is looked up using the `@@@@' mechanism, can be in any case. However, the
+keys in files that are looked up by a search type other than \%lsearch%\ (which
+works caselessly) must be in lower case, because these lookups are not
+case-independent.
+
+.index \"+caseful"\
+To allow for the possibility of caseful address list matching, if an item in
+an address list is the string `+caseful', the original case of the local
+part is restored for any comparisons that follow, and string comparisons are no
+longer case-independent. This does not affect the domain, which remains in
+lower case. However, although independent matches on the domain alone are still
+performed caselessly, regular expressions that match against an entire address
+become case-sensitive after `+caseful' has been seen.
+
+
+.section Local part lists
+.rset SECTlocparlis "~~chapter.~~section"
+.index list||local part list
+.index local part||list
+Case-sensitivity in local part lists is handled in the same way as for address
+lists, as just described. The `+caseful' item can be used if required. In a
+setting of the \local@_parts\ option in a router with \caseful@_local@_part\
+set false, the subject is lowercased and the matching is initially
+case-insensitive. In this case, `+caseful' will restore case-sensitive matching
+in the local part list, but not elsewhere in the router. If
+\caseful@_local@_part\ is set true in a router, matching in the \local@_parts\
+option is case-sensitive from the start.
+
+If a local part list is indirected to a file (see section ~~SECTfilnamlis),
+comments are handled in the same way as address lists -- they are recognized
+only if the @# is preceded by white space or the start of the line.
+Otherwise, local part lists are matched in the same way as domain lists, except
+that the special items that refer to the local host (\"@@"\, \"@@[]"\,
+\"@@mx@_any"\, \"@@mx@_primary"\, and \"@@mx@_secondary"\) are not recognized.
+Refer to section ~~SECTdomainlist for details of the other available item
+types.
+
+
+
+.
+.
+.
+.
+. ============================================================================
+.chapter String expansions
+.set runningfoot "string expansions"
+.rset CHAPexpand ~~chapter
+.index expansion||of strings
+Many strings in Exim's run time configuration are expanded before use. Some of
+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
+below in section ~~SECTexpansionitems onwards. Backslash is used as an escape
+character, as described in the following section.
+
+
+.section Literal text in expanded strings
+.rset SECTlittext "~~chapter.~~section"
+.index 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
+required because the quotes themselves cause interpretation of backslashes when
+the string is read in (see section ~~SECTstrings).
+
+.index expansion||non-expandable substrings
+A portion of the string can specified as non-expandable by placing it between
+two occurrences of \"@\N"\. This is particularly useful for protecting regular
+expressions, which often contain backslashes and dollar signs. For example:
+.display asis
+deny senders = \N^\d{8}[a-z]@some\.site\.example$\N
+.endd
+On encountering the first \"@\N"\, the expander copies subsequent characters
+without interpretation until it reaches the next \"@\N"\ or the end of the
+string.
+
+
+.section Character escape sequences in expanded strings
+.index expansion||escape sequences
+A backslash followed by one of the letters `n', `r', or `t' in an expanded
+string is recognized as an escape sequence for the character newline, carriage
+return, or tab, respectively. A backslash followed by up to three octal digits
+is recognized as an octal encoding for a single character, and a backslash
+followed by `x' and up to two hexadecimal digits is a hexadecimal encoding.
+
+These escape sequences are also recognized in quoted strings when they are read
+in. Their interpretation in expansions as well is useful for unquoted strings,
+and for other cases such as looked-up strings that are then expanded.
+
+.section Testing string expansions
+.index expansion||testing
+.index testing||string expansion
+.index \-be-\ option
+Many expansions can be tested by calling Exim with the \-be-\ option. This takes
+the command arguments, or lines from the standard input if there are no
+arguments, runs them through the string expansion code, and writes the results
+to the standard output. Variables based on configuration values are set up, but
+since no message is being processed, variables such as \$local@_part$\ have no
+value. Nevertheless the \-be-\ option can be useful for checking out file and
+database lookups, and the use of expansion operators such as \sg\, \substr\ and
+\nhash\.
+
+Exim gives up its root privilege when it is called with the \-be-\ option, and
+instead runs under the uid and gid it was called with, to prevent users from
+using \-be-\ for reading files to which they do not have access.
+
+
+.section Expansion items
+.rset SECTexpansionitems "~~chapter.~~section"
+The following items are recognized in expanded strings. White space may be used
+between sub-items that are keywords or substrings enclosed in braces inside an
+outer set of braces, to improve readability. \**Warning**\: Within braces,
+white space is significant.
+
+.startitems
+
+.item "@$<<variable name>>#$rm{or}#@$@{<<variable name>>@}"
+.index expansion||variables
+Substitute the contents of the named variable, for example
+.display asis
+$local_part
+${domain}
+.endd
+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 $it{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.
+
+.item "@$@{<<op>>:<<string>>@}"
+.index expansion||operators
+The string is first itself expanded, and then the operation specified by <<op>>
+is applied to it. For example,
+.display asis
+${lc:$local_part}
+.endd
+The string starts with the first character after the colon, which may be
+leading white space. A list of operators is given in section ~~SECTexpop 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.
+
+.item "@$@{extract@{<<key>>@}@{<<string1>>@}@{<<string2>>@}@{<<string3>>@}@}"
+.index 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:
+.display
+<<key1>> = <<value1>> <<key2>> = <<value2>> ...
+.endd
+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
+key is not found. If @{<<string2>>@} is also omitted, the value that was
+extracted is used. Thus, for example, these two expansions are identical, and
+yield `2001':
+.display
+@$@{extract@{gid@}{uid=1984 gid=2001@}@}
+@$@{extract@{gid@}{uid=1984 gid=2001@}@{@$value@}@}
+.endd
+Instead of @{<<string3>>@} the word `fail' (not in curly brackets) can appear,
+for example:
+.display
+@$@{extract@{Z@}@{A=... B=...@}@{@$value@} fail @}
+.endd
+@{<<string2>>@} must be present for `fail' to be recognized. When this syntax
+is used, if the extraction fails, the entire string expansion fails in a way
+that can be detected by the code in Exim which 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 which is expanded.
+
+
+.item "@$@{extract@{<<number>>@}@{<<separators>>@}@{<<string1>>@}@{<<string2>>@}@{<<string3>>@}@}"
+.index expansion||extracting substrings by number
+The <<number>> argument must consist entirely of decimal digits,
+apart from leading and trailing whitespace, 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
+argument. You can use \$value$\ in <<string2>> or \"fail"\ instead of
+<<string3>> as before.
+
+The fields in the string are separated by any one of the characters in the
+separator string. These may include space or tab characters.
+The first field is numbered one. If the number is negative, the fields are
+counted from the end of the string, with the rightmost one numbered -1. If the
+number given is zero, the entire string is returned. If the modulus of the
+number is greater than the number of fields in the string, the result is the
+expansion of <<string3>>, or the empty string if <<string3>> is not provided.
+For example:
+.display asis
+${extract{2}{:}{x:42:99:& Mailer::/bin/bash}}
+.endd
+yields `42', and
+.display asis
+${extract{-4}{:}{x:42:99:& Mailer::/bin/bash}}
+.endd
+yields `99'. Two successive separators mean that the field between them is
+empty (for example, the fifth field above).
+
+
+.item "@$@{hash@{<<string1>>@}@{<<string2>>@}@{<<string3>>@}@}"
+.index hash function||textual
+.index expansion||textual hash
+This is a textual hashing function, and was the first to be implemented in
+early versions of Exim. In current releases, there are other hashing functions
+(numeric, MD5, and SHA-1), which are described below.
+
+The first two strings, after expansion, must be numbers. Call them <<m>> and
+<<n>>. If you are using fixed values for these numbers, that is, if <<string1>>
+and <<string2>> do not change when they are expanded, you can use the
+simpler operator notation that avoids some of the braces:
+.display
+@$@{hash@_<<n>>@_<<m>>:<<string>>@}
+.endd
+The second number is optional (in both notations).
+
+If <<n>> is greater than or equal to the length of the string, the expansion
+item returns the string. Otherwise it computes a new string of length <<n>> by
+applying a hashing function to the string. The new string consists of
+characters taken from the first <<m>> characters of the string
+.display asis
+abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQWRSTUVWXYZ0123456789
+.endd
+If <<m>> is not present the value 26 is used, so that only lower case
+letters appear. For example:
+.display
+@$@{hash@{3@}@{monty@}@} $rm{yields} \"jmg"\
+@$@{hash@{5@}@{monty@}@} $rm{yields} \"monty"\
+@$@{hash@{4@}@{62@}@{monty python@}@} $rm{yields} \"fbWx"\
+.endd
+
+
+.item "@$header@_<<header name>>:#$rm{or}#@$h@_<<header name>>:"
+.item "@$bheader@_<<header name>>:#$rm{or}#@$bh@_<<header name>>:"
+.item "@$rheader@_<<header name>>:#$rm{or}#@$rh@_<<header name>>:"
+.index expansion||header insertion
+.index \$header@_$\
+.index \$bheader@_$\
+.index \$rheader@_$\
+.index header lines||in expansion strings
+.index header lines||character sets
+.index header lines||decoding
+Substitute the contents of the named message header line, for example
+.display asis
+$header_reply-to:
+.endd
+The newline that terminates a header line is not included in the expansion, but
+internal newlines (caused by splitting the header line over several physical
+lines) may be present.
+
+The difference between \rheader\, \bheader\, and \header\ is in the way the
+data in the header line is interpreted.
+.numberpars $.
+\rheader\ gives the original `raw' content of the header line, with no
+processing at all, and without the removal of leading and trailing whitespace.
+.nextp
+.index base64 encoding||in header lines
+\bheader\ removes leading and trailing whitespace, 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.
+.index binary zero||in header line
+If decoding produces a binary zero character, it is replaced by a question mark
+-- this is what Exim does for binary zeros that are actually received in header
+lines.
+.nextp
+\header\ tries to translate the string as decoded by \bheader\ to a standard
+character set. This is an attempt to produce the same string as would be
+displayed on a user's MUA. If translation fails, the \bheader\ string is
+returned. Translation is attempted only on operating systems that support the
+\*iconv()*\ function. This is indicated by the compile-time macro
+\\HAVE@_ICONV\\ in a system Makefile or in \(Local/Makefile)\.
+.endp
+
+In a filter file, the target character set for \header\ can be specified by a
+command of the following form:
+.display asis
+headers charset "UTF-8"
+.endd
+This command affects all references to \$h@_$\ (or \$header@_$\) expansions in
+subsequently obeyed filter commands. In the absence of this command, the target
+character set in a filter is taken from the setting of the \headers@_charset\
+option in the runtime configuration. The value of this option defaults to the
+value of \\HEADERS@_CHARSET\\ in \(Local/Makefile)\. The ultimate default is
+ISO-8859-1.
+
+Header names follow the syntax of RFC 2822, which states that they may contain
+any printing characters except space and colon. Consequently, curly brackets
+$it{do not} terminate header names, and should not be used to enclose them as
+if they were variables. Attempting to do so causes a syntax error.
+
+Only header lines that are common to all copies of a message are visible to
+this mechanism. These are the original header lines that are received with the
+message, and any that are added by
+an ACL \warn\ statement or by
+a system filter. Header lines that are added to a particular copy of a message
+by a router or transport are not accessible.
+
+For incoming SMTP messages, no header lines are visible in ACLs that are obeyed
+before the \\DATA\\ ACL, because the header structure is not set up until the
+message is received. Header lines that are added by \warn\ statements in a
+\\RCPT\\ ACL (for example) are saved until the message's incoming header lines
+are available, at which point they are added. When a \\DATA\\ ACL is running,
+however, header lines added by earlier ACLs are visible.
+
+Upper case and lower case letters are synonymous in header names. If the
+following character is white space, the terminating colon may be omitted, but
+this is not recommended, because you may then forget it when it is needed. When
+white space terminates the header name, it is included in the expanded string.
+If the message does not contain the given header, the expansion item is
+replaced by an empty string. (See the \def\ condition in section ~~SECTexpcond
+for a means of testing for the existence of a header.)
+
+If there is more than one header with the same name, they are all concatenated
+to form the substitution string, up to a maximum length of 64K. A newline
+character is inserted between each line.
+For the \header\ expansion, for those headers that contain lists of addresses,
+a comma is also inserted at the junctions between lines. This does not happen
+for the \rheader\ expansion.
+
+
+
+.item "@$@{hmac@{<<hashname>>@}@{<<secret>>@}@{<<string>>@}@}"
+.index expansion||hmac hashing
+This function uses cryptographic hashing (either MD5 or SHA-1) to convert a
+shared secret and some text into a message authentication code, as specified in
+RFC 2104.
+This differs from \"@$@{md5:secret@_text...@}"\ or
+\"@$@{sha1:secret@_text...@}"\ in that the hmac step adds a signature to the
+cryptographic hash, allowing for authentication that is not possible with MD5
+or SHA-1 alone.
+The hash name must expand to either \"md5"\ or \"sha1"\ at present. For
+example:
+.display asis
+${hmac{md5}{somesecret}{$primary_hostname $tod_log}}
+.endd
+For the hostname \*mail.example.com*\ and time 2002-10-17 11:30:59, this
+produces:
+.display asis
+dd97e3ba5d1a61b5006108f8c8252953
+.endd
+As an example of how this might be used, you might put in the main part of
+an Exim configuration:
+.display asis
+SPAMSCAN_SECRET=cohgheeLei2thahw
+.endd
+In a router or a transport you could then have:
+.display asis
+headers_add = \
+ X-Spam-Scanned: ${primary_hostname} ${message_id} \
+ ${hmac{md5}{SPAMSCAN_SECRET}\
+ {${primary_hostname},${message_id},$h_message-id:}}
+.endd
+Then given a message, you can check where it was scanned by looking at the
+::X-Spam-Scanned:: header line. If you know the secret, you can check that this
+header line is authentic by recomputing the authentication code from the host
+name, message ID and the ::Message-id:: header line. This can be done using
+Exim's \-be-\ option, or by other means, for example by using the
+\*hmac@_md5@_hex()*\ function in Perl.
+
+
+
+.item "@${if <<condition>> @{<<string1>>@}@{<<string2>>@}@}"
+.index expansion||conditional
+If <<condition>> is true, <<string1>> is expanded and replaces the whole item;
+otherwise <<string2>> is used. For example,
+.display asis
+${if eq {$local_part}{postmaster} {yes}{no} }
+.endd
+The second string need not be present; if it is not and the condition is not
+true, the item is replaced with nothing. Alternatively, the word `fail' may be
+present instead of the second string (without any curly brackets). In this
+case, the expansion is forced to fail if the condition is not true. The
+available conditions are described in section ~~SECTexpcond below.
+
+
+.item "@$@{length@{<<string1>>@}@{<<string2>>@}@}"
+.index expansion||string truncation
+The \length\ item is used to extract the initial portion of a string. Both
+strings are expanded, and the first one must yield a number, <<n>>, say. If you
+are using a fixed value for the number, that is, if <<string1>> does not change
+when expanded, you can use the simpler operator notation that avoids some of
+the braces:
+.display
+@$@{length@_<<n>>:<<string>>@}
+.endd
+The result of this item is either the first <<n>> characters or the whole
+of <<string2>>, whichever is the shorter. Do not confuse \length\ with
+\strlen\, which gives the length of a string.
+
+
+.item "@${lookup@{<<key>>@} <<search type>> @{<<file>>@} @{<<string1>>@} @{<<string2>>@}@}"
+.item "@${lookup <<search type>> @{<<query>>@} @{<<string1>>@} @{<<string2>>@}@}"
+.index expansion||lookup in
+.index file||lookup
+.index lookup||in expanded string
+These items specify data lookups in files and databases, as discussed in
+chapter ~~CHAPfdlookup. The first form is used for single-key lookups, and the
+second is used for query-style lookups. The <<key>>, <<file>>, and <<query>>
+strings are expanded before use.
+
+If there is any white space in a lookup item which is part of a filter command,
+a retry or rewrite rule, a routing rule for the \%manualroute%\ router, or any
+other place where white space is significant, the lookup item must be enclosed
+in double quotes. The use of data lookups in users' filter files may be locked
+out by the system administrator.
+
+.index \$value$\
+If the lookup succeeds, <<string1>> is expanded and replaces the entire item.
+During its expansion, the variable \$value$\ contains the data returned by the
+lookup. Afterwards it reverts to the value it had previously (at the outer
+level it is empty). If the lookup fails, <<string2>> is expanded and replaces
+the entire item. If @{<<string2>>@} is omitted, the replacement is null on
+failure. Alternatively, <<string2>> can itself be a nested lookup, thus
+providing a mechanism for looking up a default value when the original lookup
+fails.
+
+If a nested lookup is used as part of <<string1>>, \$value$\ contains the data
+for the outer lookup while the parameters of the second lookup are expanded,
+and also while <<string2>> of the second lookup is expanded, should the second
+lookup fail.
+
+Instead of @{<<string2>>@} the word `fail' can appear, and in this case, if the
+lookup fails, the entire expansion is forced to fail. If both @{<<string1>>@}
+and @{<<string2>>@} are omitted, the result is the looked up value in the case
+of a successful lookup, and nothing in the case of failure.
+
+For single-key lookups, the string `partial' is permitted to precede the
+search type in order to do partial matching, and $*$ or $*$@@ may follow a
+search type to request default lookups if the key does not match (see sections
+~~SECTdefaultvaluelookups and ~~SECTpartiallookup for details).
+
+.index numerical variables (\$1$\, \$2$\, etc)||in lookup expansion
+If a partial search is used, the variables \$1$\ and \$2$\ contain the wild
+and non-wild parts of the key during the expansion of the replacement text.
+They return to their previous values at the end of the lookup item.
+
+This example looks up the postmaster alias in the conventional alias file:
+.display asis
+${lookup {postmaster} lsearch {/etc/aliases} {$value}}
+.endd
+This example uses NIS+ to look up the full name of the user corresponding to
+the local part of an address, forcing the expansion to fail if it is not found:
+.display asis
+${lookup nisplus {[name=$local_part],passwd.org_dir:gcos} \
+ {$value}fail}
+.endd
+
+
+.item "@$@{nhash@{<<string1>>@}@{<<string2>>@}@{<<string3>>@}@}"
+.index expansion||numeric hash
+.index hash function||numeric
+The three strings are expanded; the first two must yield numbers. Call them
+<<n>> and <<m>>. If you are using fixed values for these numbers, that is, if
+<<string1>> and <<string2>> do not change when they are expanded, you can use
+the simpler operator notation that avoids some of the braces:
+.display
+@$@{nhash@_<<n>>@_<<m>>:<<string>>@}
+.endd
+The second number is optional (in both notations). If there is only one number,
+the result is a number in the range 0--<<n>>-1. Otherwise, the string is
+processed by a div/mod hash function that returns two numbers, separated by a
+slash, in the ranges 0 to <<n>>-1 and 0 to <<m>>-1, respectively. For example,
+.display asis
+${nhash{8}{64}{supercalifragilisticexpialidocious}}
+.endd
+returns the string `6/33'.
+
+
+
+.item "@$@{perl@{<<subroutine>>@}@{<<arg>>@}@{<<arg>>@}...@}"
+.index Perl||use in expanded string
+.index expansion||calling Perl from
+This item is available only if Exim has been built to include an embedded Perl
+interpreter. The subroutine name and the arguments are first separately
+expanded, and then the Perl subroutine is called with those arguments. No
+additional arguments need be given; the maximum number permitted, including the
+name of the subroutine, is nine.
+
+The return value of the subroutine is inserted into the expanded string, unless
+the return value is \undef\. In that case, the expansion fails in the same way
+as an explicit `fail' on a lookup item.
+The return value is a scalar. Whatever you return is evaluated in a scalar
+context. For example, if you return the name of a Perl vector, the
+return value is the size of the vector, not its contents.
+
+If the subroutine exits by calling Perl's \die\ function, the expansion fails
+with the error message that was passed to \die\. More details of the embedded
+Perl facility are given in chapter ~~CHAPperl.
+
+The \%redirect%\ router has an option called \forbid@_filter@_perl\ which locks
+out the use of this expansion item in filter files.
+
+
+.item "@$@{readfile@{<<file name>>@}@{<<eol string>>@}@}"
+.index expansion||inserting an entire file
+.index file||inserting into expansion
+The file name and end-of-line string are first expanded separately. The file is
+then read, and its contents replace the entire item. All newline characters in
+the file are replaced by the end-of-line string if it is present. Otherwise,
+newlines are left in the string.
+String expansion is not applied to the contents of the file. If you want this,
+you must wrap the item in an \expand\ operator. If the file cannot be read, the
+string expansion fails.
+
+The \%redirect%\ router has an option called \forbid@_filter@_readfile\ which
+locks out the use of this expansion item in filter files.
+
+
+
+.item "@$@{readsocket@{<<name>>@}@{<<request>>@}@{<<timeout>>@}@{<<eol string>>@}@{<<fail string>>@}@}"
+.index expansion||inserting from a socket
+.index socket, use of in expansion
+This item inserts data that is read from a Unix domain socket into the expanded
+string. The minimal way of using it uses just two arguments:
+.display asis
+${readsocket{/socket/name}{request string}}
+.endd
+Exim connects to the socket, writes the request string (unless it is an
+empty string) and reads from the socket until an end-of-file is read. A timeout
+of 5 seconds is applied. Additional, optional arguments extend what can be
+done. Firstly, you can vary the timeout. For example:
+.display asis
+${readsocket{/socket/name}{request-string}{3s}}
+.endd
+A fourth argument allows you to change any newlines that are in the data
+that is read, in the same way as for \readfile\ (see above). This example turns
+them into spaces:
+.display asis
+${readsocket{/socket/name}{request-string}{3s}{ }}
+.endd
+As with all expansions, the substrings are expanded before the processing
+happens. Errors in these sub-expansions cause the expansion to fail. In
+addition, the following errors can occur:
+.numberpars $.
+Failure to create a socket file descriptor;
+.nextp
+Failure to connect the socket;
+.nextp
+Failure to write the request-string;
+.nextp
+Timeout on reading from the socket.
+.endp
+By default, any of these errors causes the expansion to fail. However, if
+you supply a fifth substring, it is expanded and used when any of the above
+errors occurs. For example:
+.display asis
+${readsocket{/socket/name}{request-string}{3s}{\n}\
+ {socket failure}}
+.endd
+You can test for the existence of the socket by wrapping this expansion in
+\"@$@{if exists"\, but there is a race condition between that test and the
+actual opening of the socket, so it is safer to use the fifth argument if you
+want to be absolutely sure of avoiding an expansion error for a non-existent
+socket.
+
+The \%redirect%\ router has an option called \forbid@_filter@_readsocket\ which
+locks out the use of this expansion item in filter files.
+
+.item "@$rheader@_<<header name>>:#$rm{or}#@$rh@_<<header name>>:"
+This item inserts `raw' header lines. It is described with the \header\
+expansion item above.
+
+
+
+.item "@$@{run@{<<command>> <<args>>@}@{<<string1>>@}@{<<string2>>@}@}"
+.index expansion||running a command
+The command and its arguments are first expanded separately, and then the
+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.
+.index return code||from \run\ expansion
+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.
+
+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:
+.display asis
+if "${run{x y z}{}}$runrc" is 1 then ...
+ elif $runrc is 2 then ...
+ ...
+endif
+.endd
+If execution of the command fails (for example, the command does not exist),
+the return code is 127 -- the same code that shells use for non-existent
+commands.
+
+\**Warning**\: In a router or transport, you cannot assume the order in which
+option values are expanded, except for those pre-conditions whose order of
+testing is documented. Therefore, you cannot reliably expect to set \$runrc$\
+by the expansion of one option, and use it in another.
+
+The \%redirect%\ router has an option called \forbid@_filter@_run\ which locks
+out the use of this expansion item in filter files.
+
+
+.item "@$@{sg@{<<subject>>@}@{<<regex>>@}@{<<replacement>>@}@}"
+.index expansion||string substitution
+This item works like Perl's substitution operator (s) with the global (/g)
+option; hence its name. However, unlike the Perl equivalent, Exim does not
+modify the subject string; instead it returns the modified string for insertion
+into the overall expansion. The item takes three arguments: the subject string,
+a regular expression, and a substitution string. For example
+.display asis
+${sg{abcdefabcdef}{abc}{xyz}}
+.endd
+yields `xyzdefxyzdef'. Because all three arguments are expanded before use, if
+any @$ or @\ characters are required in the regular expression or in the
+substitution string, they have to be escaped. For example
+.display asis
+${sg{abcdef}{^(...)(...)\$}{\$2\$1}}
+.endd
+yields `defabc', and
+.display asis
+${sg{1=A 4=D 3=C}{\N(\d+)=\N}{K\$1=}}
+.endd
+yields `K1=A K4=D K3=C'.
+Note the use of \"@\N"\ to protect the contents of the regular expression from
+string expansion.
+
+
+
+.item "@$@{substr@{<<string1>>@}@{<<string2>>@}@{<<string3>>@}@}"
+.index \substr\
+.index substring extraction
+.index expansion||substring extraction
+The three strings are expanded; the first two must yield numbers. Call them
+<<n>> and <<m>>. If you are using fixed values for these numbers, that is, if
+<<string1>> and <<string2>> do not change when they are expanded, you can use
+the simpler operator notation that avoids some of the braces:
+.display
+@$@{substr@_<<n>>@_<<m>>:<<string>>@}
+.endd
+The second number is optional (in both notations).
+
+The \substr\ item can be used to extract more general substrings than \length\.
+The first number, <<n>>, is a starting offset, and <<m>> is the length
+required. For example
+.display asis
+${substr{3}{2}{$local_part}}
+.endd
+If the starting offset is greater than the string length the result is the null
+string; if the length plus starting offset is greater than the string length,
+the result is the right-hand part of the string, starting from the given
+offset. The first character in the string has offset zero.
+
+The \substr\ expansion item can take negative offset values to count
+from the right-hand end of its operand. The last character is offset -1, the
+second-last is offset -2, and so on. Thus, for example,
+.display asis
+${substr{-5}{2}{1234567}}
+.endd
+yields `34'. If the absolute value of a negative offset is greater than the
+length of the string, the substring starts at the beginning of the string, and
+the length is reduced by the amount of overshoot. Thus, for example,
+.display asis
+${substr{-5}{2}{12}}
+.endd
+yields an empty string, but
+.display asis
+${substr{-3}{2}{12}}
+.endd
+yields `1'.
+
+If the second number is omitted from \substr\, the remainder of the string is
+taken if the offset was positive. If it was negative, all characters in the
+string preceding the offset point are taken. For example, an offset of -1 and
+no length yields all but the last character of the string.
+
+
+
+.item "@$@{tr@{<<subject>>@}@{<<characters>>@}@{<<replacements>>@}@}"
+.index expansion||character translation
+This item does single-character translation on its subject string. The second
+argument is a list of characters to be translated in the subject string. Each
+matching character is replaced by the corresponding character from the
+replacement list. For example
+.display asis
+${tr{abcdea}{ac}{13}}
+.endd
+yields `1b3de1'. If there are duplicates in the second character string, the
+last occurrence is used. If the third string is shorter than the second, its
+last character is replicated. However, if it is empty, no translation takes
+place.
+
+.enditems
+
+
+.section Expansion operators
+.rset SECTexpop "~~chapter.~~section"
+.index expansion||operators
+For expansion items that perform transformations on a single argument string,
+the `operator' notation is used because it is simpler and uses fewer braces.
+The substring is first expanded before the operation is applied to it. The
+following operations can be performed:
+
+.startitems
+
+.item "@$@{address:<<string>>@}"
+.index expansion||RFC 2822 address handling
+The string is interpreted as an RFC 2822 address, as it might appear in a
+header line, and the effective address is extracted from it. If the string does
+not parse successfully, the result is empty.
+
+
+.item "@$@{base62:<<digits>>@}"
+.index base62
+.index 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.
+
+.em
+.item "@$@{base62d:<<base-62 digits>>@}"
+.index base62
+.index 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.
+.nem
+
+
+.item "@$@{domain:<<string>>@}"
+.index domain||extraction
+.index expansion||domain extraction
+The string is interpreted as an RFC 2822 address and the domain is extracted
+from it. If the string does not parse successfully, the result is empty.
+
+
+.item "@$@{escape:<<string>>@}"
+.index expansion||escaping non-printing characters
+If the string contains any non-printing characters, they are converted to
+escape sequences starting with a backslash. Whether characters with the most
+significant bit set (so-called `8-bit characters') count as printing or not is
+controlled by the \print@_topbitchars\ option.
+
+
+.em
+.item "@$@{eval:<<string>>@}"
+.item "@$@{eval10:<<string>>@}"
+.index expansion||expression evaluation
+.index 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.
+
+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
+they start with a leading zero. This can be useful when processing numbers
+extracted from dates or times, which often do have leading zeros.
+.nem
+
+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:
+.display
+ @$@{eval:1+1@} $rm{yields} 2
+ @$@{eval:1+2*3@} $rm{yields} 7
+ @$@{eval:(1+2)*3@} $rm{yields} 9
+.endd
+As a more realistic example, in an ACL you might have
+.display asis
+deny message = Too many bad recipients
+ condition = \
+ ${if and { \
+ {>{$rcpt_count}{10}} \
+ { \
+ < \
+ {$recipients_count} \
+ {${eval:$rcpt_count/2}} \
+ } \
+ }{yes}{no}}
+.endd
+The condition is true if there have been more than 10 \\RCPT\\ commands and
+fewer than half of them have resulted in a valid recipient.
+
+
+.item "@$@{expand:<<string>>@}"
+.index expansion||re-expansion of substring
+The \expand\ operator causes a string to be expanded for a second time. For
+example,
+.display asis
+${expand:${lookup{$domain}dbm{/some/file}{$value}}}
+.endd
+first looks up a string in a file while expanding the operand for \expand\, and
+then re-expands what it has found.
+
+
+.item "@$@{from@_utf8:<<string>>@}"
+.index Unicode
+.index UTF-8||conversion from
+.index expansion||UTF-8 conversion
+The world is slowly moving towards Unicode, although there are no standards for
+email yet. However, other applications (including some databases) are starting
+to store data in Unicode, using UTF-8 encoding. This operator converts from a
+UTF-8 string to an ISO-8859-1 string. UTF-8 code values greater than 255 are
+converted to underscores. The input must be a valid UTF-8 string. If it is not,
+the result is an undefined sequence of bytes.
+
+Unicode code points with values less than 256 are compatible with ASCII and
+ISO-8859-1 (also known as Latin-1).
+For example, character 169 is the copyright symbol in both cases, though the
+way it is encoded is different. In UTF-8, more than one byte is needed for
+characters with code values greater than 127, whereas ISO-8859-1 is a
+single-byte encoding (but thereby limited to 256 characters). This makes
+translation from UTF-8 to ISO-8859-1 straightforward.
+
+
+.item "@$@{hash@_<<n>>@_<<m>>:<<string>>@}"
+.index hash function||textual
+.index expansion||textual hash
+The \hash\ operator is a simpler interface to the hashing function that can be
+used when the two parameters are fixed numbers (as opposed to strings that
+change when expanded). The effect is the same as
+.display
+@$@{hash@{<<n>>@}@{<<m>>@}@{<<string>>@}@}
+.endd
+See the description of the general \hash\ item above for details. The
+abbreviation \h\ can be used when \hash\ is used as an operator.
+
+
+
+.item "@$@{hex2b64:<<hexstring>>@}"
+.index base64 encoding||conversion from hex
+.index expansion||hex to base64
+This operator converts a hex string into one that is base64 encoded. This can
+be useful for processing the output of the MD5 and SHA-1 hashing functions.
+
+
+.item "@$@{lc:<<string>>@}"
+.index case forcing in strings
+.index string||case forcing
+.index lower casing
+.index expansion||case forcing
+This forces the letters in the string into lower-case, for example:
+.display asis
+${lc:$local_part}
+.endd
+
+
+.item "@$@{length@_<<number>>:<<string>>@}"
+.index expansion||string truncation
+The \length\ operator is a simpler interface to the \length\ function that can
+be used when the parameter is a fixed number (as opposed to a string that
+changes when expanded). The effect is the same as
+.display
+@$@{length@{<<number>>@}@{<<string>>@}@}
+.endd
+See the description of the general \length\ item above for details. Note that
+\length\ is not the same as \strlen\. The abbreviation \l\ can be used when
+\length\ is used as an operator.
+
+
+.item "@$@{local@_part:<<string>>@}"
+.index expansion||local part extraction
+The string is interpreted as an RFC 2822 address and the local part is
+extracted from it. If the string does not parse successfully, the result is
+empty.
+
+
+.item "@$@{mask:<<IP address>>/<<bit count>>@}"
+.index masked IP address
+.index IP address||masking
+.index CIDR notation
+.index expansion||IP address masking
+If the form of the string to be operated on is not an IP address followed by a
+slash and an integer (that is, a network address in CIDR notation), the
+expansion fails. Otherwise, this operator converts the IP address to binary,
+masks off the least significant bits according to the bit count, and converts
+the result back to text, with mask appended. For example,
+.display asis
+${mask:10.111.131.206/28}
+.endd
+returns the string `10.111.131.192/28'. Since this operation is expected to be
+mostly used for looking up masked addresses in files, the result for an IPv6
+address uses dots to separate components instead of colons, because colon
+terminates a key string in lsearch files. So, for example,
+.display asis
+${mask:3ffe:ffff:836f:0a00:000a:0800:200a:c031/99}
+.endd
+returns the string
+.display asis
+3ffe.ffff.836f.0a00.000a.0800.2000.0000/99
+.endd
+Letters in IPv6 addresses are always output in lower case.
+
+
+.item "@$@{md5:<<string>>@}"
+.index MD5 hash
+.index expansion||MD5 hash
+The \md5\ operator computes the MD5 hash value of the string, and returns it as
+a 32-digit hexadecimal number,
+in which any letters are in lower case.
+
+
+.item "@$@{nhash@_<<n>>@_<<m>>:<<string>>@}"
+.index expansion||numeric hash
+.index hash function||numeric
+The \nhash\ operator is a simpler interface to the numeric hashing function
+that can be used when the two parameters are fixed numbers (as opposed to
+strings that change when expanded). The effect is the same as
+.display
+@$@{nhash@{<<n>>@}@{<<m>>@}@{<<string>>@}@}
+.endd
+See the description of the general \nhash\ item above for details.
+
+
+.item "@$@{quote:<<string>>@}"
+.index quoting||in string expansions
+.index expansion||quoting
+The \quote\ operator puts its argument into double quotes if it
+is an empty string or
+contains anything other than letters, digits, underscores, dots, and hyphens.
+Any occurrences of double quotes and backslashes are escaped with a backslash.
+Newlines and carriage returns are converted to \"@\n"\ and \"@\r"\,
+respectively For example,
+.display asis
+${quote:ab"*"cd}
+.endd
+becomes
+.display asis
+"ab\"*\"cd"
+.endd
+The place where this is useful is when the argument is a substitution from a
+variable or a message header.
+
+.item "@$@{quote@_local@_part:<<string>>@}"
+This operator is like \quote\, except that it quotes the string only if
+required to do so by the rules of RFC 2822 for quoting local parts. For
+example, a plus sign would not cause quoting (but it would for \quote\).
+If you are creating a new email address from the contents of \$local@_part$\
+(or any other unknown data), you should always use this operator.
+
+
+.item "@$@{quote@_<<lookup-type>>:<<string>>@}"
+.index quoting||lookup-specific
+This operator applies lookup-specific quoting rules to the string. Each
+query-style lookup type has its own quoting rules which are described with
+the lookups in chapter ~~CHAPfdlookup. For example,
+.display asis
+${quote_ldap:two * two}
+.endd
+returns
+.display asis
+two%20%5C2A%20two
+.endd
+For single-key lookup types, no quoting is ever necessary and this operator
+yields an unchanged string.
+
+
+.item "@$@{rxquote:<<string>>@}"
+.index quoting||in regular expressions
+.index regular expressions||quoting
+The \rxquote\ operator inserts a backslash before any non-alphanumeric
+characters in its argument. This is useful when substituting the values of
+variables or headers inside regular expressions.
+
+
+.item "@$@{rfc2047:<<string>>@}"
+.index expansion||RFC 2047
+This operator encodes text according to the rules of RFC 2047. This is an
+encoding that is used in header lines to encode non-ASCII characters. It is
+assumed that the input string is in the encoding specified by the
+\headers@_charset\ option, which defaults to ISO-8859-1.
+If the string contains only characters in the range 33--126, and no instances
+of the characters
+.display asis
+? = ( ) < > @ , ; : \ " . [ ] _
+.endd
+it is not modified. Otherwise, the result is the RFC 2047 encoding, as a single
+`coded word'.
+
+
+.item "@$@{sha1:<<string>>@}"
+.index SHA-1 hash
+.index expansion||SHA-1 hashing
+The \sha1\ operator computes the SHA-1 hash value of the string, and returns it
+as a 40-digit hexadecimal number, in which any letters are in upper case.
+
+
+.item "@$@{stat:<<string>>@}"
+.index expansion||statting a file
+.index 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
+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.
+
+
+.item "@$@{strlen:<<string>>@}"
+.index expansion||string length
+.index string||length in expansion
+The item is replace by the length of the expanded string, expressed as a
+decimal number. \**Note**\: Do not confuse \strlen\ with \length\.
+
+
+.item "@$@{substr@_<<start>>@_<<length>>:<<string>>@}"
+.index \substr\
+.index substring extraction
+.index expansion||substring expansion
+The \substr\ operator is a simpler interface to the \substr\ function that can
+be used when the two parameters are fixed numbers (as opposed to strings that
+change when expanded). The effect is the same as
+.display
+@$@{substr@{<<start>>@}@{<<length>>@}@{<<string>>@}@}
+.endd
+See the description of the general \substr\ item above for details. The
+abbreviation \s\ can be used when \substr\ is used as an operator.
+
+.em
+.item "@$@{time@_interval:<<string>>@}"
+.index \time@_interval\
+.index time interval||formatting
+The argument (after sub-expansion) must be a sequence of decimal digits that
+represents an interval of time as a number of seconds. It is converted into a
+number of larger units and output in Exim's normal time format, for example,
+\"1w3d4h2m6s"\.
+.nem
+
+.item "@$@{uc:<<string>>@}"
+.index case forcing in strings
+.index string||case forcing
+.index upper casing
+.index expansion||case forcing
+This forces the letters in the string into upper-case.
+
+.enditems
+
+
+
+.section Expansion conditions
+.rset SECTexpcond "~~chapter.~~section"
+.index expansion||conditions
+The following conditions are available for testing by the \@$@{if\ construct
+while expanding strings:
+
+.startitems
+
+.item "!<<condition>>"
+.index expansion||negating a condition
+Preceding any condition with an exclamation mark negates the result of the
+condition.
+
+.item "<<symbolic operator>> @{<<string1>>@}@{<<string2>>@}"
+.index numeric comparison
+.index expansion||numeric comparison
+There are a number of symbolic operators for doing numeric comparisons. They
+are:
+.display
+.tabs 8
+= $t $rm{equal}
+== $t $rm{equal}
+> $t $rm{greater}
+>= $t $rm{greater or equal}
+< $t $rm{less}
+<= $t $rm{less or equal}
+.endd
+For example,
+.display asis
+${if >{$message_size}{10M} ...
+.endd
+Note that the general negation operator provides for inequality testing. The
+two strings must take the form of optionally signed decimal integers,
+optionally followed by one of the letters `K' or `M' (in either upper or lower
+case), signifying multiplication by 1024 or 1024$*$1024, respectively.
+
+.item "crypteq @{<<string1>>@}@{<<string2>>@}"
+.index expansion||encrypted comparison
+.index encrypted strings, comparing
+This condition is included in the Exim binary if it is built to support any
+authentication mechanisms (see chapter ~~CHAPSMTPAUTH). Otherwise, it is
+necessary to define \\SUPPORT@_CRYPTEQ\\ in \(Local/Makefile)\ to get \crypteq\
+included in the binary.
+
+The \crypteq\ condition has two arguments. The first is encrypted and compared
+against the second, which is already encrypted. The second string may be in the
+LDAP form for storing encrypted strings, which starts with the encryption type
+in curly brackets, followed by the data. If the second string does not begin
+with `{' it is assumed to be encrypted with \*crypt()*\
+or \*crypt16()*\ (see below),
+since such strings cannot begin with `{'. Typically this will be a field from a
+password file.
+
+An example of an encrypted string in LDAP form is:
+.display asis
+{md5}CY9rzUYh03PK3k6DJie09g==
+.endd
+If such a string appears directly in an expansion, the curly brackets have to
+be quoted, because they are part of the expansion syntax. For example:
+.display asis
+${if crypteq {test}{\{md5\}CY9rzUYh03PK3k6DJie09g==}{yes}{no}}
+.endd
+The following encryption types
+(whose names are matched case-independently)
+are supported:
+.numberpars $.
+.index MD5 hash
+.index base64 encoding||in encrypted password
+\@{md5@}\ computes the MD5 digest of the first string, and expresses this as
+printable characters to compare with the remainder of the second string. If the
+length of the comparison string is 24, Exim assumes that it is base64 encoded
+(as in the above example). If the length is 32, Exim assumes that it is a
+hexadecimal encoding of the MD5 digest. If the length not 24 or 32, the
+comparison fails.
+.nextp
+.index SHA-1 hash
+\@{sha1@}\ computes the SHA-1 digest of the first string, and expresses this as
+printable characters to compare with the remainder of the second string. If the
+length of the comparison string is 28, Exim assumes that it is base64 encoded.
+If the length is 40, Exim assumes that it is a hexadecimal encoding of the
+SHA-1 digest. If the length is not 28 or 40, the comparison fails.
+.nextp
+.index \*crypt()*\
+\@{crypt@}\ calls the \*crypt()*\ function, which uses only the first eight
+characters of the password.
+.nextp
+.index \*crypt16()*\
+\@{crypt16@}\ calls the \*crypt16()*\ function (also known as \*bigcrypt()*\),
+which uses up to 16 characters of the password.
+.endp
+Exim has its own version of \*crypt16()*\ (which is just a double call to
+\*crypt()*\). For operating systems that have their own version, setting
+\\HAVE@_CRYPT16\\ in \(Local/Makefile)\ when building Exim causes it to use the
+operating system version instead of its own. This option is set by default in
+the OS-dependent \(Makefile)\ for those operating systems that are known to
+support \*crypt16()*\.
+
+If you do not put any curly bracket encryption type in a \crypteq\ comparison,
+the default is either \"@{crypt@}"\ or \"@{crypt16@}"\, as determined by the
+setting of \\DEFAULT@_CRYPT\\ in \(Local/Makefile)\. The default default is
+\"@{crypt@}"\. Whatever the default, you can always use either function by
+specifying it explicitly in curly brackets.
+
+Note that if a password is no longer than 8 characters, the results of
+encrypting it with \*crypt()*\ and \*crypt16()*\ are identical. That means that
+\*crypt16()*\ is backwards compatible, as long as nobody feeds it a password
+longer than 8 characters.
+
+
+.item "def:<<variable name>>"
+.index expansion||checking for empty variable
+The \def\ condition must be followed by the name of one of the expansion
+variables defined in section ~~SECTexpvar. The condition is true if the named
+expansion variable does not contain the empty string, for example
+.display asis
+${if def:sender_ident {from $sender_ident}}
+.endd
+Note that the variable name is given without a leading \@$\ character. If the
+variable does not exist, the expansion fails.
+
+.item "def:header@_<<header name>>:##or##def:h@_<<header name>>:"
+.index expansion||checking header line existence
+This condition is true if a message is being processed and the named header
+exists in the message. For example,
+.display asis
+${if def:header_reply-to:{$h_reply-to:}{$h_from:}}
+.endd
+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.
+
+.item "eq @{<<string1>>@}@{<<string2>>@}"
+.item "eqi @{<<string1>>@}@{<<string2>>@}"
+.index string||comparison
+.index expansion||string comparison
+The two substrings are first expanded. The condition is true if the two
+resulting strings are identical: for \eq\ the comparison includes the case of
+letters, whereas for \eqi\ the comparison is case-independent.
+
+.item "exists @{<<file name>>@}"
+.index expansion||file existence test
+.index file||existence test
+The substring is first expanded and then interpreted as an absolute path. The
+condition is true if the named file (or directory) exists. The existence test
+is done by calling the \*stat()*\ function. The use of the \exists\ test in
+users' filter files may be locked out by the system administrator.
+
+.item "first@_delivery"
+.index delivery||first
+.index first delivery
+.index expansion||first delivery test
+This condition, which has no data, is true during a message's first delivery
+attempt. It is false during any subsequent delivery attempts.
+
+.em
+.item "ge @{<<string1>>@}@{<<string2>>@}"
+.item "gei @{<<string1>>@}@{<<string2>>@}"
+.index string||comparison
+.index expansion||string comparison
+The two substrings are first expanded. The condition is true if the first
+string is lexically greater than or equal to the second string: for \ge\ the
+comparison includes the case of letters, whereas for \gei\ the comparison is
+case-independent.
+
+.item "gt @{<<string1>>@}@{<<string2>>@}"
+.item "gti @{<<string1>>@}@{<<string2>>@}"
+.index string||comparison
+.index expansion||string comparison
+The two substrings are first expanded. The condition is true if the first
+string is lexically greater than the second string: for \gt\ the comparison
+includes the case of letters, whereas for \gti\ the comparison is
+case-independent.
+.nem
+
+.item "isip @{<<string>>@}" 8
+.item "isip4 @{<<string>>@}"
+.item "isip6 @{<<string>>@}"
+.index IP address||testing string format
+.index string||testing for IP address
+The substring is first expanded, and then tested to see if it has the form of
+an IP address. Both IPv4 and IPv6 addresses are valid for \isip\, whereas
+\isip4\ and \isip6\ test just for IPv4 or IPv6 addresses, respectively. For
+example, you could use
+.display asis
+${if isip4{$sender_host_address}...
+.endd
+to test which version of IP an incoming SMTP connection is using.
+
+
+.item "ldapauth @{<<ldap query>>@}"
+.index LDAP||use for authentication
+.index expansion||LDAP authentication test
+This condition supports user authentication using LDAP. See section ~~SECTldap
+for details of how to use LDAP in lookups and the syntax of queries. For this
+use, the query must contain a user name and password. The query itself is not
+used, and can be empty. The condition is true if
+the password is not empty, and the user name and password are accepted by the
+LDAP server. An empty password is rejected without calling LDAP because LDAP
+binds with an empty password are considered anonymous regardless of
+the username, and will succeed in most configurations.
+See chapter ~~CHAPSMTPAUTH for details of SMTP authentication, and chapter
+~~CHAPplaintext for an example of how this can be used.
+
+
+.em
+.item "le @{<<string1>>@}@{<<string2>>@}"
+.item "lei @{<<string1>>@}@{<<string2>>@}"
+.index string||comparison
+.index expansion||string comparison
+The two substrings are first expanded. The condition is true if the first
+string is lexically less than or equal to the second string: for \le\ the
+comparison includes the case of letters, whereas for \lei\ the comparison is
+case-independent.
+
+.item "lt @{<<string1>>@}@{<<string2>>@}"
+.item "lti @{<<string1>>@}@{<<string2>>@}"
+.index string||comparison
+.index expansion||string comparison
+The two substrings are first expanded. The condition is true if the first
+string is lexically less than the second string: for \lt\ the comparison
+includes the case of letters, whereas for \lti\ the comparison is
+case-independent.
+.nem
+
+
+.item "match @{<<string1>>@}@{<<string2>>@}"
+.index expansion||regular expression comparison
+.index regular expressions||match in expanded string
+The two substrings are first expanded. The second is then treated as a regular
+expression and applied to the first. Because of the pre-expansion, if the
+regular expression contains dollar, or backslash characters, they must be
+escaped. Care must also be taken if the regular expression contains braces
+(curly brackets). A closing brace must be escaped so that it is not taken as a
+premature termination of <<string2>>. The easiest approach is to use the
+\"@\N"\ feature to disable expansion of the regular expression.
+For example,
+.display asis
+${if match {$local_part}{\N^\d{3}\N} ...
+.endd
+If the whole expansion string is in double quotes, further escaping of
+backslashes is also required.
+
+The condition is true if the regular expression match succeeds.
+.em
+The regular expression is not required to begin with a circumflex
+metacharacter, but if there is no circumflex, the expression is not anchored,
+and it may match anywhere in the subject, not just at the start. If you want
+the pattern to match at the end of the subject, you must include the \"@$"\
+metacharacter at an appropriate point.
+.nem
+
+.index numerical variables (\$1$\, \$2$\, etc)||in \if\ expansion
+At the start of an \if\ expansion the values of the numeric variable
+substitutions \$1$\ etc. are remembered. Obeying a \match\ condition that
+succeeds causes them to be reset to the substrings of that condition and they
+will have these values during the expansion of the success string. At the end
+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.
+
+.em
+.item "match@_domain @{<<string1>>@}@{<<string2>>@}"
+.item "match@_address @{<<string1>>@}@{<<string2>>@}"
+.item "match@_local@_part @{<<string1>>@}@{<<string2>>@}"
+.index domain list||in expansion condition
+.index address list||in expansion condition
+.index 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:
+.display asis
+${if match_domain{a.b.c}{x.y.z:a.b.c:p.q.r}{yes}{no}}
+.endd
+In each case, the second argument may contain any of the allowable items for a
+list of the appropriate type. Also, because the second argument (after
+expansion) is a standard form of list, it is possible to refer to a named list.
+Thus, you can use conditions like this:
+.display asis
+${if match_domain{$domain}{+local_domains}{...
+.endd
+.index \"+caseful"\
+For address lists, the matching starts off caselessly, but the \"+caseful"\
+item can be used, as in all address lists, to cause subsequent items to
+have their local parts matched casefully. Domains are always matched
+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.
+.nem
+
+.item "pam {<<string1>>:<<string2>>:...@}"
+.index PAM authentication
+.index \\AUTH\\||with PAM
+.index Solaris||PAM support
+.index expansion||PAM authentication test
+\*Pluggable Authentication Modules*\
+(\?http://www.kernel.org/pub/linux/libs/pam/?\)
+are a facility which is available in the latest releases of Solaris and in some
+GNU/Linux distributions. The Exim support, which is intended for use in
+conjunction with the SMTP \\AUTH\\ command, is available only if Exim is
+compiled with
+.display asis
+SUPPORT_PAM=yes
+.endd
+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.
+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
+the authentication function. In the simple case there will only be one request,
+for a password, so the data consists of just two strings.
+
+There can be problems if any of the strings are permitted to contain colon
+characters. In the usual way, these have to be doubled to avoid being taken as
+separators. If the data is being inserted from a variable, the \sg\ expansion
+item can be used to double any existing colons. For example, the configuration
+of a LOGIN authenticator might contain this setting:
+.display asis
+server_condition = ${if pam{$1:${sg{$2}{:}{::}}}{yes}{no}}
+.endd
+For a PLAIN authenticator you could use:
+.display asis
+server_condition = ${if pam{$2:${sg{$3}{:}{::}}}{yes}{no}}
+.endd
+In some operating systems, PAM authentication can be done only from a process
+running as root. Since Exim is running as the Exim user when receiving
+messages, this means that PAM cannot be used directly in those systems.
+A patched version of the \*pam@_unix*\ module that comes with the
+Linux PAM package is available from \?http:@/@/www.e-admin.de/pam@_exim/?\.
+The patched module allows one special uid/gid combination, in addition to root,
+to authenticate. If you build the patched module to allow the Exim user and
+group, PAM can then be used from an Exim authenticator.
+
+
+.item "pwcheck {<<string1>>:<<string2>>@}"
+.index \*pwcheck*\ daemon
+.index Cyrus
+.index expansion||\*pwcheck*\ authentication test
+This condition supports user authentication using the Cyrus \*pwcheck*\ daemon.
+This is one way of making it possible for passwords to be checked by a process
+that is not running as root.
+\**Note:**\ The use of \*pwcheck*\ is now deprecated. Its replacement is
+\*saslauthd*\ (see below).
+
+The pwcheck support is not included in Exim by default. You need to specify
+the location of the pwcheck daemon's socket in \(Local/Makefile)\ before
+building Exim. For example:
+.display asis
+CYRUS_PWCHECK_SOCKET=/var/pwcheck/pwcheck
+.endd
+You do not need to install the full Cyrus software suite in order to use
+the pwcheck daemon. You can compile and install just the daemon alone
+from the Cyrus SASL library. Ensure that \*exim*\ is the only user that has
+access to the \(/var/pwcheck)\ directory.
+
+The \pwcheck\ condition takes one argument, which must be the user name and
+password, separated by a colon. For example, in a LOGIN authenticator
+configuration, you might have this:
+.display asis
+server_condition = ${if pwcheck{$1:$2}{1}{0}}
+.endd
+
+.item "queue@_running"
+.index queue runner||detecting when delivering from
+.index expansion||queue runner test
+This condition, which has no data, is true during delivery attempts that are
+initiated by queue runner processes, and false otherwise.
+
+
+.item "radius {<<authentication string>>@}"
+.index Radius
+.index expansion||Radius authentication
+Radius authentication (RFC 2865) is supported in a similar way to PAM. You must
+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.
+You may also have to supply a suitable setting in \\EXTRALIBS\\ so that the
+Radius library can be found when Exim is linked.
+The string specified by \\RADIUS@_CONFIG@_FILE\\ is expanded and passed to the
+Radius client library, which calls the Radius server. The condition is true if
+the authentication is successful. For example
+.display
+server@_condition = @$@{if radius@{<<arguments>>@}@{yes@}@{no@}@}
+.endd
+
+
+
+.item "saslauthd @{@{<<user>>@}@{<<password>>@}@{<<service>>@}@{<<realm>>@}@}"
+.index \*saslauthd*\ daemon
+.index Cyrus
+.index expansion||\*saslauthd*\ authentication test
+This condition supports user authentication using the Cyrus \*saslauthd*\
+daemon. This replaces the older \*pwcheck*\ daemon, which is now deprecated.
+Using this daemon is one way of making it possible for passwords to be checked
+by a process that is not running as root.
+
+The saslauthd support is not included in Exim by default. You need to specify
+the location of the saslauthd daemon's socket in \(Local/Makefile)\ before
+building Exim. For example:
+.display asis
+CYRUS_SASLAUTHD_SOCKET=/var/state/saslauthd/mux
+.endd
+You do not need to install the full Cyrus software suite in order to use
+the saslauthd daemon. You can compile and install just the daemon alone
+from the Cyrus SASL library.
+
+Up to four arguments can be supplied to the \saslauthd\ condition, but only two
+are mandatory. For example:
+.display asis
+server_condition = ${if saslauthd{{$1}{$2}}{1}{0}}
+.endd
+The service and the realm are optional (which is why the arguments are enclosed
+in their own set of braces). For details of the meaning of the service and
+realm, and how to run the daemon, consult the Cyrus documentation.
+
+.enditems
+
+
+
+.section Combining expansion conditions
+.index expansion||combining conditions
+Several conditions can be tested at once by combining them using the \and\ and
+\or\ combination conditions. Note that \and\ and \or\ are complete conditions
+on their own, and precede their lists of sub-conditions. Each sub-condition
+must be enclosed in braces within the overall braces that contain the list. No
+repetition of \if\ is used.
+
+.startitems
+
+.item "or @{@{<<cond1>>@}@{<<cond2>>@}...@}"
+.index `or' expansion condition
+.index expansion||`or' of conditions
+The sub-conditions are evaluated from left to right. The condition is true if
+any one of the sub-conditions is true.
+For example,
+.display asis
+${if or {{eq{$local_part}{spqr}}{eq{$domain}{testing.com}}}...
+.endd
+When a true sub-condition is found, the following ones are parsed but not
+evaluated. If there are several `match' sub-conditions the values of the
+numeric variables afterwards are taken from the first one that succeeds.
+
+.item "and @{@{<<cond1>>@}@{<<cond2>>@}...@}"
+.index `and' expansion condition
+.index expansion||`and' of conditions
+The sub-conditions are evaluated from left to right. The condition is true if
+all of the sub-conditions are true. If there are several `match'
+sub-conditions, the values of the numeric variables afterwards are taken from
+the last one. When a false sub-condition is found, the following ones are
+parsed but not evaluated.
+
+.enditems
+
+
+
+.section Expansion variables
+.rset SECTexpvar "~~chapter.~~section"
+.index expansion||variables, list of
+
+The variables that are available for use in expansion strings are:
+
+.push
+.indent 2em
+.tempindent 0
+.index numerical variables (\$1$\, \$2$\, etc)
+\$0$\, \$1$\, etc: When a \match\ expansion condition succeeds, these
+variables contain the captured substrings identified by the regular expression
+during subsequent processing of the success string of the containing \if\
+expansion item. They may also be set externally by some other matching process
+which precedes the expansion of the string. For example, the commands available
+in Exim filter files include an \if\ command with its own regular expression
+matching condition.
+
+.tempindent 0
+\$acl@_c0$\ -- \$acl@_c9$\: Values can be placed in these variables by the
+\set\ modifier in an ACL. The values persist throughout the lifetime of an SMTP
+connection. They can be used to pass information between ACLs and different
+invocations of the same ACL.
+When a message is received, the values of these variables are saved with the
+message, and can be accessed by filters, routers, and transports during
+subsequent delivery.
+
+.tempindent 0
+\$acl@_m0$\ -- \$acl@_m9$\: Values can be placed in these variables by the
+\set\ modifier in an ACL. They retain their values while a message is being
+received, but are reset afterwards. They are also reset by \\MAIL\\, \\RSET\\,
+\\EHLO\\, \\HELO\\, and after starting a TLS session.
+When a message is received, the values of these variables are saved with the
+message, and can be accessed by filters, routers, and transports during
+subsequent delivery.
+
+
+.tempindent 0
+\$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.
+
+.tempindent 0
+\$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, the value from the first address is used. See
+chapter ~~CHAProutergeneric for more details.
+\**Note**\: the contents of \$address@_data$\ are visible in user filter files.
+
+If \$address@_data$\ is set when the routers are called to verify an address
+from an ACL, the final value remains available in subsequent conditions in the
+ACL statement. If routing the address caused it to be redirected to a single
+address, the child address is also routed as part of the verification, and in
+this case the final value of \$address@_data$\ is from the child's routing.
+
+.tempindent 0
+\$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 default configuration, if user \r2d2\ has a \(.forward)\
+file containing
+.display asis
+/home/r2d2/savemail
+.endd
+then when the \%address@_file%\ transport is running, \$address@_file$\
+contains `/home/r2d2/savemail'.
+.index Sieve filter||value of \$address@_file$\
+For Sieve filters, the value may be `inbox' or a relative folder name. It is
+then up to the transport configuration to generate an appropriate absolute path
+to the relevant file.
+
+
+.tempindent 0
+\$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.
+
+.index authentication||id
+.tempindent 0
+\$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.
+
+.index sender||authenticated
+.index authentication||sender
+.index \\AUTH\\||on \\MAIL\\ command
+.tempindent 0
+\$authenticated@_sender$\:
+.em
+When acting as a server, Exim takes note of the \\AUTH=\\ parameter on an
+incoming SMTP \\MAIL\\ command
+.nem
+if it believes the sender is sufficiently trusted, as described in section
+~~SECTauthparamail. Unless the data is the string `@<@>', it is set as the
+authenticated sender of the message, and the value is available during delivery
+in the \$authenticated@_sender$\ variable. If the sender is not trusted, Exim
+accepts the syntax of \\AUTH=\\, but ignores the data.
+
+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$\.
+
+
+.index authentication||failure
+.tempindent 0
+\$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'
+(\$sender@_host@_authenticated$\ is empty and \$authentication__failed$\ is set
+to `0') and `tried to authenticate but failed' (\$sender@_host@_authenticated$\
+is empty and \$authentication@_failed$\ is set to `1'). Failure includes any
+negative response to an \\AUTH\\ command, including (for example) an attempt to
+use an undefined mechanism.
+
+
+.index message||body, line count
+.index body of message||line count
+.tempindent 0
+\$body@_linecount$\:
+When a message is being received or delivered, this variable contains the
+number of lines in the message's body.
+
+.index message||body, binary zero count
+.index body of message||binary zero count
+.index binary zero||in message body
+.tempindent 0
+.em
+\$body@_zerocount$\:
+When a message is being received or delivered, this variable contains the
+number of binary zero bytes in the message's body.
+.nem
+
+.tempindent 0
+\$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).
+
+.tempindent 0
+\$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).
+
+.index gid (group id)||caller
+.tempindent 0
+\$caller@_gid$\: The
+.em
+real
+.nem
+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
+incarnation normally contains the Exim gid.
+
+.index uid (user id)||caller
+.tempindent 0
+\$caller@_uid$\: The
+.em
+real
+.nem
+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.
+
+.tempindent 0
+\$compile@_date$\: The date on which the Exim binary was compiled.
+
+.tempindent 0
+\$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.
+
+.index black list (DNS)
+.tempindent 0
+\$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.
+
+.tempindent 0
+\$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.
+
+.tempindent 0
+\$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.
+
+.tempindent 0
+\$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
+have the same domain. Transports can be restricted to handling only one domain
+at a time if the value of \$domain$\ is required at transport time -- this is
+the default for local transports. For further details of the environment in
+which local transports are run, see chapter ~~CHAPenvironment.
+
+.index \delay@_warning@_condition\
+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:
+.numberpars $.
+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.
+.nextp
+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
+used in the expansion of the replacement address, for example, to rewrite
+domains by file lookup.
+.nextp
+With one important exception, whenever a domain list is being scanned,
+\$domain$\ contains the subject domain. \**Exception**\: When a domain list in
+a \sender@_domains\ condition in an ACL is being processed, the subject domain
+is in \$sender@_address@_domain$\ and not in \$domain$\. It works this way so
+that, in a \\RCPT\\ ACL, the sender domain list can be dependent on the
+recipient domain (which is what is in \$domain$\ at this time).
+.nextp
+.index \\ETRN\\||value of \$domain$\
+.index \smtp@_etrn@_command\
+When the \smtp@_etrn@_command\ option is being expanded, \$domain$\ contains
+the complete argument of the \\ETRN\\ command (see section ~~SECTETRN).
+.endp
+
+.tempindent 0
+\$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
+address to a transport, the value is available in that transport. If the
+transport is handling multiple addresses, the value from the first address is
+used.
+
+\$domain@_data$\ is also set when the \domains\ condition in an ACL matches a
+domain by means of a lookup. The data read by the lookup is available during
+the rest of the ACL statement. In all other situations, this variable expands
+to nothing.
+
+.em
+.tempindent 0
+\$exim@_gid$\: This variable contains the numerical value of the Exim group id.
+
+.tempindent 0
+\$exim@_path$\: This variable contains the path to the Exim binary.
+
+.tempindent 0
+\$exim@_uid$\: This variable contains the numerical value of the Exim user id.
+.nem
+
+.tempindent 0
+\$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.
+
+.tempindent 0
+\$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
+explicitly set a home directory for use by a transport; this can be overridden
+by a setting on the transport itself.
+
+When running a filter test via the \-bf-\ option, \$home$\ is set to the value
+of the environment variable \\HOME\\.
+
+.tempindent 0
+\$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
+~~CHAPSMTPAUTH), \$host$\ contains the name of the server to which the client
+is connected.
+.index transport||filter
+.index filter||transport filter
+When used in a transport filter (see chapter ~~CHAPtransportgeneric) \$host$\
+refers to the host involved in the current connection. When a local transport
+is run as a result of a router that sets up a host list, \$host$\ contains the
+name of the first host.
+
+.tempindent 0
+\$host@_address$\:
+This variable is set to the remote host's IP address whenever \$host$\ is set
+for a remote connection.
+
+.tempindent 0
+\$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:
+.display asis
+deny hosts = net-lsearch;/some/file
+ message = $host_data
+.endd
+
+.index host||name lookup, failure of
+.tempindent 0
+\$host@_lookup@_failed$\:
+This variable contains `1' if the message came from a remote host and there was
+an attempt to look up the host's name from its IP address, but the attempt
+failed. Otherwise the value of the variable is `0'.
+.em
+Exim checks that a forward lookup of at least one of the names it receives from
+a reverse lookup yields the original IP address. If this is not the case, Exim
+does not accept the looked up name(s), and \$host@_lookup@_failed$\ is set to
+`1'. Thus, being able to find a name from an IP address (for example, the
+existence of a PTR record in the DNS) is not sufficient on its own for the
+success of a host name lookup.
+.nem
+
+.tempindent 0
+\$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.
+
+.tempindent 0
+\$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.
+
+.tempindent 0
+\$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.
+
+.tempindent 0
+\$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.
+
+
+.tempindent 0
+\$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.
+
+.tempindent 0
+\$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
+session), \$local@_part$\ is not set.
+
+Global address rewriting happens when a message is received, so the value of
+\$local@_part$\ during routing and delivery is the value after rewriting.
+\$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.
+
+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
+\$local@_part@_suffix$\, respectively.
+
+When a message is being delivered to a file, pipe, or autoreply transport as a
+result of aliasing or forwarding, \$local@_part$\ is set to the local part of
+the parent address, not to the file name or command (see \$address@_file$\ and
+\$address@_pipe$\).
+
+When an ACL is running for a \\RCPT\\ command, \$local@_part$\ contains the
+local part of the recipient address.
+
+When a rewrite item is being processed (see chapter ~~CHAPrewrite),
+\$local@_part$\ contains the local part of the address that is being rewritten;
+it can be used in the expansion of the replacement address, for example.
+
+In all cases, all quoting is removed from the local part. For example, for both
+the addresses
+.display asis
+"abc:xyz"@test.example
+abc\:xyz@test.example
+.endd
+the value of \$local@_part$\ is
+.display asis
+abc:xyz
+.endd
+If you use \$local@_part$\ to create another address, you should always wrap it
+inside a quoting operator. For example, in a \%redirect%\ router you could have:
+.display asis
+data = ${quote_local_part:$local_part}@new.domain.example
+.endd
+.em
+\**Note**\: The value of \$local@_part$\ is normally lower cased. If you want
+to process local parts in a case-dependent manner in a router, you can set the
+\caseful@_local@_part\ option (see chapter ~~CHAProutergeneric).
+.nem
+
+.tempindent 0
+\$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
+to a transport, the value is available in that transport. If the transport is
+handling multiple addresses, the value from the first address is used.
+
+\$local@_part@_data$\ is also set when the \local@_parts\ condition in an ACL
+matches a local part by means of a lookup. The data read by the lookup is
+available during the rest of the ACL statement. In all other situations, this
+variable expands to nothing.
+
+.tempindent 0
+\$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$\.
+
+.tempindent 0
+\$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$\.
+
+.tempindent 0
+\$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.
+
+.tempindent 0
+\$local@_user@_gid$\: See \$local@_user@_uid$\.
+
+.tempindent 0
+\$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.
+
+
+.tempindent 0
+\$localhost@_number$\: This contains the expanded value of the
+\localhost@_number\ option. The expansion happens after the main options have
+been read.
+
+.tempindent 0
+\$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.
+
+.index message||age of
+.tempindent 0
+\$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.
+
+.index body of message||expansion variable
+.index message||body, in expansion
+.index binary zero||in message body
+.tempindent 0
+\$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
+variable is set by the \message@_body@_visible\ configuration option; the
+default is 500. Newlines are converted into spaces to make it easier to search
+for phrases that might be split over a line break.
+Binary zeros are also converted into spaces.
+
+.index body of message||expansion variable
+.index message||body, in expansion
+.tempindent 0
+\$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$\.
+
+.index body of message||size
+.index message||body, size
+.tempindent 0
+\$message@_body@_size$\: When a message is being processed, 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$\ and \$body@_linecount$\.
+
+.tempindent 0
+\$message@_headers$\:
+This variable contains a concatenation of all the header lines when a message
+is being processed, except for lines added by routers or transports. The header
+lines are separated by newline characters.
+
+.tempindent 0
+\$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.
+.em
+\**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"\.
+.nem
+
+.index size||of message
+.index message||size
+.tempindent 0
+\$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
+deliveries as they are written. However, there is one special case: during the
+expansion of the \maildir@_tag\ option in the \%appendfile%\ transport while
+doing a delivery in maildir format, the value of \$message@_size$\ is the
+precise size of the file that has been written. See also
+\$message@_body@_size$\ and \$body@_linecount$\.
+
+.index \\RCPT\\||value of \$message@_size$\
+While running an ACL at the time of an SMTP \\RCPT\\ command, \$message@_size$\
+contains the size supplied on the \\MAIL\\ command, or
+-1
+if no size was given. The value may not, of course, be truthful.
+
+.tempindent 0
+\$n0$\ -- \$n9$\: These variables are counters that can be incremented by means
+of the \add\ command in filter files.
+
+.tempindent 0
+\$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.
+
+.tempindent 0
+\$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, in which case \$original@_local@_part$\
+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. This variable differs from
+\$parent@_local@_part$\ 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@_local@_part$\ 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.
+
+
+.index gid (group id)||of originating user
+.index sender||gid
+.tempindent 0
+\$originator@_gid$\: 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.
+
+.index uid (user id)||of originating user
+.index sender||uid
+.tempindent 0
+\$originator@_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.
+
+.tempindent 0
+\$parent@_domain$\: This variable is similar to \$original@_domain$\ (see
+above), except that it refers to the immediately preceding parent address.
+
+.tempindent 0
+\$parent@_local@_part$\: This variable is similar to \$original@_local@_part$\
+(see above), except that it refers to the immediately preceding parent address.
+
+.index pid (process id)||of current process
+.tempindent 0
+\$pid$\: This variable contains the current process id.
+
+.index filter||transport filter
+.index transport||filter
+.tempindent 0
+\$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.
+
+.tempindent 0
+\$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.
+.em
+See also \$smtp@_active@_hostname$\.
+.nem
+
+.tempindent 0
+\$qualify@_domain$\: The value set for this option in the configuration file.
+
+.tempindent 0
+\$qualify@_recipient$\: The value set for this option in the configuration file,
+or if not set, the value of \$qualify@_domain$\.
+
+.tempindent 0
+\$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.
+
+.tempindent 0
+\$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.
+
+.tempindent 0
+\$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.
+
+.tempindent 0
+\$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.
+
+.tempindent 0
+\$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.
+.em
+The value is copied after recipient rewriting has happened, but before the
+\*local@_scan()*\ function is run.
+.nem
+
+.tempindent 0
+\$received@_protocol$\: When a message is being processed, this variable
+contains the name of the protocol by which it was received. See also the
+\-oMr-\ option.
+
+.em
+.tempindent 0
+\$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:
+.display
+require recipients = cdb*@@;/some/file
+deny \*some further test involving*\ @$recipient@_data
+.endd
+\**Warning**\: This variable is set only when a lookup is used as an indexing
+method in the address list, using the semicolon syntax as in the example above.
+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.
+.nem
+
+.tempindent 0
+\$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
+recipients in unprivileged users' filter files. You can use \$recipients$\ only
+.numberpars
+In a system filter file.
+.nextp
+In the \\DATA\\ or non-SMTP ACL, that is, in the final ACL for accepting a
+message.
+.endp
+
+.tempindent 0
+\$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.
+
+.tempindent 0
+\$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.
+
+.tempindent 0
+\$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 same value as \$sender@_address$\, but if, for
+example, an incoming message to a mailing list has been expanded by a router
+which specifies a different address for bounce messages, \$return@_path$\
+subsequently contains the new bounce address, whereas \$sender@_address$\
+always contains the original sender address that was received with the message.
+In other words, \$sender@_address$\ contains the incoming envelope sender, and
+\$return@_path$\ contains the outgoing envelope sender.
+
+.tempindent 0
+\$return@_size@_limit$\: This is an obsolete name for
+\$bounce@_return@_size@_limit$\.
+
+.index return code||from \run\ expansion
+.tempindent 0
+\$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 pre-conditions whose order of
+testing is documented. Therefore, you cannot reliably expect to set \$runrc$\
+by the expansion of one option, and use it in another.
+
+.tempindent 0
+\$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
+.index \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.
+
+.tempindent 0
+\$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$\.
+
+.tempindent 0
+\$sender@_address@_domain$\: The domain portion of \$sender@_address$\.
+
+.tempindent 0
+\$sender@_address@_local@_part$\: The local part portion of \$sender@_address$\.
+
+.em
+.tempindent 0
+\$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:
+.display
+require senders = cdb*@@;/some/file
+deny \*some further test involving*\ @$sender@_data
+.endd
+\**Warning**\: This variable is set only when a lookup is used as an indexing
+method in the address list, using the semicolon syntax as in the example above.
+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.
+.nem
+
+.tempindent 0
+\$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 enabled. The format of the rest of the string
+depends on whether the host issued a \\HELO\\ or \\EHLO\\ SMTP command, and
+whether the host name was verified by looking up its IP address. (Looking up
+the IP address can be forced by the \host@_lookup\ option, independent of
+verification.) A plain host name at the start of the string is a verified host
+name; if this is not present, verification either failed or was not requested.
+A host name in parentheses is 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.
+
+.tempindent 0
+\$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.
+
+.tempindent 0
+\$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.
+
+.tempindent 0
+\$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.
+
+.tempindent 0
+\$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.
+
+If the host name has not previously been looked up, a reference to
+\$sender@_host@_name$\ triggers a lookup (for messages from remote hosts).
+.em
+A looked up name is accepted only if it leads back to the original IP address
+via a forward lookup. If either the reverse or the forward lookup fails, 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'.
+.nem
+
+Exim does not automatically look up every calling host's name. If you want
+maximum efficiency, you should arrange your configuration so that it avoids
+these lookups altogether. The lookup happens only if one or more of the
+following are true:
+.numberpars
+A string containing \$sender@_host@_name$\ is expanded.
+.nextp
+The calling host matches the list in \host@_lookup\. In the default
+configuration, this option is set to $*$, so it must be changed if lookups are
+to be avoided. (In the code, the default for \host@_lookup\ is unset.)
+.nextp
+Exim needs the host name in order to test an item in a host list. The items
+that require this are described in sections ~~SECThoslispatnam and
+~~SECThoslispatnamsk.
+.nextp
+The calling host matches \helo@_try@_verify@_hosts\ or \helo@_verify@_hosts\.
+In this case, the host name is required to compare with the name quoted in any
+\\EHLO\\ or \\HELO\\ commands that the client issues.
+.nextp
+The remote host issues a \\EHLO\\ or \\HELO\\ command that quotes one of the
+domains in \helo@_lookup@_domains\. The default value of this option is
+.display asis
+helo_lookup_domains = @ : @[]
+.endd
+which causes a lookup if a remote host (incorrectly) gives the server's name or
+IP address in an \\EHLO\\ or \\HELO\\ command.
+.endp
+
+.tempindent 0
+\$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.
+
+.tempindent 0
+\$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.
+
+.tempindent 0
+\$sender@_rcvhost$\: This is provided specifically for use in ::Received::
+headers. It starts with either the verified host name (as obtained from a
+.index DNS||reverse lookup
+.index 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=$it{xxxx}' inside the parentheses.
+
+There may also be items of the form `helo=$it{xxxx}' if \\HELO\\ or \\EHLO\\
+was used and its argument was not identical to the real host name or IP
+address, and `ident=$it{xxxx}' if an RFC 1413 ident string is available. If all
+three items are present in the parentheses, a newline and tab are inserted into
+the string, to improve the formatting of the ::Received:: header.
+
+.index \\AUTH\\||argument
+.index \\EXPN\\||argument
+.index \\ETRN\\||argument
+.index \\VRFY\\||argument
+.tempindent 0
+\$smtp@_command@_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.
+
+.tempindent 0
+\$sn0$\ -- \$sn9$\: These variables are copies of the values of the \$n0$\
+-- \$n9$\ accumulators that were current at the end of the system filter file.
+This allows a system filter file to set values that can be tested in users'
+filter files. For example, a system filter could set a value indicating how
+likely it is that a message is junk mail.
+
+.tempindent 0
+\$spool@_directory$\: The name of Exim's spool directory.
+
+.tempindent 0
+\$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.
+
+.tempindent 0
+\$tls@_certificate@_verified$\:
+This variable is set to `1' if a TLS certificate was verified when the message
+was received, and `0' otherwise.
+
+.tempindent 0
+\$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 received over unencrypted
+connections, the variable is empty.
+See chapter ~~CHAPTLS for details of TLS support.
+
+.tempindent 0
+\$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.
+
+.tempindent 0
+\$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.
+
+.tempindent 0
+\$tod@_epoch$\: The time and date as a number of seconds since the start of the
+Unix epoch.
+
+.tempindent 0
+\$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).
+
+.tempindent 0
+\$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.
+
+.tempindent 0
+\$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.
+
+.tempindent 0
+\$tod@_zone$\: This variable contains the numerical value of the local
+timezone, for example: -0500.
+
+.tempindent 0
+\$tod@_zulu$\:
+This variable contains the UTC date and time in `Zulu' format, as specified by
+ISO 8601, for example: 20030221154023Z.
+
+.index \$value$\
+.tempindent 0
+\$value$\: This variable contains the result of an expansion lookup, extraction
+operation, or external command, as described above.
+
+.tempindent 0
+\$version@_number$\: The version number of Exim.
+
+.tempindent 0
+\$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.
+
+.tempindent 0
+\$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.
+.pop
+
+
+
+.
+.
+. ============================================================================
+.chapter Embedded Perl
+.set runningfoot "embedded Perl"
+.rset CHAPperl "~~chapter"
+.index Perl||calling from Exim
+
+Exim can be built to include an embedded Perl interpreter. When this is done,
+Perl subroutines can be called as part of the string expansion process. To make
+use of the Perl support, you need version 5.004 or later of Perl installed on
+your system. To include the embedded interpreter in the Exim binary, include
+the line
+.display asis
+EXIM_PERL = perl.o
+.endd
+in your \(Local/Makefile)\ and then build Exim in the normal way.
+
+Access to Perl subroutines is via a global configuration option called
+.index \perl@_startup\
+\perl@_startup\ and an expansion string operator \@$@{perl ...@}\. If there is
+no \perl@_startup\ option in the Exim configuration file then no Perl
+interpreter is started and there is almost no overhead for Exim (since none of
+the Perl library will be paged in unless used). If there is a \perl@_startup\
+option then the associated value is taken to be Perl code which is executed in
+a newly created Perl interpreter.
+
+The value of \perl@_startup\ is not expanded in the Exim sense, so you do not
+need backslashes before any characters to escape special meanings. The option
+should usually be something like
+.display asis
+perl_startup = do '/etc/exim.pl'
+.endd
+where \(/etc/exim.pl)\ is Perl code which defines any subroutines you want to
+use from Exim. Exim can be configured either to start up a Perl interpreter as
+soon as it is entered, or to wait until the first time it is needed. Starting
+the interpreter at the beginning ensures that it is done while Exim still has
+its setuid privilege, but can impose an unnecessary overhead if Perl is not in
+fact used in a particular run. Also, note that this does not mean that Exim is
+necessarily running as root when Perl is called at a later time. By default,
+the interpreter is started only when it is needed, but this can be changed in
+two ways:
+.numberpars $.
+.index \perl@_at@_start\
+Setting \perl@_at@_start\ (a boolean option) in the configuration requests
+a startup when Exim is entered.
+.nextp
+The command line option \-ps-\ also requests a startup when Exim is entered,
+overriding the setting of \perl@_at@_start\.
+.endp
+There is also a command line option \-pd-\ (for delay) which suppresses the
+initial startup, even if \perl@_at@_start\ is set.
+
+When the configuration file includes a \perl@_startup\ option you can make use
+of the string expansion item to call the Perl subroutines that are defined
+by the \perl@_startup\ code. The operator is used in any of the following
+forms:
+.display asis
+${perl{foo}}
+${perl{foo}{argument}}
+${perl{foo}{argument1}{argument2} ... }
+.endd
+which calls the subroutine \foo\ with the given arguments. A maximum of eight
+arguments may be passed. Passing more than this results in an expansion failure
+with an error message of the form
+.display asis
+Too many arguments passed to Perl subroutine "foo" (max is 8)
+.endd
+The return value of the Perl subroutine is evaluated in a scalar context before
+it is passed back to Exim to be inserted into the expanded string. If the
+return value is \*undef*\, the expansion fails in the same way as an explicit
+`fail' on an \@$@{if ...@}\ or \@$@{lookup...@}\ item.
+If the subroutine aborts by obeying Perl's \die\ function, the expansion fails
+with the error message that was passed to \die\.
+
+Within any Perl code called from Exim, the function \*Exim@:@:expand@_string*\
+is available to call back into Exim's string expansion function. For example,
+the Perl code
+.display asis
+my $lp = Exim::expand_string('$local_part');
+.endd
+makes the current Exim \$local@_part$\ available in the Perl variable \$lp$\.
+Note those are single quotes and not double quotes to protect against
+\$local@_part$\ being interpolated as a Perl variable.
+
+If the string expansion is forced to fail by a `fail' item, the result of
+\*Exim@:@:expand@_string*\ is \undef\. If there is a syntax error in the
+expansion string, the Perl call from the original expansion string fails with
+an appropriate error message, in the same way as if \die\ were used.
+
+.index debugging||from embedded Perl
+.index log||writing from embedded Perl
+Two other Exim functions are available for use from within Perl code.
+\*Exim@:@:debug@_write(<<string>>)*\ writes the string to the standard error
+stream if Exim's debugging is enabled. If you want a newline at the end, you
+must supply it. \*Exim@:@:log@_write(<<string>>)*\ writes the string to Exim's
+main log, adding a leading timestamp. In this case, you should not supply a
+terminating newline.
+
+
+
+.
+.
+.
+.
+. ============================================================================
+.chapter Starting the daemon and the use of network interfaces
+.set runningfoot "starting the daemon"
+.rset CHAPinterfaces "~~chapter"
+.index daemon||starting
+.index interface||listening
+.index network interface
+.index interface||network
+.index IP address||for listening
+.index daemon||listening IP addresses
+.index TCP/IP||setting listening interfaces
+.index TCP/IP||setting listening ports
+
+A host that is connected to a TCP/IP network may have one or more physical
+hardware network interfaces. Each of these interfaces may be configured as one
+or more `logical' interfaces, which are the entities that a program actually
+works with. Each of these logical interfaces is associated with an IP address.
+In addition, TCP/IP software supports `loopback' interfaces (127.0.0.1 in IPv4
+and @:@:1 in IPv6), which do not use any physical hardware. Exim requires
+knowledge about the host's interfaces for use in three different circumstances:
+.numberpars
+When a listening daemon is started, Exim needs to know which interfaces
+and ports to listen on.
+.nextp
+When Exim is routing an address, it needs to know which IP addresses
+are associated with local interfaces. This is required for the correct
+processing of MX lists by removing the local host and others with the
+same or higher priority values. Also, Exim needs to detect cases
+when an address is routed to an IP address that in fact belongs to the
+local host. Unless the \self\ router option or the \allow@_localhost\
+option of the smtp transport is set (as appropriate), this is treated
+as an error situation.
+.nextp
+When Exim connects to a remote host, it may need to know which interface to use
+for the outgoing connection.
+.endp
+
+Exim's default behaviour is likely to be appropriate in the vast majority
+of cases. If your host has only one interface, and you want all its IP
+addresses to be treated in the same way, and you are using only the
+standard SMTP port, you should not need to take any special action. The
+rest of this chapter does not apply to you.
+
+In a more complicated situation you may want to listen only on certain
+interfaces, or on different ports, and for this reason there are a number of
+options that can be used to influence Exim's behaviour. The rest of this
+chapter describes how they operate.
+
+When a message is received over TCP/IP, the interface and port that were
+actually used are set in \$interface@_address$\ and \$interface@_port$\.
+
+
+.section Starting a listening daemon
+When a listening daemon is started (by means of the \-bd-\ command line
+option), the interfaces and ports on which it listens are controlled by the
+following options:
+.numberpars $.
+\daemon@_smtp@_ports\ contains a list of default ports. (For backward
+compatibility, this option can also be specified in the singular.)
+.nextp
+\local@_interfaces\ contains list of interface IP addresses on which to
+listen. Each item may optionally also specify a port.
+.endp
+The default list separator in both cases is a colon, but this can be changed as
+described in section ~~SECTlistconstruct. When IPv6 addresses are involved, it
+is usually best to change the separator to avoid having to double all the
+colons. For example:
+.display asis
+local_interfaces = <; 127.0.0.1 ; \
+ 192.168.23.65 ; \
+ ::1 ; \
+ 3ffe:ffff:836f::fe86:a061
+.endd
+There are two different formats for specifying a port along with an IP address
+in \local@_interfaces\:
+.numberpars
+The port is added onto the address with a dot separator. For example, to listen
+on port 1234 on two different IP addresses:
+.display asis
+local_interfaces = <; 192.168.23.65.1234 ; \
+ 3ffe:ffff:836f::fe86:a061.1234
+.endd
+.nextp
+The IP address is enclosed in square brackets, and the port is added
+with a colon separator, for example:
+.display asis
+local_interfaces = <; [192.168.23.65]:1234 ; \
+ [3ffe:ffff:836f::fe86:a061]:1234
+.endd
+.endp
+When a port is not specified, the value of \daemon@_smtp@_ports\ is used. The
+default setting contains just one port:
+.display asis
+daemon_smtp_ports = smtp
+.endd
+If more than one port is listed, each interface that does not have its own port
+specified listens on all of them. Ports that are listed in
+\daemon@_smtp@_ports\ can be identified either by name (defined in
+\(/etc/services)\) or by number. However, when ports are given with individual
+IP addresses in \local@_interfaces\, only numbers (not names) can be used.
+
+
+.section Special IP listening addresses
+The addresses 0.0.0.0 and @:@:0 are treated specially. They are interpreted
+as `all IPv4 interfaces' and `all IPv6 interfaces', respectively. In each
+case, Exim tells the TCP/IP stack to `listen on all IPv\*x*\ interfaces'
+instead of setting up separate listening sockets for each interface. The
+default value of \local@_interfaces\ is
+.display asis
+local_interfaces = 0.0.0.0
+.endd
+when Exim is built without IPv6 support; otherwise it is:
+.display asis
+local_interfaces = <; ::0 ; 0.0.0.0
+.endd
+Thus, by default, Exim listens on all available interfaces, on the SMTP port.
+
+
+.section Overriding local@_interfaces and daemon@_smtp@_ports
+The \-oX-\ command line option can be used to override the values of
+\daemon@_smtp@_ports\ and/or \local@_interfaces\ for a particular daemon
+instance. Another way of doing this would be to use macros and the \-D-\
+option. However, \-oX-\ can be used by any admin user, whereas modification of
+the runtime configuration by \-D-\ is allowed only when the caller is root or
+exim.
+
+The value of \-oX-\ is a list of items. The default colon separator can be
+changed in the usual way if required. If there are any items that do not
+contain dots or colons (that is, are not IP addresses), the value of
+\daemon@_smtp@_ports\ is replaced by the list of those items. If there are any
+items that do contain dots or colons, the value of \local@_interfaces\ is
+replaced by those items. Thus, for example,
+.display asis
+-oX 1225
+.endd
+overrides \daemon@_smtp@_ports\, but leaves \local@_interfaces\ unchanged,
+whereas
+.display asis
+-oX 192.168.34.5.1125
+.endd
+overrides \local@_interfaces\, leaving \daemon@_smtp@_ports\ unchanged.
+(However, since \local@_interfaces\ now contains no items without ports, the
+value of \daemon@_smtp@_ports\ is no longer relevant in this example.)
+
+
+.section IPv6 address scopes
+IPv6 addresses have `scopes', and a host with multiple hardware interfaces
+can, in principle, have the same link-local IPv6 address on different
+interfaces. Thus, additional information is needed, over and above the IP
+address, to distinguish individual interfaces. A convention of using a
+percent sign followed by something (often the interface name) has been
+adopted in some cases, leading to addresses like this:
+.display asis
+3ffe:2101:12:1:a00:20ff:fe86:a061%eth0
+.endd
+To accommodate this usage, a percent sign followed by an arbitrary string is
+allowed at the end of an IPv6 address. By default, Exim calls \*getaddrinfo()*\
+to convert a textual IPv6 address for actual use. This function recognizes the
+percent convention in operating systems that support it, and it processes the
+address appropriately. Unfortunately, some older libraries have problems with
+\*getaddrinfo()*\. If
+.display asis
+IPV6_USE_INET_PTON=yes
+.endd
+is set in \(Local/Makefile)\ (or an OS-dependent Makefile) when Exim is built,
+Exim uses \*inet@_pton()*\ to convert a textual IPv6 address for actual use,
+instead of \*getaddrinfo()*\. (Before version 4.14, it always used this
+function.) Of course, this means that the additional functionality of
+\*getaddrinfo()*\ -- recognizing scoped addresses -- is lost.
+
+
+.section Examples of starting a listening daemon
+The default case in an IPv6 environment is
+.display asis
+daemon_smtp_port = smtp
+local_interfaces = <; ::0 ; 0.0.0.0
+.endd
+This specifies listening on the smtp port on all IPv6 and IPv4 interfaces.
+Either one or two sockets may be used, depending on the characteristics of
+the TCP/IP stack. (This is complicated and messy; for more information,
+read the comments in the \(daemon.c)\ source file.)
+
+To specify listening on ports 25 and 26 on all interfaces:
+.display asis
+daemon_smtp_ports = 25 : 26
+.endd
+(leaving \local@_interfaces\ at the default setting) or, more explicitly:
+.display asis
+local_interfaces = <; ::0.25 ; ::0.26 \
+ 0.0.0.0.25 ; 0.0.0.0.26
+.endd
+To listen on the default port on all IPv4 interfaces, and on port 26 on the
+IPv4 loopback address only:
+.display asis
+local_interfaces = 0.0.0.0 : 127.0.0.1.26
+.endd
+To specify listening on the default port on specific interfaces only:
+.display asis
+local_interfaces = 192.168.34.67 : 192.168.34.67
+.endd
+\**Note**\: such a setting excludes listening on the loopback interfaces.
+
+
+.section Recognising the local host
+.rset SECTreclocipadd "~~chapter.~~section"
+The \local@_interfaces\ option is also used when Exim needs to determine
+whether or not an IP address refers to the local host. That is, the IP
+addresses of all the interfaces on which a daemon is listening are always
+treated as local.
+
+For this usage, port numbers in \local@_interfaces\ are ignored. If either of
+the items 0.0.0.0 or @:@:0 are encountered, Exim gets a complete list of
+available interfaces from the operating system, and extracts the relevant
+(that is, IPv4 or IPv6) addresses to use for checking.
+
+Some systems set up large numbers of virtual interfaces in order to provide
+many virtual web servers. In this situation, you may want to listen for
+email on only a few of the available interfaces, but nevertheless treat all
+interfaces as local when routing. You can do this by setting
+\extra@_local@_interfaces\ to a list of IP addresses, possibly including the
+`all' wildcard values. These addresses are recognized as local, but are not
+used for listening. Consider this example:
+.display asis
+local_interfaces = <; 127.0.0.1 ; ::1 ; \
+ 192.168.53.235 ; \
+ 3ffe:2101:12:1:a00:20ff:fe86:a061
+
+extra_local_interfaces = <; ::0 ; 0.0.0.0
+.endd
+The daemon listens on the loopback interfaces and just one IPv4 and one IPv6
+address, but all available interface addresses are treated as local when
+Exim is routing.
+
+In some environments the local host name may be in an MX list, but with an IP
+address that is not assigned to any local interface. In other cases it may be
+desirable to treat other host names as if they referred to the local host. Both
+these cases can be handled by setting the \hosts@_treat@_as@_local\ option.
+This contains host names rather than IP addresses. When a host is referenced
+during routing, either via an MX record or directly, it is treated as the local
+host if its name matches \hosts@_treat@_as@_local\, or if any of its IP
+addresses match \local@_interfaces\ or \extra@_local@_interfaces\.
+
+
+.section Delivering to a remote host
+Delivery to a remote host is handled by the smtp transport. By default, it
+allows the system's TCP/IP functions to choose which interface to use (if
+there is more than one) when connecting to a remote host. However, the
+\interface\ option can be set to specify which interface is used. See the
+description of the smtp transport in chapter ~~CHAPsmtptrans for more details.
+
+
+
+
+
+.
+.
+.
+.
+. ============================================================================
+.chapter Main configuration
+.set runningfoot "main configuration"
+.rset CHAPmainconfig "~~chapter"
+.index configuration file||main section
+.index main configuration
+The first part of the run time configuration file contains three types of item:
+.numberpars $.
+Macro definitions: These lines start with an upper case letter. See section
+~~SECTmacrodefs for details of macro processing.
+.nextp
+Named list definitions: These lines start with one of the words `domainlist',
+`hostlist', `addresslist', or `localpartlist'. Their use is described in
+section ~~SECTnamedlists.
+.nextp
+Main configuration settings: Each setting occupies one line of the file
+(with possible continuations). If any setting is preceded by the word
+`hide', the \-bP-\ command line option displays its value to admin users only.
+See section ~~SECTcos for a description of the syntax of these option settings.
+.endp
+This chapter specifies all the main configuration options, along with their
+types and default values. For ease of finding a particular option, they appear
+in alphabetical order in section ~~SECTalomo below. However, because there are
+now so many options, they are first listed briefly in functional groups, as an
+aid to finding the name of the option you are looking for.
+Some options are listed in more than one group.
+
+.set savedisplayflowcheck ~~displayflowcheck
+.set displayflowcheck 0
+
+.section Miscellaneous
+.display flow rm
+.tabs 31
+\bi@_command\ $t$rm{to run for \-bi-\ command line option}
+\keep@_malformed\ $t$rm{for broken files -- should not happen}
+\localhost@_number\ $t$rm{for unique message ids in clusters}
+\message@_body@_visible\ $t$rm{how much to show in \$message@_body$\}
+\print@_topbitchars\ $t$rm{top-bit characters are printing}
+\timezone\ $t$rm{force time zone}
+.endd
+
+.section Exim parameters
+.display flow rm
+.tabs 31
+\exim@_group\ $t$rm{override compiled-in value}
+\exim@_path\ $t$rm{override compiled-in value}
+\exim@_user\ $t$rm{override compiled-in value}
+\primary@_hostname\ $t$rm{default from \*uname()*\}
+\split@_spool@_directory\ $t$rm{use multiple directories}
+\spool@_directory\ $t$rm{override compiled-in value}
+.endd
+
+.section Privilege controls
+.display flow rm
+.tabs 31
+\admin@_groups\ $t$rm{groups that are Exim admin users}
+\deliver@_drop@_privilege\ $t$rm{drop root for delivery processes}
+\local@_from@_check\ $t$rm{insert ::Sender:: if necessary}
+\local@_from@_prefix\ $t$rm{for testing ::From:: for local sender}
+\local@_from@_suffix\ $t$rm{for testing ::From:: for local sender}
+\local@_sender@_retain\ $t$rm{keep ::Sender:: from untrusted user}
+\never@_users\ $t$rm{do not run deliveries as these}
+\prod@_requires@_admin\ $t$rm{forced delivery requires admin user}
+\queue@_list@_requires@_admin\ $t$rm{queue listing requires admin user}
+\trusted@_groups\ $t$rm{groups that are trusted}
+\trusted@_users\ $t$rm{users that are trusted}
+.endd
+
+.section Logging
+.display flow rm
+.tabs 31
+\log@_file@_path\ $t$rm{override compiled-in value}
+\log@_selector\ $t$rm{set/unset optional logging}
+\log@_timezone\ $t$rm{add timezone to log lines}
+\message@_logs\ $t$rm{create per-message logs}
+\preserve@_message@_logs\ $t$rm{in another directory after message completion}
+\process@_log@_path\ $t$rm{for SIGUSR1 and \*exiwhat*\}
+\syslog@_duplication\ $t$rm{controls duplicate log lines on syslog }
+\syslog@_facility\ $t$rm{set syslog `facility' field}
+\syslog@_processname\ $t$rm{set syslog `ident' field}
+\syslog@_timestamp\ $t$rm{timestamp syslog lines}
+.newline
+.em
+\write@_rejectlog\ $t$rm{control use of message log}
+.newline
+.nem
+.endd
+
+.section Frozen messages
+.display flow rm
+.tabs 31
+\auto@_thaw\ $t$rm{sets time for retrying frozen messages}
+\freeze@_tell\ $t$rm{send message when freezing}
+\move@_frozen@_messages\ $t$rm{to another directory}
+\timeout@_frozen@_after\ $t$rm{keep frozen messages only so long}
+.endd
+
+.section Data lookups
+.display flow rm
+.tabs 31
+\ldap@_default@_servers\ $t$rm{used if no server in query}
+\ldap@_version\ $t$rm{set protocol version}
+\lookup@_open@_max\ $t$rm{lookup files held open}
+\mysql@_servers\ $t$rm{as it says}
+\oracle@_servers\ $t$rm{as it says}
+\pgsql@_servers\ $t$rm{as it says}
+.endd
+
+.section Message ids
+.display flow rm
+.tabs 31
+\message@_id@_header@_domain\ $t$rm{used to build ::Message-ID:: header}
+\message@_id@_header@_text\ $t$rm{ditto}
+.endd
+
+.section Embedded Perl Startup
+.display flow rm
+.tabs 31
+\perl@_at@_start\ $t$rm{always start the interpreter}
+\perl@_startup\ $t$rm{code to obey when starting Perl}
+.endd
+
+.section Daemon
+.display flow rm
+.tabs 31
+\daemon@_smtp@_ports\ $t$rm{default ports}
+\extra@_local@_interfaces\ $t$rm{not necessarily listened on}
+\local@_interfaces\ $t$rm{on which to listen, with optional ports}
+\pid@_file@_path\ $t$rm{override compiled-in value}
+\queue@_run@_max\ $t$rm{maximum number of simultaneous queue runners}
+.endd
+
+.section Resource control
+.display flow rm
+.tabs 31
+\check@_log@_inodes\ $t$rm{before accepting a message}
+\check@_log@_space\ $t$rm{before accepting a message}
+\check@_spool@_inodes\ $t$rm{before accepting a message}
+\check@_spool@_space\ $t$rm{before accepting a message}
+\deliver@_queue@_load@_max\ $t$rm{no queue deliveries if load high}
+\queue@_only@_load\ $t$rm{queue incoming if load high}
+\queue@_run@_max\ $t$rm{maximum number of simultaneous queue runners}
+\remote@_max@_parallel\ $t$rm{parallel SMTP delivery per message}
+\smtp@_accept@_max\ $t$rm{simultaneous incoming connections}
+\smtp@_accept@_max@_nommail\ $t$rm{non-mail commands}
+\smtp@_accept@_max@_nonmail@_hosts\ $t$rm{hosts to which the limit applies}
+\smtp@_accept@_max@_per@_connection\ $t$rm{messages per connection}
+\smtp@_accept@_max@_per@_host\ $t$rm{connections from one host}
+\smtp@_accept@_queue\ $t$rm{queue mail if more connections}
+\smtp@_accept@_queue@_per@_connection\ $t$rm{queue if more messages per connection}
+\smtp@_accept@_reserve\ $t$rm{only reserve hosts if more connections}
+\smtp@_check@_spool@_space\ $t$rm{from \\SIZE\\ on \\MAIL\\ command}
+\smtp@_connect@_backlog\ $t$rm{passed to TCP/IP stack}
+\smtp@_load@_reserve\ $t$rm{SMTP from reserved hosts if load high}
+\smtp@_reserve@_hosts\ $t$rm{these are the reserve hosts}
+.endd
+
+.section Policy controls
+.display flow rm
+.tabs 31
+\acl@_not@_smtp\ $t$rm{set ACL for non-SMTP messages}
+\acl@_smtp@_auth\ $t$rm{set ACL for \\AUTH\\}
+\acl@_smtp@_connect\ $t$rm{set ACL for connection}
+\acl@_smtp@_data\ $t$rm{set ACL for \\DATA\\}
+\acl@_smtp@_etrn\ $t$rm{set ACL for \\ETRN\\}
+\acl@_smtp@_expn\ $t$rm{set ACL for \\EXPN\\}
+\acl@_smtp@_helo\ $t$rm{set ACL for \\EHLO\\ or \\HELO\\}
+\acl@_smtp@_mail\ $t$rm{set ACL for \\MAIL\\}
+\acl@_smtp@_mailauth\ $t$rm{set ACL for \\AUTH\\ on \\MAIL\\ command}
+\acl@_smtp@_rcpt\ $t$rm{set ACL for \\RCPT\\}
+\acl@_smtp@_starttls\ $t$rm{set ACL for \\STARTTLS\\}
+\acl@_smtp@_vrfy\ $t$rm{set ACL for \\VRFY\\}
+\header@_maxsize\ $t$rm{total size of message header}
+\header@_line@_maxsize\ $t$rm{individual header line limit}
+\helo@_accept@_junk@_hosts\ $t$rm{allow syntactic junk from these hosts}
+\helo@_allow@_chars\ $t$rm{allow illegal chars in \\HELO\\ names}
+\helo@_lookup@_domains\ $t$rm{lookup hostname for these \\HELO\\ names}
+\helo@_try@_verify@_hosts\ $t$rm{\\HELO\\ soft-checked for these hosts}
+\helo@_verify@_hosts\ $t$rm{\\HELO\\ hard-checked for these hosts}
+\host@_lookup\ $t$rm{host name looked up for these hosts}
+\host@_lookup@_order\ $t$rm{order of DNS and local name lookups}
+\host@_reject@_connection\ $t$rm{reject connection from these hosts}
+\hosts@_treat@_as@_local\ $t$rm{useful in some cluster configurations}
+\local@_scan@_timeout\ $t$rm{timeout for \*local@_scan()*\}
+\message@_size@_limit\ $t$rm{for all messages}
+\percent@_hack@_domains\ $t$rm{recognize %-hack for these domains}
+.endd
+
+.section Callout cache
+.display flow rm
+.tabs 31
+\callout@_domain@_negative@_expire\ $t$rm{timeout for negative domain cache item}
+\callout@_domain@_positive@_expire\ $t$rm{timeout for positive domain cache item}
+\callout@_negative@_expire\ $t$rm{timeout for negative address cache item}
+\callout@_positive@_expire\ $t$rm{timeout for positive address cache item}
+\callout@_random@_local@_part\ $t$rm{string to use for `random' testing}
+.endd
+
+.section TLS
+.display flow rm
+.tabs 31
+\tls@_advertise@_hosts\ $t$rm{advertise TLS to these hosts}
+\tls@_certificate\ $t$rm{location of server certificate}
+.newline
+.em
+\tls@_crl\ $t$rm{certificate revocation list}
+.newline
+.nem
+\tls@_dhparam\ $t$rm{DH parameters for server}
+\tls@_privatekey\ $t$rm{location of server private key}
+\tls@_remember@_esmtp\ $t$rm{don't reset after starting TLS}
+.newline
+.em
+\tls@_require@_ciphers\ $t$rm{specify acceptable cipers}
+.newline
+.nem
+\tls@_try@_verify@_hosts\ $t$rm{try to verify client certificate}
+\tls@_verify@_certificates\ $t$rm{expected client certificates}
+\tls@_verify@_hosts\ $t$rm{insist on client certificate verify}
+.endd
+
+.section Local user handling
+.display flow rm
+.tabs 31
+\finduser@_retries\ $t$rm{useful in NIS environments}
+\gecos@_name\ $t$rm{used when creating ::Sender::}
+\gecos@_pattern\ $t$rm{ditto}
+\max@_username@_length\ $t$rm{for systems that truncate}
+\unknown@_login\ $t$rm{used when no login name found}
+\unknown@_username\ $t$rm{ditto}
+\uucp@_from@_pattern\ $t$rm{for recognizing `From ' lines}
+\uucp@_from@_sender\ $t$rm{ditto}
+.endd
+
+.section All incoming messages (SMTP and non-SMTP)
+.display flow rm
+.tabs 31
+\header@_maxsize\ $t$rm{total size of message header}
+\header@_line@_maxsize\ $t$rm{individual header line limit}
+\message@_size@_limit\ $t$rm{applies to all messages}
+\percent@_hack@_domains\ $t$rm{recognize %-hack for these domains}
+\received@_header@_text\ $t$rm{expanded to make ::Received::}
+\received@_headers@_max\ $t$rm{for mail loop detection}
+\recipients@_max\ $t$rm{limit per message}
+\recipients@_max@_reject\ $t$rm{permanently reject excess}
+.endd
+
+
+.section Non-SMTP incoming messages
+.display rm
+.tabs 31
+\receive@_timeout\ $t$rm{for non-SMTP messages}
+.endd
+
+
+
+.section Incoming SMTP messages
+See also the \*Policy controls*\ section above.
+.display flow rm
+.tabs 31
+\host@_lookup\ $t$rm{host name looked up for these hosts}
+\host@_lookup@_order\ $t$rm{order of DNS and local name lookups}
+\recipient@_unqualified@_hosts\ $t$rm{may send unqualified recipients}
+\rfc1413@_hosts\ $t$rm{make ident calls to these hosts}
+\rfc1413@_query@_timeout\ $t$rm{zero disables ident calls}
+\sender@_unqualified@_hosts\ $t$rm{may send unqualified senders}
+\smtp@_accept@_keepalive\ $t$rm{some TCP/IP magic}
+\smtp@_accept@_max\ $t$rm{simultaneous incoming connections}
+\smtp@_accept@_max@_nommail\ $t$rm{non-mail commands}
+\smtp@_accept@_max@_nonmail@_hosts\ $t$rm{hosts to which the limit applies}
+\smtp@_accept@_max@_per@_connection\ $t$rm{messages per connection}
+\smtp@_accept@_max@_per@_host\ $t$rm{connections from one host}
+\smtp@_accept@_queue\ $t$rm{queue mail if more connections}
+\smtp@_accept@_queue@_per@_connection\ $t$rm{queue if more messages per connection}
+\smtp@_accept@_reserve\ $t$rm{only reserve hosts if more connections}
+.newline
+.em
+\smtp@_active@_hostname\ $t$rm{host name to use in messages}
+.newline
+.nem
+\smtp@_banner\ $t$rm{text for welcome banner}
+\smtp@_check@_spool@_space\ $t$rm{from \\SIZE\\ on \\MAIL\\ command}
+\smtp@_connect@_backlog\ $t$rm{passed to TCP/IP stack}
+\smtp@_enforce@_sync\ $t$rm{of SMTP command/responses}
+\smtp@_etrn@_command\ $t$rm{what to run for \\ETRN\\}
+\smtp@_etrn@_serialize\ $t$rm{only one at once}
+\smtp@_load@_reserve\ $t$rm{only reserve hosts if this load}
+\smtp@_max@_unknown@_commands\ $t$rm{before dropping connection}
+\smtp@_ratelimit@_hosts\ $t$rm{apply ratelimiting to these hosts}
+\smtp@_ratelimit@_mail\ $t$rm{ratelimit for \\MAIL\\ commands}
+\smtp@_ratelimit@_rcpt\ $t$rm{ratelimit for \\RCPT\\ commands}
+\smtp@_receive@_timeout\ $t$rm{per command or data line}
+\smtp@_reserve@_hosts\ $t$rm{these are the reserve hosts}
+\smtp@_return@_error@_details\ $t$rm{give detail on rejections}
+.endd
+
+.section SMTP extensions
+.display flow rm
+.tabs 31
+\accept@_8bitmime\ $t$rm{advertise \\8BITMIME\\}
+\auth@_advertise@_hosts\ $t$rm{advertise \\AUTH\\ to these hosts}
+\ignore@_fromline@_hosts\ $t$rm{allow `From ' from these hosts}
+\ignore@_fromline@_local\ $t$rm{allow `From ' from local SMTP}
+\pipelining@_advertise@_hosts\ $t$rm{advertise pipelining to these hosts}
+\tls@_advertise@_hosts\ $t$rm{advertise TLS to these hosts}
+.endd
+
+.section Processing messages
+.display flow rm
+.tabs 31
+\allow@_domain@_literals\ $t$rm{recognize domain literal syntax}
+\allow@_mx@_to@_ip\ $t$rm{allow MX to point to IP address}
+\allow@_utf8@_domains\ $t$rm{in addresses}
+\delivery@_date@_remove\ $t$rm{from incoming messages}
+\envelope@_to@_remote\ $t$rm{from incoming messages}
+\extract@_addresses@_remove@_arguments\ $t$rm{affects \-t-\ processing}
+\headers@_charset\ $t$rm{default for translations}
+\qualify@_domain\ $t$rm{default for senders}
+\qualify@_recipient\ $t$rm{default for recipients}
+\return@_path@_remove\ $t$rm{from incoming messages}
+\strip@_excess@_angle@_brackets\ $t$rm{in addresses}
+\strip@_trailing@_dot\ $t$rm{at end of addresses}
+\untrusted@_set@_sender\ $t$rm{untrusted can set envelope sender}
+.endd
+
+.section System filter
+.display flow rm
+.tabs 31
+\system@_filter\ $t$rm{locate system filter}
+\system@_filter@_directory@_transport\ $t$rm{transport for delivery to a directory}
+\system@_filter@_file@_transport\ $t$rm{transport for delivery to a file}
+\system@_filter@_group\ $t$rm{group for filter running}
+\system@_filter@_pipe@_transport\ $t$rm{transport for delivery to a pipe}
+\system@_filter@_reply@_transport\ $t$rm{transport for autoreply delivery}
+\system@_filter@_user\ $t$rm{user for filter running}
+.endd
+
+.section Routing and delivery
+.display flow rm
+.tabs 31
+\dns@_again@_means@_nonexist\ $t$rm{for broken domains}
+\dns@_check@_names@_pattern\ $t$rm{pre-DNS syntax check}
+\dns@_ipv4@_lookup\ $t$rm{only v4 lookup for these domains}
+\dns@_retrans\ $t$rm{parameter for resolver}
+\dns@_retry\ $t$rm{parameter for resolver}
+\hold@_domains\ $t$rm{hold delivery for these domains}
+\local@_interfaces\ $t$rm{for routing checks}
+\queue@_domains\ $t$rm{no immediate delivery for these}
+\queue@_only\ $t$rm{no immediate delivery at all}
+\queue@_only@_file\ $t$rm{no immediate deliveryif file exists}
+\queue@_only@_load\ $t$rm{no immediate delivery if load is high}
+\queue@_only@_override\ $t$rm{allow command line to override}
+\queue@_run@_in@_order\ $t$rm{order of arrival}
+\queue@_run@_max\ $t$rm{of simultaneous queue runners}
+\queue@_smtp@_domains\ $t$rm{no immediate SMTP delivery for these}
+\remote@_max@_parallel\ $t$rm{parallel SMTP delivery (per message, not overall)}
+\remote@_sort@_domains\ $t$rm{order of remote deliveries}
+\retry@_data@_expire\ $t$rm{timeout for retry data}
+\retry@_interval@_max\ $t$rm{safety net for retry rules}
+.endd
+
+.section Bounce and warning messages
+.display flow rm
+.tabs 31
+\bounce@_message@_file\ $t$rm{content of bounce}
+\bounce@_message@_text\ $t$rm{content of bounce}
+\bounce@_return@_body\ $t$rm{include body if returning message}
+\bounce@_return@_message\ $t$rm{include original message in bounce}
+\bounce@_return@_size@_limit\ $t$rm{limit on returned message}
+\bounce@_sender@_authentication\ $t$rm{send authenticated sender with bounce}
+\errors@_copy\ $t$rm{copy bounce messages}
+\errors@_reply@_to\ $t$rm{::Reply-to:: in bounces}
+\delay@_warning\ $t$rm{time schedule}
+\delay@_warning@_condition\ $t$rm{condition for warning messages}
+\ignore@_bounce@_errors@_after\ $t$rm{discard undeliverable bounces}
+\warn@_message@_file\ $t$rm{content of warning message}
+.endd
+
+.set displayflowcheck ~~savedisplayflowcheck
+
+.section Alphabetical list of main options
+.rset SECTalomo "~~chapter.~~section"
+.if ~~sgcal
+Those options that undergo string expansion before use are marked with $**$.
+.fi
+
+.startconf
+
+.index \\8BITMIME\\
+.index 8-bit characters
+.conf accept@_8bitmime boolean false
+This option causes Exim to send \\8BITMIME\\ in its response to an SMTP
+\\EHLO\\ command, and to accept the \\BODY=\\ parameter on \\MAIL\\ commands.
+However, though Exim is 8-bit clean, it is not a protocol converter, and it
+takes no steps to do anything special with messages received by this route.
+Consequently, this option is turned off by default.
+
+.index ~~ACL||for non-SMTP messages
+.index non-SMTP messages, ACL for
+.conf acl@_not@_smtp string$**$ unset
+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.
+
+.index ~~ACL||on SMTP connection
+.conf acl@_smtp@_connect string$**$ unset
+This option defines the ACL that is run when an SMTP connection is received.
+See chapter ~~CHAPACL for further details.
+
+.index ~~ACL||setting up for SMTP commands
+.index \\AUTH\\||ACL for
+.conf acl@_smtp@_auth string$**$ unset
+This option defines the ACL that is run when an SMTP \\AUTH\\ command is
+received. See chapter ~~CHAPACL for further details.
+
+.index \\DATA\\, ACL for
+.conf acl@_smtp@_data string$**$ unset
+This option defines the ACL that is run after an SMTP \\DATA\\ command has been
+processed and the message itself has been received, but before the final
+acknowledgement is sent. See chapter ~~CHAPACL for further details.
+
+.index \\ETRN\\||ACL for
+.conf acl@_smtp@_etrn string$**$ unset
+This option defines the ACL that is run when an SMTP \\ETRN\\ command is
+received. See chapter ~~CHAPACL for further details.
+
+.index \\EXPN\\||ACL for
+.conf acl@_smtp@_expn string$**$ unset
+This option defines the ACL that is run when an SMTP \\EXPN\\ command is
+received. See chapter ~~CHAPACL for further details.
+
+.index \\EHLO\\||ACL for
+.index \\HELO\\||ACL for
+.conf acl@_smtp@_helo string$**$ unset
+This option defines the ACL that is run when an SMTP \\EHLO\\ or \\HELO\\
+command is received. See chapter ~~CHAPACL for further details.
+
+.index \\MAIL\\||ACL for
+.conf acl@_smtp@_mail string$**$ unset
+This option defines the ACL that is run when an SMTP \\MAIL\\ command is
+received. See chapter ~~CHAPACL for further details.
+
+.index \\AUTH\\||on \\MAIL\\ command
+.conf acl@_smtp@_mailauth string$**$ unset
+This option defines the ACL that is run when there is an \\AUTH\\ parameter on
+a \\MAIL\\ command. See chapter ~~CHAPACL for details of ACLs, and chapter
+~~CHAPSMTPAUTH for details of authentication.
+
+.index \\RCPT\\||ACL for
+.conf acl@_smtp@_rcpt string$**$ unset
+This option defines the ACL that is run when an SMTP \\RCPT\\ command is
+received. See chapter ~~CHAPACL for further details.
+
+.index \\STARTTLS\\, ACL for
+.conf acl@_smtp@_starttls string$**$ unset
+This option defines the ACL that is run when an SMTP \\STARTTLS\\ command is
+received. See chapter ~~CHAPACL for further details.
+
+.index \\VRFY\\||ACL for
+.conf acl@_smtp@_vrfy string$**$ unset
+This option defines the ACL that is run when an SMTP \\VRFY\\ command is
+received. See chapter ~~CHAPACL for further details.
+
+.conf admin@_groups "string list" unset
+.index 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
+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).
+To permit this, you have to add individuals to the Exim group.
+
+.conf allow@_domain@_literals boolean false
+.index domain literal
+If this option is set, the RFC 2822 domain literal format is permitted in
+email addresses. The option is not set by default, because the domain literal
+format is not normally required these days, and few people know about it. It
+has, however, been exploited by mail abusers.
+
+Unfortunately, it seems that some DNS black list maintainers are using this
+format to report black listing to postmasters. If you want to accept messages
+addressed to your hosts by IP address, you need to set
+\allow@_domain@_literals\ true, and also to add \"@@[]"\ to the list of local
+domains (defined in the named domain list \local@_domains\ in the default
+configuration). This `magic string' matches the domain literal form of all the
+local host's IP addresses.
+
+.conf allow@_mx@_to@_ip boolean false
+.index MX record||pointing to IP address
+It appears that more and more DNS zone administrators are breaking the rules
+and putting domain names that look like IP addresses on the right hand side of
+MX records. Exim follows the rules and rejects this, giving an error message
+that explains the mis-configuration. However, some other MTAs support this
+practice, so to avoid `Why can't Exim do this?' complaints, \allow@_mx@_to@_ip\
+exists, in order to enable this heinous activity. It is not recommended, except
+when you have no other choice.
+
+.index domain||UTF-8 characters in
+.index UTF-8||in domain name
+.conf allow@_utf8@_domains boolean false
+Lots of discussion is going on about internationalized domain names. One
+camp is strongly in favour of just using UTF-8 characters, and it seems
+that at least two other MTAs permit this. This option allows Exim users to
+experiment if they wish.
+
+If it is set true, Exim's domain parsing function allows valid
+UTF-8 multicharacters to appear in domain name components, in addition to
+letters, digits, and hyphens. However, just setting this option is not
+enough; if you want to look up these domain names in the DNS, you must also
+adjust the value of \dns@_check@_names@_pattern\ to match the extended form. A
+suitable setting is:
+.display asis
+dns_check_names_pattern = (?i)^(?>(?(1)\.|())[a-z0-9\xc0-\xff]\
+ (?>[-a-z0-9\x80-\xff]*[a-z0-9\x80-\xbf])?)+$
+.endd
+Alternatively, you can just disable this feature by setting
+.display asis
+dns_check_names_pattern =
+.endd
+That is, set the option to an empty string so that no check is done.
+
+.conf auth@_advertise@_hosts "host list$**$" $*$
+.index authentication||advertising
+.index \\AUTH\\||advertising
+If any server authentication mechanisms are configured, Exim advertises them in
+response to an \\EHLO\\ command only if the calling host matches this list.
+Otherwise, Exim does not advertise \\AUTH\\.
+Exim does not accept \\AUTH\\ commands from clients to which it has not
+advertised the availability of \\AUTH\\. The advertising of individual
+authentication mechanisms can be controlled by the use of the
+\server@_advertise@_condition\ generic authenticator option on the individual
+authenticators. See chapter ~~CHAPSMTPAUTH for further details.
+
+Certain mail clients (for example, Netscape) require the user to provide a name
+and password for authentication if \\AUTH\\ is advertised, even though it may
+not be needed (the host may accept messages from hosts on its local LAN without
+authentication, for example). The \auth@_advertise@_hosts\ option can be used
+to make these clients more friendly by excluding them from the set of hosts to
+which Exim advertises \\AUTH\\.
+
+.index \\AUTH\\||advertising when encrypted
+If you want to advertise the availability of \\AUTH\\ only when the connection
+is encrypted using TLS, you can make use of the fact that the value of this
+option is expanded, with a setting like this:
+.display asis
+auth_advertise_hosts = ${if eq{$tls_cipher}{}{}{*}}
+.endd
+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.
+
+.conf auto@_thaw time 0s
+.index thawing messages
+.index 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\.
+
+.conf bi@_command string unset
+.index \-bi-\ option
+This option supplies the name of a command that is run when Exim is called with
+the \-bi-\ option (see chapter ~~CHAPcommandline). The string value is just the
+command name, it is not a complete command line. If an argument is required, it
+must come from the \-oA-\ command line option.
+
+.conf bounce@_message@_file string unset
+.index bounce message||customizing
+.index customizing||bounce message
+This option defines a template file containing paragraphs of text to be used
+for constructing bounce messages. Details of the file's contents are given in
+chapter ~~CHAPemsgcust. See also \warn@_message@_file\.
+
+.conf bounce@_message@_text string unset
+When this option is set, its contents are included in the default bounce
+message immediately after `This message was created automatically by mail
+delivery software.' It is not used if \bounce@_message@_file\ is set.
+
+.index bounce message||including body
+.conf bounce@_return@_body boolean true
+This option controls whether the body of an incoming message is included in a
+bounce message when \bounce@_return@_message\ is true. If it is not set, only
+the message header is included.
+
+.index bounce message||including original
+.conf bounce@_return@_message boolean true
+If this option is set false, the original message is not included in bounce
+messages generated by Exim. See also \bounce@_return@_size@_limit\.
+
+.conf bounce@_return@_size@_limit integer 100K
+.index size||of bounce, limit
+.index bounce message||size limit
+.index limit||bounce message size
+This option sets a limit in bytes on the size of messages that are returned to
+senders as part of bounce messages when \bounce@_return@_message\ is true. The
+limit should be less than the value of the global \message@_size@_limit\ and of
+any \message@_size@_limit\ settings on transports, to allow for the bounce text
+that Exim generates. If this option is set to zero there is no limit.
+
+When the body of any message that is to be included in a bounce message is
+greater than the limit, it is truncated, and a comment pointing this out is
+added at the top. The actual cutoff may be greater than the value given, owing
+to the use of buffering for transferring the message in chunks (typically 8K in
+size). The idea is to save bandwidth on those undeliverable 15-megabyte
+messages.
+
+.index bounce message||sender authentication
+.index authentication||bounce message
+.index \\AUTH\\||on bounce message
+.conf bounce@_sender@_authentication string unset
+This option provides an authenticated sender address that is sent with any
+bounce messages generated by Exim that are sent over an authenticated SMTP
+connection. A typical setting might be:
+.display asis
+bounce_sender_authentication = mailer-daemon@my.domain.example
+.endd
+which would cause bounce messages to be sent using the SMTP command:
+.display asis
+MAIL FROM:<> AUTH=mailer-daemon@my.domain.example
+.endd
+The value of \bounce@_sender@_authentication\ must always be a complete email
+address.
+
+.index caching||callout, timeouts
+.index callout||caching timeouts
+.conf callout@_domain@_negative@_expire time 3h
+This option specifies the expiry time for negative callout cache data for a
+domain. See section ~~SECTcallver for details of callout verification, and
+section ~~SECTcallvercache for details of the caching.
+
+.conf callout@_domain@_positive@_expire time 7d
+This option specifies the expiry time for positive callout cache data for a
+domain. See section ~~SECTcallver for details of callout verification, and
+section ~~SECTcallvercache for details of the caching.
+
+.conf callout@_negative@_expire time 2h
+This option specifies the expiry time for negative callout cache data for an
+address. See section ~~SECTcallver for details of callout verification, and
+section ~~SECTcallvercache for details of the caching.
+
+.conf callout@_positive@_expire time 24h
+This option specifies the expiry time for positive callout cache data for an
+address. See section ~~SECTcallver for details of callout verification, and
+section ~~SECTcallvercache for details of the caching.
+
+.conf callout@_random@_local@_part string$**$ "see below"
+This option defines the `random' local part that can be used as part of callout
+verification. The default value is
+.display asis
+$primary_host_name-$tod_epoch-testing
+.endd
+See section ~~CALLaddparcall for details of how this value is used.
+
+.conf check@_log@_inodes integer 0
+See \check@_spool@_space\ below.
+
+.conf check@_log@_space integer 0
+See \check@_spool@_space\ below.
+
+.conf check@_spool@_inodes integer 0
+See \check@_spool@_space\ below.
+
+.conf check@_spool@_space integer 0
+.index checking disk space
+.index disk space, checking
+.index spool directory||checking space
+The four \check@_...\ options allow for checking of disk resources before a
+message is accepted. \check@_spool@_space\ and \check@_spool@_inodes\ check the
+spool partition if either value is greater than zero, for example:
+.display asis
+check_spool_space = 10M
+check_spool_inodes = 100
+.endd
+The spool partition is the one which contains the directory defined by
+\\SPOOL@_DIRECTORY\\ in \(Local/Makefile)\. It is used for holding messages in
+transit.
+
+\check@_log@_space\ and \check@_log@_inodes\ check the partition in which log
+files are written if either is greater than zero. These should be set only if
+\log@_file@_path\ and \spool@_directory\ refer to different partitions.
+
+If there is less space or fewer inodes than requested, Exim refuses to accept
+incoming mail. In the case of SMTP input this is done by giving a 452 temporary
+error response to the \\MAIL\\ command. If ESMTP is in use and there was a
+\\SIZE\\ parameter on the \\MAIL\\ command, its value is added to the
+\check@_spool@_space\ value, and the check is performed even if
+\check@_spool@_space\ is zero, unless \no@_smtp@_check@_spool@_space\ is set.
+
+The values for \check@_spool@_space\ and \check@_log@_space\ are held as a
+number of kilobytes. If a non-multiple of 1024 is specified, it is rounded up.
+
+For non-SMTP input and for batched SMTP input, the test is done at start-up; on
+failure a message is written to stderr and Exim exits with a non-zero code, as
+it obviously cannot send an error message of any kind.
+
+.index port||for daemon
+.index TCP/IP||setting listening ports
+.conf daemon@_smtp@_ports string "$tt{smtp}"
+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.
+
+.conf delay@_warning "time list" 24h
+.index warning of delay
+.index delay warning, specifying
+When a message is delayed, Exim sends a warning message to the sender at
+intervals specified by this option. If it is set to a zero, no warnings are
+sent. The data is a colon-separated list of times after which to send warning
+messages. Up to 10 times may be given. If a message has been on the queue for
+longer than the last time, the last interval between the times is used to
+compute subsequent warning times. For example, with
+.display asis
+delay_warning = 4h:8h:24h
+.endd
+the first message is sent after 4 hours, the second after 8 hours, and
+the third one after 24 hours. After that, messages are sent every 16 hours,
+because that is the interval between the last two times on the list. If you set
+just one time, it specifies the repeat interval. For example, with:
+.display asis
+delay_warning = 6h
+.endd
+messages are repeated every six hours. To stop warnings after a given time, set
+a very large time at the end of the list. For example:
+.display asis
+delay_warning = 2h:12h:99d
+.endd
+
+.conf delay@_warning@_condition string$**$ "see below"
+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
+forced failure, an empty string, or a string matching any of `0', `no' or
+`false' (the comparison being done caselessly) then the warning message is not
+sent. The default is
+.display asis
+delay_warning_condition = \
+ ${if match{$h_precedence:}{(?i)bulk|list|junk}{no}{yes}}
+.endd
+which suppresses the sending of warnings about messages that have `bulk',
+`list' or `junk' in a ::Precedence:: header.
+
+.index unprivileged delivery
+.index delivery||unprivileged
+.conf deliver@_drop@_privilege boolean false
+If this option is set true, Exim drops its root privilege at the start of a
+delivery process, and runs as the Exim user throughout. This severely restricts
+the kinds of local delivery that are possible, but is viable in certain types
+of configuration. There is a discussion about the use of root privilege in
+chapter ~~CHAPsecurity.
+
+.index load average
+.index queue runner||abandoning
+.conf deliver@_queue@_load@_max fixed-point unset
+When this option is set, a queue run is abandoned if the system load average
+becomes greater than the value of the option. The option has no effect on
+ancient operating systems on which Exim cannot determine the load average.
+See also \queue@_only@_load\ and \smtp@_load@_reserve\.
+
+.conf delivery@_date@_remove boolean true
+.index ::Delivery-date:: header line
+Exim's transports have an option for adding a ::Delivery-date:: header to a
+message when it is delivered -- in exactly the same way as ::Return-path:: is
+handled. ::Delivery-date:: records the actual time of delivery. Such headers
+should not be present in incoming messages, and this option causes them to be
+removed at the time the message is received, to avoid any problems that might
+occur when a delivered message is subsequently sent on to some other recipient.
+
+.index DNS||`try again' response, overriding
+.conf dns@_again@_means@_nonexist "domain list$**$" unset
+DNS lookups give a `try again' response for the DNS errors `non-authoritative
+host not found' and `\\SERVERFAIL\\'. This can cause Exim to keep trying to
+deliver a message, or to give repeated temporary errors to incoming mail.
+Sometimes the effect is caused by a badly set up name server and may persist
+for a long time. If a domain which exhibits this problem matches anything in
+\dns__again__means__nonexist\, it is treated as if it did not exist. This
+option should be used with care.
+.em
+You can make it apply to reverse lookups by a setting such as this:
+.display asis
+dns_again_means_nonexist = *.in-addr.arpa
+.endd
+.nem
+
+.index DNS||pre-check of name syntax
+.conf dns@_check@_names@_pattern string "see below"
+When this option is set to a non-empty string, it causes Exim to check domain
+names for illegal characters before handing them to the DNS resolver, because
+some resolvers give temporary errors for malformed names. If a domain name
+contains any illegal characters, a `not found' result is forced, and the
+resolver is not called. The check is done by matching the domain name against a
+regular expression, which is the value of this option. The default pattern is
+.display asis
+dns_check_names_pattern = \
+ (?i)^(?>(?(1)\.|())[^\W_](?>[a-z0-9-]*[^\W_])?)+$
+.endd
+which permits only letters, digits, and hyphens in components, but they may not
+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.
+
+.conf dns@_ipv4@_lookup "domain list$**$" unset
+.index IPv6||DNS lookup for AAAA records
+.index DNS||IPv6 lookup for AAAA records
+When Exim is compiled with IPv6 support, it looks for IPv6 address records
+(AAAA and, if configured, A6) as well as IPv4 address records when trying to
+find IP addresses for hosts, unless the host's domain matches this list.
+
+This is a fudge to help with name servers that give big delays or otherwise do
+not work for the new IPv6 record types. If Exim is handed an IPv6 address
+record as a result of an MX lookup, it always recognizes it, and may as a
+result make an outgoing IPv6 connection. All this option does is to make Exim
+look only for IPv4-style A records when it needs to find an IP address for a
+host name. In due course, when the world's name servers have all been upgraded,
+there should be no need for this option.
+
+.conf dns@_retrans time 0s
+.index DNS||resolver options
+The options \dns@_retrans\ and \dns@_retry\ can be used to set the
+retransmission and retry parameters for DNS lookups. Values of zero (the
+defaults) leave the system default settings unchanged. The first value is the
+time between retries, and the second is the number of retries. It isn't
+totally clear exactly how these settings affect the total time a DNS lookup may
+take. I haven't found any documentation about timeouts on DNS lookups; these
+parameter values are available in the external resolver interface structure,
+but nowhere does it seem to describe how they are used or what you might want
+to set in them.
+
+.conf dns@_retry integer 0
+See \dns@_retrans\ above.
+
+.conf drop@_cr boolean false
+This is an obsolete option that is now a no-op. It used to affect the way Exim
+handled CR and LF characters in incoming messages. What happens now is
+described in section ~~SECTlineendings.
+
+.conf envelope@_to@_remove boolean true
+.index ::Envelope-to:: header line
+Exim's transports have an option for adding an ::Envelope-to:: header to a
+message when it is delivered -- in exactly the same way as ::Return-path:: is
+handled. ::Envelope-to:: records the original recipient address from the
+messages's envelope that caused the delivery to happen. Such headers should not
+be present in incoming messages, and this option causes them to be removed at
+the time the message is received, to avoid any problems that might occur when a
+delivered message is subsequently sent on to some other recipient.
+
+.conf errors@_copy "string list$**$" unset
+.index bounce message||copy to other address
+.index copy of bounce message
+Setting this option causes Exim to send bcc copies of bounce messages that it
+generates to other addresses. \**Note**\: this does not apply to bounce messages
+coming from elsewhere. The value of the option is a colon-separated list of
+items. Each item consists of a pattern, terminated by white space, followed by
+a comma-separated list of email addresses. If a pattern contains spaces, it
+must be enclosed in double quotes.
+
+Each pattern is processed in the same way as a single item in an address list
+(see section ~~SECTaddresslist). When a pattern matches the recipient of the
+bounce message, the message is copied to the addresses on the list. The items
+are scanned in order, and once a matching one is found, no further items are
+examined. For example:
+.display asis
+errors_copy = spqr@mydomain postmaster@mydomain.example :\
+ rqps@mydomain hostmaster@mydomain.example,\
+ postmaster@mydomain.example
+.endd
+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
+.index numerical variables (\$1$\, \$2$\, etc)||in \errors@_copy\
+variables \$0$\, \$1$\, etc. are set in the normal way.
+
+.conf errors@_reply@_to string unset
+.index bounce message||::Reply-to:: in
+Exim's bounce and delivery warning messages contain the header line
+.display
+From: Mail Delivery System @<Mailer-Daemon@@<<qualify-domain>>@>
+.endd
+where <<qualify-domain>> is the value of the \qualify@_domain\ option.
+Experience shows that people reply to bounce messages. If the
+\errors@_reply@_to\ option is set, a ::Reply-To:: header is added to bounce and
+warning messages. For example:
+.display asis
+errors_reply_to = postmaster@my.domain.example
+.endd
+The value of the option is not expanded. It must specify a valid RFC 2822
+address.
+
+.conf exim@_group string "compile-time configured"
+.index gid (group id)||Exim's own
+.index Exim group
+This option changes the gid under which Exim runs when it gives up root
+privilege. The default value is compiled into the binary. The value of this
+option is used only when \exim@_user\ is also set. Unless it consists entirely
+of digits, the string is looked up using \*getgrnam()*\, and failure causes a
+configuration error. See chapter ~~CHAPsecurity for a discussion of security
+issues.
+
+.conf exim@_path string "see below"
+.index Exim binary, path name
+This option specifies the path name of the Exim binary, which is used when Exim
+needs to re-exec itself. The default is set up to point to the file \*exim*\ in
+the directory configured at compile time by the \\BIN@_DIRECTORY\\ setting. It
+is necessary to change \exim@_path\ if, exceptionally, Exim is run from some
+other place.
+\**Warning**\: Do not use a macro to define the value of this option, because
+you will break those Exim utilities that scan the configuration file to find
+where the binary is. (They then use the \-bP-\ option to extract option
+settings such as the value of \spool@_directory\.)
+
+.conf exim@_user string "compile-time configured"
+.index uid (user id)||Exim's own
+.index Exim user
+This option changes the uid under which Exim runs when it gives up root
+privilege. The default value is compiled into the binary. Ownership of the run
+time configuration file and the use of the \-C-\ and \-D-\ command line options
+is checked against the values in the binary, not what is set here.
+
+Unless it consists entirely of digits, the string is looked up using
+\*getpwnam()*\, and failure causes a configuration error. If \exim@_group\ is
+not also supplied, the gid is taken from the result of \*getpwnam()*\ if it is
+used. See chapter ~~CHAPsecurity for a discussion of security issues.
+
+.conf extra@_local@_interfaces "string list" unset
+.index
+This option defines network interfaces that are to be considered local when
+routing, but which are not used for listening by the daemon. See section
+~~SECTreclocipadd for details.
+
+.conf extract@_addresses@_remove@_arguments boolean true
+.index \-t-\ option
+.index command line||addresses with \-t-\
+.index Sendmail compatibility||\-t-\ option
+According to some Sendmail documentation (Sun, IRIX, HP-UX), if any addresses
+are present on the command line when the \-t-\ option is used to build an
+envelope from a message's ::To::, ::Cc:: and ::Bcc:: headers, the command line
+addresses are removed from the recipients list. This is also how Smail behaves.
+However, other Sendmail documentation (the O'Reilly book) states that command
+line addresses are added to those obtained from the header lines. When
+\extract@_addresses@_remove@_arguments\ is true (the default), Exim subtracts
+argument headers. If it is set false, Exim adds rather than removes argument
+addresses.
+
+.conf finduser@_retries integer 0
+.index NIS, looking up users, retrying
+On systems running NIS or other schemes in which user and group information is
+distributed from a remote system, there can be times when \*getpwnam()*\ and
+related functions fail, even when given valid data, because things time out.
+Unfortunately these failures cannot be distinguished from genuine `not found'
+errors. If \finduser@_retries\ is set greater than zero, Exim will try that
+many extra times to find a user or a group, waiting for one second between
+retries.
+
+.conf freeze@_tell "string list, comma separated" unset
+.index freezing messages||sending a message when freezing
+On encountering certain errors, or when configured to do so in a system filter,
+or in an ACL,
+Exim freezes a message. This means that no further delivery attempts take place
+until an administrator (or the \auto@_thaw\ feature) thaws the message. If
+\freeze@_tell\ is set, Exim generates a warning message whenever it freezes
+something, unless the message it is freezing is a
+locally-generated
+bounce message. (Without this exception there is the possibility of looping.)
+The warning message is sent to the addresses supplied as the comma-separated
+value of this option. If several of the message's addresses cause freezing,
+only a single message is sent.
+If the freezing was automatic, the reason(s) for freezing can be found in the
+message log. If you configure freezing in a filter or ACL, you must arrange for
+any logging that you require.
+
+.conf gecos@_name string$**$ unset
+.index HP-UX
+.index `gecos' field, parsing
+Some operating systems, notably HP-UX, use the `gecos' field in the system
+password file to hold other information in addition to users' real names. Exim
+looks up this field for use when it is creating ::Sender:: or ::From:: headers.
+If either \gecos@_pattern\ or \gecos@_name\ are unset, the contents of the
+field are used unchanged, except that, if an ampersand is encountered, it is
+replaced by the user's login name with the first character forced to
+upper case, since this is a convention that is observed on many systems.
+
+When these options are set, \gecos@_pattern\ is treated as a regular expression
+that is to be applied to the field (again with & replaced by the login name),
+and if it matches, \gecos@_name\ is expanded and used as the user's name.
+.index numerical variables (\$1$\, \$2$\, etc)||in \gecos@_name\
+Numeric variables such as \$1$\, \$2$\, etc. can be used in the expansion to
+pick up sub-fields that were matched by the pattern. In HP-UX, where the user's
+name terminates at the first comma, the following can be used:
+.display asis
+gecos_pattern = ([^,]*)
+gecos_name = $1
+.endd
+
+.conf gecos@_pattern string unset
+See \gecos@_name\ above.
+
+.conf headers@_charset string "see below"
+This option sets a default character set for translating from encoded MIME
+`words' in header lines, when referenced by an \$h@_xxx$\ expansion item. The
+default is the value of \\HEADERS@_CHARSET\\ in \(Local/Makefile)\. The
+ultimate default is ISO-8859-1. For more details see the description of header
+insertions in section ~~SECTexpansionitems.
+
+
+.conf header@_maxsize integer "see below"
+.index header section||maximum size of
+.index limit||size of message header section
+This option controls the overall maximum size of a message's header
+section. The default is the value of \\HEADER@_MAXSIZE\\ in
+\(Local/Makefile)\; the default for that is 1M. Messages with larger header
+sections are rejected.
+
+.conf header@_line@_maxsize integer 0
+.index header lines||maximum size of
+.index limit||size of one header line
+This option limits the length of any individual header line in a message, after
+all the continuations have been joined together. Messages with individual
+header lines that are longer than the limit are rejected. The default value of
+zero means `no limit'.
+
+
+
+.conf helo@_accept@_junk@_hosts "host list$**$" unset
+.index \\HELO\\||accepting junk data
+.index \\EHLO\\||accepting junk data
+Exim checks the syntax of \\HELO\\ and \\EHLO\\ commands for incoming SMTP
+mail, and gives an error response for invalid data. Unfortunately, there are
+some SMTP clients that send syntactic junk. They can be accommodated by setting
+this option. Note that this is a syntax check only. See \helo@_verify@_hosts\
+if you want to do semantic checking.
+See also \helo@_allow@_chars\ for a way of extending the permitted character
+set.
+
+.conf helo@_allow@_chars string unset
+.index \\HELO\\||underscores in
+.index \\EHLO\\||underscores in
+.index underscore in \\EHLO\\/\\HELO\\
+This option can be set to a string of rogue characters that are permitted in
+all \\EHLO\\ and \\HELO\\ names in addition to the standard letters, digits,
+hyphens, and dots. If you really must allow underscores, you can set
+.display asis
+helo_allow_chars = _
+.endd
+Note that the value is one string, not a list.
+
+.conf helo@_lookup@_domains "domain list$**$" "$tt{@@:@@[]}"
+.index \\HELO\\||forcing reverse lookup
+.index \\EHLO\\||forcing reverse lookup
+If the domain given by a client in a \\HELO\\ or \\EHLO\\ command matches this
+list, a reverse lookup is done in order to establish the host's true name. The
+default forces a lookup if the client host gives the server's name or any of
+its IP addresses (in brackets), something that broken clients have been seen to
+do.
+
+.conf helo@_try@_verify@_hosts "host list$**$" unset
+.index \\HELO\\||verifying, optional
+.index \\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:
+.numberpars $.
+is an IP literal matching the calling address of the host (the RFCs
+specifically allow this), or
+.nextp
+.index DNS||reverse lookup
+.index reverse DNS lookup
+matches the host name that Exim obtains by doing a reverse lookup of the
+calling host address, or
+.nextp
+when looked up using \*gethostbyname()*\ (or \*getipnodebyname()*\ when
+available) yields the calling host address.
+.endp
+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.
+
+
+.conf helo@_verify@_hosts "host list$**$" unset
+.index \\HELO\\||verifying, mandatory
+.index \\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.
+
+.conf hold@_domains "domain list$**$" unset
+.index domain||delaying delivery
+.index delivery||delaying certain domains
+This option allows mail for particular domains to be held on the queue
+manually. The option is overridden if a message delivery is forced with the
+\-M-\, \-qf-\, \-Rf-\ or \-Sf-\ options, and also while testing or verifying
+addresses using \-bt-\ or \-bv-\. Otherwise, if a domain matches an item in
+\hold@_domains\, no routing or delivery for that address is done, and it is
+deferred every time the message is looked at.
+
+This option is intended as a temporary operational measure for delaying the
+delivery of mail while some problem is being sorted out, or some new
+configuration tested. If you just want to delay the processing of some
+domains until a queue run occurs, you should use \queue@_domains\ or
+\queue@_smtp@_domains\, not \hold@_domains\.
+
+A setting of \hold@_domains\ does not override Exim's code for removing
+messages from the queue if they have been there longer than the longest retry
+time in any retry rule. If you want to hold messages for longer than the normal
+retry times, insert a dummy retry rule with a long retry time.
+
+.conf host@_lookup "host list$**$" unset
+.index host||name lookup, forcing
+Exim does not look up the name of a calling host from its IP address unless it
+is required to compare against some host list, or the host matches
+\helo@_try@_verify@_hosts\ or \helo@_verify@_hosts\, or the host matches this
+option (which normally contains IP addresses rather than host names). The
+default configuration file contains
+.display asis
+host_lookup = *
+.endd
+which causes a lookup to happen for all hosts. If the expense of these lookups
+is felt to be too great, the setting can be changed or removed.
+
+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.
+
+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 =
+reverse@_host@_lookup"\ in ACLs.
+
+.conf host@_lookup@_order "string list" $tt{bydns:byaddr}
+This option specifies the order of different lookup methods when Exim is trying
+to find a host name from an IP address. The default is to do a DNS lookup
+first, and then to try a local lookup (using \*gethostbyaddr()*\ or equivalent)
+if that fails. You can change the order of these lookups, or omit one entirely,
+if you want.
+
+\**Warning**\: the `byaddr' method does not always yield aliases when there are
+multiple PTR records in the DNS and the IP address is not listed in
+\(/etc/hosts)\. Different operating systems give different results in this
+case. That is why the default tries a DNS lookup first.
+
+
+.conf host@_reject@_connection "host list$**$" unset
+.index host||rejecting connections from
+If this option is set, incoming SMTP calls from the hosts listed are rejected
+as soon as the connection is made.
+This option is obsolete, and retained only for backward compatibility, because
+nowadays the ACL specified by \acl@_smtp@_connect\ can also reject incoming
+connections immediately.
+
+The ability to give an immediate rejection (either by this option or using an
+ACL) is provided for use in unusual cases. Many hosts will just try again,
+sometimes without much delay. Normally, it is better to use an ACL to reject
+incoming messages at a later stage, such as after \\RCPT\\ commands. See
+chapter ~~CHAPACL.
+
+.conf hosts@_treat@_as@_local "domain list$**$" unset
+.index local host||domains treated as
+.index host||treated as local
+If this option is set, any host names that match the domain list are treated as
+if they were the local host when Exim is scanning host lists obtained from MX
+records
+or other sources. Note that the value of this option is a domain list, not a
+host list, because it is always used to check host names, not IP addresses.
+
+This option also applies when Exim is matching the special items
+\"@@mx@_any"\, \"@@mx@_primary"\, and \"@@mx@_secondary"\ in a domain list (see
+section ~~SECTdomainlist), and when checking the \hosts\ option in the \%smtp%\
+transport for the local host (see the \allow@_localhost\ option in that
+transport).
+See also \local@_interfaces\, \extra@_local@_interfaces\, and chapter
+~~CHAPinterfaces, which contains a discussion about local network interfaces
+and recognising the local host.
+
+.conf ignore@_bounce@_errors@_after time 10w
+.index bounce message||discarding
+.index discarding bounce message
+This option affects the processing of bounce messages that cannot be delivered,
+that is, those that suffer a permanent delivery failure. (Bounce messages that
+suffer temporary delivery failures are of course retried in the usual way.)
+
+After a permanent delivery failure, bounce messages are frozen,
+because there is no sender to whom they can be returned. When a frozen bounce
+message has been on the queue for more than the given time, it is unfrozen at
+the next queue run, and a further delivery is attempted. If delivery fails
+again, the bounce message is discarded. This makes it possible to keep failed
+bounce messages around for a shorter time than the normal maximum retry time
+for frozen messages. For example,
+.display asis
+ignore_bounce_errors_after = 12h
+.endd
+retries failed bounce message deliveries after 12 hours, discarding any further
+failures. If the value of this option is set to a zero time period, bounce
+failures are discarded immediately. Setting a very long time (as in the default
+value) has the effect of disabling this option. For ways of automatically
+dealing with other kinds of frozen message, see \auto@_thaw\ and
+\timeout@_frozen@_after\.
+
+.conf ignore@_fromline@_hosts "host list$**$" unset
+.index `From' line
+.index UUCP||`From' line
+Some broken SMTP clients insist on sending a UUCP-like `From' line before the
+headers of a message. By default this is treated as the start of the message's
+body, which means that any following headers are not recognized as such. Exim
+can be made to ignore it by setting \ignore@_fromline@_hosts\ to match those
+hosts that insist on sending it. If the sender is actually a local process
+rather than a remote host, and is using \-bs-\ to inject the messages,
+\ignore__fromline__local\ must be set to achieve this effect.
+
+.conf ignore@_fromline@_local boolean false
+See \ignore@_fromline@_hosts\ above.
+
+.conf keep@_malformed time 4d
+This option specifies the length of time to keep messages whose spool files
+have been corrupted in some way. This should, of course, never happen. At the
+next attempt to deliver such a message, it gets removed. The incident is
+logged.
+
+.conf ldap@_default@_servers "string list" unset
+.index LDAP||default servers
+This option provides a list of LDAP servers which are tried in turn when an
+LDAP query does not contain a server. See section ~~SECTforldaque for details
+of LDAP queries. This option is available only when Exim has been built with
+LDAP support.
+
+.conf ldap@_version integer unset
+.index LDAP||protocol version, forcing
+This option can be used to force Exim to set a specific protocol version for
+LDAP. If it option is unset, it is shown by the \-bP-\ command line option as
+-1. When this is the case, the default is 3 if \\LDAP@_VERSION3\\ is defined in
+the LDAP headers; otherwise it is 2. This option is available only when Exim
+has been built with LDAP support.
+
+
+.conf local@_from@_check boolean true
+.index ::Sender:: header line||disabling addition of
+.index ::From:: header line||disabling checking of
+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, and checks
+that the ::From:: header line matches the login of the calling user. You can
+use \local@_from@_prefix\ and \local@_from@_suffix\ to permit affixes on the
+local part. If the ::From:: header line does not match, Exim adds a ::Sender::
+header with an address constructed from the calling user's login and the
+default qualify domain.
+
+If \local@_from@_check\ is set false, the ::From:: header check is disabled,
+and no ::Sender:: header is ever added. If, in addition, you want to retain
+::Sender:: header lines supplied by untrusted users, you must also set
+\local@_sender@_retain\ to be true.
+
+.index envelope sender
+These options affect only the header lines in the message. The envelope sender
+is still forced to be the login id at the qualify domain unless
+\untrusted@_set@_sender\ permits the user to supply an envelope sender.
+Section ~~SECTthesenhea has more details about ::Sender:: processing.
+
+
+.conf local@_from@_prefix string unset
+When Exim checks the ::From:: header line of locally submitted messages for
+matching the login id (see \local@_from@_check\ above), it can be configured to
+ignore certain prefixes and suffixes in the local part of the address. This is
+done by setting \local@_from@_prefix\ and/or \local@_from@_suffix\ to
+appropriate lists, in the same form as the \local@_part@_prefix\ and
+\local@_part@_suffix\ router options (see chapter ~~CHAProutergeneric). For
+example, if
+.display asis
+local_from_prefix = *-
+.endd
+is set, a ::From:: line containing
+.display asis
+From: anything-user@your.domain.example
+.endd
+will not cause a ::Sender:: header to be added if \*user@@your.domain.example*\
+matches the actual sender address that is constructed from the login name and
+qualify domain.
+
+.conf local@_from@_suffix string unset
+See \local@_from@_prefix\ above.
+
+.conf local@_interfaces "string list" "see below"
+This option controls which network interfaces are used by the daemon for
+listening; they are also used to identify the local host when routing. Chapter
+~~CHAPinterfaces contains a full description of this option and the related
+options \extra@_local@_interfaces\ and \hosts@_treat@_as@_local\. The default
+value for \local@_interfaces\ is
+.display asis
+local_interfaces = 0.0.0.0
+.endd
+when Exim is built without IPv6 support; otherwise it is
+.display asis
+local_interfaces = <; ::0 ; 0.0.0.0
+.endd
+
+.conf local@_scan@_timeout time 5m
+.index timeout||for \*local@_scan()*\ function
+.index \*local@_scan()*\ function||timeout
+This timeout applies to the \*local@_scan()*\ function (see chapter
+~~CHAPlocalscan). Zero means `no timeout'. If the timeout is exceeded, the
+incoming message is rejected with a temporary error if it is an SMTP message.
+For a non-SMTP message, the message is dropped and Exim ends with a non-zero
+code. The incident is logged on the main and reject logs.
+
+
+.conf local@_sender@_retain boolean false
+.index ::Sender:: header line||retaining from local submission
+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.
+
+
+
+.conf localhost@_number string$**$ unset
+.index host||locally unique number for
+.index message||ids, with multiple hosts
+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
+after reading the configuration file (so that a number can be computed from the
+host name, for example) and the result of the expansion must be a number in the
+range 0--16 (or 0--10 on operating systems with case-insensitive file systems).
+This is available in subsequent string expansions via the variable
+\$localhost@_number$\. When \localhost@_number is set\, the final two
+characters of the message id, instead of just being a fractional part of the
+time, are computed from the time and the local host number as described in
+section ~~SECTmessiden.
+
+
+.conf log@_file@_path "string list$**$" "set at compile time"
+.index log||file path for
+This option sets the path which is used to determine the names of Exim's log
+files, or indicates that logging is to be to syslog, or both. It is expanded
+when Exim is entered, so it can, for example, contain a reference to the host
+name. If no specific path is set for the log files at compile or run time, they
+are written in a sub-directory called \(log)\ in Exim's spool directory.
+Chapter ~~CHAPlog contains further details about Exim's logging, and section
+~~SECTwhelogwri describes how the contents of \log@_file@_path\ are used. If
+this string is fixed at your installation (contains no expansion variables) it
+is recommended that you do not set this option in the configuration file, but
+instead supply the path using \\LOG@_FILE@_PATH\\ in \(Local/Makefile)\ so that
+it is available to Exim for logging errors detected early on -- in particular,
+failure to read the configuration file.
+
+.conf log@_selector string unset
+.index log||selectors
+This option can be used to reduce or increase the number of things that Exim
+writes to its log files. Its argument is made up of names preceded by plus or
+minus characters. For example:
+.display asis
+log_selector = +arguments -retry_defer
+.endd
+A list of possible names and what they control is given in the chapter on
+logging, in section ~~SECTlogselector.
+
+.conf log@_timezone boolean false
+.index log||timezone for entries
+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
+avoiding this problem is to set the timezone to UTC. An alternative is to set
+\log@_timezone\ true. This turns on the addition of the timezone offset to
+timestamps in log lines. Turning on this option can add quite a lot to the size
+of log files because each line is extended by 6 characters. Note that the
+\$tod@_log$\ variable contains the log timestamp without the zone, but there is
+another variable called \$tod@_zone$\ that contains just the timezone offset.
+
+.conf lookup@_open@_max integer 25
+.index too many open files
+.index open files, too many
+.index file||too many open
+.index lookup||maximum open files
+.index limit||open files for lookups
+This option limits the number of simultaneously open files for single-key
+lookups that use regular files (that is, \%lsearch%\, \%dbm%\, and \%cdb%\). Exim
+normally keeps these files open during routing, because often the same file is
+required several times. If the limit is reached, Exim closes the least recently
+used file. Note that if you are using the \*ndbm*\ library, it actually opens
+two files for each logical DBM database, though it still counts as one for the
+purposes of \lookup@_open@_max\. If you are getting `too many open files'
+errors with NDBM, you need to reduce the value of \lookup@_open@_max\.
+
+.conf max@_username@_length integer 0
+.index length of login name
+.index user name||maximum length
+.index limit||user name length
+Some operating systems are broken in that they truncate long arguments to
+\*getpwnam()*\ to eight characters, instead of returning `no such user'. If
+this option is set greater than zero, any attempt to call \*getpwnam()*\ with
+an argument that is longer behaves as if \*getpwnam()*\ failed.
+
+
+.conf message@_body@_visible integer 500
+.index body of message||visible size
+.index message||body, visible size
+This option specifies how much of a message's body is to be included in the
+\$message@_body$\ and \$message@_body@_end$\ expansion variables.
+
+.conf message@_id@_header@_domain string$**$ unset
+.index ::Message-ID:: header line
+If this option is set, the string is expanded and used as the right hand side
+(domain) of the ::Message-ID:: header that Exim creates if a
+locally-originated incoming message does not have one. `Locally-originated'
+means `not received over TCP/IP.'
+Otherwise, the primary host name is used.
+Only letters, digits, dot and hyphen are accepted; any other characters are
+replaced by hyphens. If the expansion is forced to fail, or if the result is an
+empty string, the option is ignored.
+
+.conf message@_id@_header@_text string$**$ unset
+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.
+
+.conf message@_logs boolean true
+.index message||log, disabling
+.index log||message log, disabling
+If this option is turned off, per-message log files are not created in the
+\(msglog)\ spool sub-directory. This reduces the amount of disk I/O required by
+Exim, by reducing the number of files involved in handling a message from a
+minimum of four (header spool file, body spool file, delivery journal, and
+per-message log) to three. The other major I/O activity is Exim's main log,
+which is not affected by this option.
+
+.conf message@_size@_limit string$**$ 50M
+.index message||size limit
+.index limit||message size
+.index size||of message, limit
+This option limits the maximum size of message that Exim will process. The
+value is expanded for each incoming
+connection so, for example, it can be made to depend on the IP address of the
+remote host for messages arriving via TCP/IP. \**Note**\: This limit cannot be
+made to depend on a message's sender or any other properties of an individual
+message, because it has to be advertised in the server's response to \\EHLO\\.
+String expansion failure causes a temporary error. A value of zero means no
+limit, but its use is not recommended. See also \bounce@_return@_size@_limit\.
+
+Incoming SMTP messages are failed with a 552 error if the limit is
+exceeded; locally-generated messages either get a stderr message or a delivery
+failure message to the sender, depending on the \-oe-\ setting. Rejection of an
+oversized message is logged in both the main and the reject logs. See also the
+generic transport option \message@_size@_limit\, which limits the size of
+message that an individual transport can process.
+
+.conf move@_frozen@_messages boolean false
+.index frozen messages||moving
+This option, which is available only if Exim has been built with the setting
+.display asis
+SUPPORT_MOVE_FROZEN_MESSAGES=yes
+.endd
+in \(Local/Makefile)\, causes frozen messages and their message logs to be
+moved from the \(input)\ and \(msglog)\ directories on the spool to \(Finput)\
+and \(Fmsglog)\, respectively. There is currently no support in Exim or the
+standard utilities for handling such moved messages, and they do not show up in
+lists generated by \-bp-\ or by the Exim monitor.
+
+.conf mysql@_servers "string list" unset
+.index MySQL||server list
+This option provides a list of MySQL servers and associated connection data, to
+be used in conjunction with \%mysql%\ lookups (see section ~~SECTsql). The
+option is available only if Exim has been built with MySQL support.
+
+.conf never@_users "string list" unset
+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.
+
+When Exim is built, an option called \\FIXED@_NEVER@_USERS\\ can be set to a
+list of users that must not be used for local deliveries. This list is fixed in
+the binary and cannot be overridden by the configuration file. By default, it
+contains just the single user name `root'. The \never@_users\ runtime option
+can be used to add more users to the fixed list.
+
+If a message is to be delivered as one of the users on the fixed list or the
+\never@_users\ list, an error occurs, and delivery is deferred. A common
+example is
+.display
+never@_users = root:daemon:bin
+.endd
+Including root is redundant if it is also on the fixed list, but it does no
+harm.
+This option overrides the \pipe@_as@_creator\ option of the \%pipe%\ transport
+driver.
+
+.conf oracle@_servers "string list" unset
+.index Oracle||server list
+This option provides a list of Oracle servers and associated connection data,
+to be used in conjunction with \%oracle%\ lookups (see section ~~SECTsql). The
+option is available only if Exim has been built with Oracle support.
+
+.conf percent@_hack@_domains "domain list$**$" unset
+.index `percent hack'
+.index source routing||in email address
+.index address||source-routed
+The `percent hack' is the convention whereby a local part containing a percent
+sign is re-interpreted as a new email address, with the percent replaced by @@.
+This is sometimes called `source routing', though that term is also applied to
+RFC 2822 addresses that begin with an @@ character. If this option is set, Exim
+implements the percent facility for those domains listed, but no others. This
+happens before an incoming SMTP address is tested against an ACL.
+
+\**Warning**\: The `percent hack' has often been abused by people who are
+trying to get round relaying restrictions. For this reason, it is best avoided
+if at all possible. Unfortunately, a number of less security-conscious MTAs
+implement it unconditionally. If you are running Exim on a gateway host, and
+routing mail through to internal MTAs without processing the local parts, it is
+a good idea to reject recipient addresses with percent characters in their
+local parts. Exim's default configuration does this.
+
+.conf perl@_at@_start boolean false
+This option is available only when Exim is built with an embedded Perl
+interpreter. See chapter ~~CHAPperl for details of its use.
+
+.conf perl@_startup string unset
+This option is available only when Exim is built with an embedded Perl
+interpreter. See chapter ~~CHAPperl for details of its use.
+
+.conf pgsql@_servers "string list" unset
+.index PostgreSQL lookup type||server list
+This option provides a list of PostgreSQL servers and associated connection
+data, to be used in conjunction with \%pgsql%\ lookups (see section ~~SECTsql).
+The option is available only if Exim has been built with PostgreSQL support.
+
+.conf pid@_file@_path string$**$ "set at compile time"
+.index daemon||pid file path
+.index pid file, path for
+This option sets the name of the file to which the Exim daemon writes its
+process id. The string is expanded, so it can contain, for example, references
+to the host name:
+.display asis
+pid_file_path = /var/log/$primary_hostname/exim.pid
+.endd
+If no path is set, the pid is written to the file \(exim-daemon.pid)\ in Exim's
+spool directory.
+The value set by the option can be overridden by the \-oP-\ command line
+option. A pid file is not written if a `non-standard' daemon is run by means of
+the \-oX-\ option, unless a path is explicitly supplied by \-oP-\.
+
+.conf pipelining@_advertise@_hosts "host list$**$" $*$
+.index \\PIPELINING\\||advertising, suppressing
+This option can be used to suppress the advertisement of the SMTP
+\\PIPELINING\\ extension to specific hosts. When \\PIPELINING\\ is not
+advertised and \smtp@_enforce@_sync\ is true, an Exim server enforces strict
+synchronization for each SMTP command and response.
+.em
+When \\PIPELINING\\ is advertised, Exim assumes that clients will use it; `out
+of order' commands that are `expected' do not count as protocol errors (see
+\smtp@_max@_synprot@_errors\).
+.nem
+
+.conf preserve@_message@_logs boolean false
+.index message logs, preserving
+If this option is set, message log files are not deleted when messages are
+completed. Instead, they are moved to a sub-directory of the spool directory
+called \(msglog.OLD)\, where they remain available for statistical or debugging
+purposes. This is a dangerous option to set on systems with any appreciable
+volume of mail. Use with care!
+
+.conf primary@_hostname string "see below"
+.index name||of local host
+.index host||name of local
+.index local host||name of
+.em
+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),
+.nem
+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.
+
+.em
+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\.
+.nem
+
+.conf print@_topbitchars boolean false
+.index printing characters
+.index 8-bit characters
+By default, Exim considers only those characters whose codes lie in the range
+32--126 to be printing characters. In a number of circumstances (for example,
+when writing log entries) non-printing characters are converted into escape
+sequences, primarily to avoid messing up the layout. If \print@_topbitchars\ is
+set, code values of 128 and above are also considered to be printing
+characters.
+
+.conf process@_log@_path string unset
+.index process log path
+.index log||process log
+.index \*exiwhat*\
+This option sets the name of the file to which an Exim process writes its
+`process log' when sent a USR1 signal. This is used by the \*exiwhat*\ utility
+script. If this option is unset, the file called \(exim-process.info)\ in
+Exim's spool directory is used. The ability to specify the name explicitly can
+be useful in environments where two different Exims are running, using
+different spool directories.
+
+.conf prod@_requires@_admin boolean true
+.index \-M-\ option
+.index \-R-\ option
+.index \-q-\ option
+The \-M-\, \-R-\, and \-q-\ command-line options require the caller to be an
+admin user unless \prod@_requires@_admin\ is set false. See also
+\queue@_list@_requires@_admin\.
+
+.conf qualify@_domain string "see below"
+.index domain||for qualifying addresses
+.index address||qualification
+This option specifies the domain name that is added to any sender addresses
+that do not have a domain qualification. It also applies to recipient addresses
+if \qualify@_recipient\ is not set. Such addresses are accepted by default only
+for locally-generated messages. Messages from external sources must always
+contain fully qualified addresses, unless the sending host matches
+\sender@_unqualified@_hosts\ or \recipient@_unqualified@_hosts\ (as
+appropriate), in which case incoming addresses are qualified with
+\qualify@_domain\ or \qualify@_recipient\ as necessary. Internally, Exim always
+works with fully qualified addresses.
+If \qualify@_domain\ is not set, it defaults to the \primary@_hostname\ value.
+
+.conf qualify@_recipient string "see below"
+This specifies the domain name that is added to any recipient addresses that do
+not have a domain qualification. Such addresses are accepted by default only
+for locally-generated messages. Messages from external sources must always
+contain fully qualified recipient addresses, unless the sending host matches
+\recipient@_unqualified@_hosts\,
+in which case incoming recipient addresses are qualified with
+\qualify@_recipient\.
+If \qualify@_recipient\ is not set, it defaults to the \qualify@_domain\ value.
+
+.conf queue@_domains "domain list$**$" unset
+.index domain||specifying non-immediate delivery
+.index queueing incoming messages
+.index message||queueing certain domains
+This option lists domains for which immediate delivery is not required.
+A delivery process is started whenever a message is received, but only those
+domains that do not match are processed. All other deliveries wait until the
+next queue run. See also \hold@_domains\ and \queue@_smtp@_domains\.
+
+.conf queue@_list@_requires@_admin boolean true
+.index \-bp-\ option
+The \-bp-\ command-line option, which lists the messages that are on the queue,
+requires the caller to be an admin user unless \queue__list__requires__admin\
+is set false. See also \prod@_requires@_admin\.
+
+.conf queue@_only boolean false
+.index queueing incoming messages
+.index message||queueing unconditionally
+If \queue@_only\ is set, a delivery process is not automatically started
+whenever a message is received. Instead, the message waits on the queue for the
+next queue run. Even if \queue@_only\ is false, incoming messages may not get
+delivered immediately when certain conditions (such as heavy load) occur.
+
+The \-odq-\ command line has the same effect as \queue@_only\. The \-odb-\ and
+\-odi-\ command line options override \queue@_only\ unless
+\queue@_only@_override\ is set false. See also \queue@_only@_file\,
+\queue@_only@_load\, and \smtp@_accept@_queue\.
+
+.conf queue@_only@_file string unset
+.index queueing incoming messages
+.index message||queueing by file existence
+This option can be set to a colon-separated list of absolute path names, each
+one optionally preceded by `smtp'. When Exim is receiving a message,
+it tests for the existence of each listed path using a call to \*stat()*\. For
+each path that exists, the corresponding queuing option is set.
+For paths with no prefix, \queue@_only\ is set; for paths prefixed by `smtp',
+\queue@_smtp@_domains\ is set to match all domains. So, for example,
+.display asis
+queue_only_file = smtp/some/file
+.endd
+causes Exim to behave as if \queue@_smtp@_domains\ were set to `$*$' whenever
+\(/some/file)\ exists.
+
+.conf queue@_only@_load fixed-point unset
+.index load average
+.index queueing incoming messages
+.index message||queueing by load
+If the system load average is higher than this value, incoming messages from
+all sources are queued, and no automatic deliveries are started. If this
+happens during local or remote SMTP input, all subsequent messages on the same
+connection are queued. Deliveries will subsequently be performed by queue
+runner processes. This option has no effect on ancient operating systems on
+which Exim cannot determine the load average. See also
+\deliver@_queue@_load@_max\ and \smtp@_load@_reserve\.
+
+.conf queue@_only@_override boolean true
+.index queueing incoming messages
+When this option is true, the \-od\*x*\-\ command line options override the
+setting of \queue@_only\ or \queue@_only@_file\ in the configuration file. If
+\queue@_only@_override\ is set false, the \-od\*x*\-\ options cannot be used to
+override; they are accepted, but ignored.
+
+.conf queue@_run@_in@_order boolean false
+.index queue runner||processing messages in order
+If this option is set, queue runs happen in order of message arrival instead of
+in an arbitrary order. For this to happen, a complete list of the entire queue
+must be set up before the deliveries start. When the queue is all in a single
+directory (the default), this happens anyway, but if \split@_spool@_directory\
+is set it does not -- for delivery in random order, the sub-directories are
+processed one at a time (in random order), to avoid setting up one huge list.
+Thus, setting \queue@_run@_in@_order\ with \split@_spool@_directory\ may
+degrade performance when the queue is large. In most situations,
+\queue@_run@_in@_order\ should not be set.
+
+.conf queue@_run@_max integer 5
+.index queue runner||maximum number of
+This controls the maximum number of queue runner processes that an Exim daemon
+can run simultaneously. This does not mean that it starts them all at once,
+but rather that if the maximum number are still running when the time comes to
+start another one, it refrains from starting another one. This can happen with
+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.
+
+.conf queue@_smtp@_domains "domain list$**$" unset
+.index queueing incoming messages
+.index message||queueing remote deliveries
+When this option is set, a delivery process is started whenever a message is
+received, routing is performed, and local deliveries take place.
+However, if any SMTP deliveries are required for domains that match
+\queue@_smtp@_domains\, they are not immediately delivered, but instead the
+message waits on the queue for the next queue run. Since routing of the message
+has taken place, Exim knows to which remote hosts it must be delivered, and so
+when the queue run happens, multiple messages for the same host are delivered
+over a single SMTP connection. The \-odqs-\ command line option causes all SMTP
+deliveries to be queued in this way, and is equivalent to setting
+\queue@_smtp@_domains\ to `$*$'. See also \hold@_domains\ and \queue@_domains\.
+
+.conf receive@_timeout time 0s
+.index timeout||for non-SMTP input
+This option sets the timeout for accepting a non-SMTP message, that is, the
+maximum time that Exim waits when reading a message on the standard input. If
+the value is zero, it will wait for ever. This setting is overridden by the
+\-or-\ command line option. The timeout for incoming SMTP messages is
+controlled by \smtp@_receive@_timeout\.
+
+.index customizing|| ::Received:: header
+.index ::Received:: header line||customizing
+.conf received@_header@_text string$**$ "see below"
+This string defines the contents of the ::Received:: message header that is
+added to each message, except for the timestamp, which is automatically added
+on at the end (preceded by a semicolon). The string is expanded each time it is
+used. If the expansion yields an empty string, no ::Received:: header line is
+added to the message. Otherwise, the string should start with the text
+`Received:' and conform to the RFC 2822 specification for ::Received:: header
+lines. The default setting is:
+.display asis
+received_header_text = Received: \
+ ${if def:sender_rcvhost {from $sender_rcvhost\n\t}\
+ {${if def:sender_ident {from $sender_ident }}\
+ ${if def:sender_helo_name {(helo=$sender_helo_name)\n\t}}}}\
+ by $primary_hostname \
+ ${if def:received_protocol {with $received_protocol}} \
+ ${if def:tls_cipher {($tls_cipher)\n\t}}\
+ (Exim $version_number)\n\t\
+ id $message_id\
+ ${if def:received_for {\n\tfor $received_for}}
+.endd
+Note the use of quotes, to allow the sequences \"@\n"\ and \"@\t"\ to be used
+for newlines and tabs, respectively. The reference to the TLS cipher is omitted
+when Exim is built without TLS support. The use of conditional expansions
+ensures that this works for both locally generated messages and messages
+received from remote hosts, giving header lines such as the following:
+.display asis
+Received: from scrooge.carol.example ([192.168.12.25] ident=root)
+ by marley.carol.example with esmtp (Exim 4.00)
+ id 16IOWa-00019l-00
+ for chas@dickens.example; Tue, 25 Dec 2001 14:43:44 +0000
+Received: by scrooge.carol.example with local (Exim 4.00)
+ id 16IOWW-000083-00; Tue, 25 Dec 2001 14:43:41 +0000
+.endd
+.em
+Until the body of the message has been received, the timestamp is the time when
+the message started to be received. Once the body has arrived, and all policy
+checks have taken place, the timestamp is updated to the time at which the
+message was accepted.
+.nem
+
+.conf received@_headers@_max integer 30
+.index loop||prevention
+.index mail loop prevention
+.index ::Received:: header line||counting
+When a message is to be delivered, the number of ::Received:: headers is
+counted, and if it is greater than this parameter, a mail loop is assumed to
+have occurred, the delivery is abandoned, and an error message is generated.
+This applies to both local and remote deliveries.
+
+.conf recipient@_unqualified@_hosts "host list$**$" unset
+.index unqualified addresses
+.index host||unqualified addresses from
+This option lists those hosts from which Exim is prepared to accept unqualified
+recipient addresses in message envelopes. The addresses are made fully
+qualified by the addition of the \qualify@_recipient\ value. This option also
+affects message header lines. Exim does not reject unqualified recipient
+addresses in headers, but it qualifies them only if the message came from a
+host that matches \recipient@_unqualified@_hosts\,
+.em
+or if the message was submitted locally (not using TCP/IP), and the \-bnq-\
+option was not set.
+.nem
+
+.conf recipients@_max integer 0
+.index limit||number of recipients
+.index recipient||maximum number
+If this option is set greater than zero, it specifies the maximum number of
+original recipients for any message. Additional recipients that are generated
+by aliasing or forwarding do not count. SMTP messages get a 452 response for
+all recipients over the limit; earlier recipients are delivered as normal.
+Non-SMTP messages with too many recipients are failed, and no deliveries are
+done.
+.index \\RCPT\\||maximum number of incoming
+Note that the RFCs specify that an SMTP server should accept at least 100
+\\RCPT\\ commands in a single message.
+
+.conf recipients@_max@_reject boolean false
+If this option is set true, Exim rejects SMTP messages containing too many
+recipients by giving 552 errors to the surplus \\RCPT\\ commands, and a 554
+error to the eventual \\DATA\\ command. Otherwise (the default) it gives a 452
+error to the surplus \\RCPT\\ commands and accepts the message on behalf of the
+initial set of recipients. The remote server should then re-send the message
+for the remaining recipients at a later time.
+
+.conf remote@_max@_parallel integer 2
+.index delivery||parallelism for remote
+This option controls parallel delivery of one message to a number of remote
+hosts. If the value is less than 2, parallel delivery is disabled, and Exim
+does all the remote deliveries for a message one by one. Otherwise, if a single
+message has to be delivered to more than one remote host, or if several copies
+have to be sent to the same remote host, up to \remote@_max@_parallel\
+deliveries are done simultaneously. If more than \remote@_max@_parallel\
+deliveries are required, the maximum number of processes are started, and as
+each one finishes, another is begun. The order of starting processes is the
+same as if sequential delivery were being done, and can be controlled by the
+\remote@_sort@_domains\ option. If parallel delivery takes place while running
+with debugging turned on, the debugging output from each delivery process is
+tagged with its process id.
+
+This option controls only the maximum number of parallel deliveries for one
+message in one Exim delivery process. Because Exim has no central queue
+manager, there is no way of controlling the total number of simultaneous
+deliveries if the configuration allows a delivery attempt as soon as a message
+is received.
+.index number of deliveries
+.index delivery||maximum number of
+If you want to control the total number of deliveries on the system, you
+need to set the \queue@_only\ option. This ensures that all incoming messages
+are added to the queue without starting a delivery process. Then set up an Exim
+daemon to start queue runner processes at appropriate intervals (probably
+fairly often, for example, every minute), and limit the total number of queue
+runners by setting the \queue__run__max\ parameter. Because each queue runner
+delivers only one message at a time, the maximum number of deliveries that can
+then take place at once is \queue@_run@_max\ multiplied by
+\remote@_max@_parallel\.
+
+If it is purely remote deliveries you want to control, use \queue@_smtp\
+instead of \queue@_only\. This has the added benefit of doing the SMTP routing
+before queuing, so that several messages for the same host will eventually get
+delivered down the same connection.
+
+.conf remote@_sort@_domains "domain list$**$" unset
+.index sorting remote deliveries
+.index delivery||sorting remote
+When there are a number of remote deliveries for a message, they are sorted by
+domain into the order given by this list. For example,
+.display asis
+remote_sort_domains = *.cam.ac.uk:*.uk
+.endd
+would attempt to deliver to all addresses in the \*cam.ac.uk*\ domain first, then
+to those in the \uk\ domain, then to any others.
+
+.conf retry@_data@_expire time 7d
+.index hints database||data expiry
+This option sets a `use before' time on retry information in Exim's hints
+database. Any older retry data is ignored. This means that, for example, once a
+host has not been tried for 7 days, Exim behaves as if it has no knowledge of
+past failures.
+
+.conf retry@_interval@_max time 24h
+.index retry||limit on interval
+.index limit||on retry interval
+Chapter ~~CHAPretry describes Exim's mechanisms for controlling the intervals
+between delivery attempts for messages that cannot be delivered straight away.
+This option sets an overall limit to the length of time between retries.
+
+.conf return@_path@_remove boolean true
+.index ::Return-path:: header line||removing
+RFC 2821, section 4.4, states that an SMTP server must insert a ::Return-path::
+header line into a message when it makes a `final delivery'. The ::Return-path::
+header preserves the sender address as received in the \\MAIL\\ command. This
+description implies that this header should not be present in an incoming
+message. If \return@_path@_remove\ is true, any existing ::Return-path::
+headers are removed from messages at the time they are received. Exim's
+transports have options for adding ::Return-path:: headers at the time of
+delivery. They are normally used only for final local deliveries.
+
+.conf return@_size@_limit integer 100K
+This option is an obsolete synonym for \bounce@_return@_size@_limit\.
+
+.conf rfc1413@_hosts "host list$**$" $*$
+.index RFC 1413
+.index host||for RFC 1413 calls
+RFC 1413 identification calls are made to any client host which matches an item
+in the list.
+
+.conf rfc1413@_query@_timeout time 30s
+.index RFC 1413||query timeout
+.index timeout||for RFC 1413 call
+This sets the timeout on RFC 1413 identification calls. If it is set to zero,
+no RFC 1413 calls are ever made.
+
+.conf sender@_unqualified@_hosts "host list$**$" unset
+.index unqualified addresses
+.index host||unqualified addresses from
+This option lists those hosts from which Exim is prepared to accept unqualified
+sender addresses. The addresses are made fully qualified by the addition of
+\qualify@_domain\. This option also affects message header lines. Exim does not
+reject unqualified addresses in headers that contain sender addresses, but it
+qualifies them only if the message came from a host that matches
+\sender@_unqualified@_hosts\,
+.em
+or if the message was submitted locally (not using TCP/IP), and the \-bnq-\
+option was not set.
+.nem
+
+.conf smtp@_accept@_keepalive boolean true
+.index keepalive||on incoming connection
+This option controls the setting of the \\SO@_KEEPALIVE\\ option on incoming
+TCP/IP socket connections. When set, it causes the kernel to probe idle
+connections periodically, by sending packets with `old' sequence numbers. The
+other end of the connection should send an acknowledgement if the connection is
+still okay or a reset if the connection has been aborted. The reason for doing
+this is that it has the beneficial effect of freeing up certain types of
+connection that can get stuck when the remote host is disconnected without
+tidying up the TCP/IP call properly. The keepalive mechanism takes several
+hours to detect unreachable hosts.
+
+
+.conf smtp@_accept@_max integer 20
+.index limit||incoming SMTP connections
+.index SMTP||incoming connection count
+.index inetd
+This option specifies the maximum number of simultaneous incoming SMTP calls
+that Exim will accept. It applies only to the listening daemon; there is no
+control (in Exim) when incoming SMTP is being handled by \*inetd*\. If the value
+is set to zero, no limit is applied. However, it is required to be non-zero if
+either \smtp@_accept@_max@_per@_host\ or \smtp@_accept@_queue\ is set. See also
+\smtp@_accept@_reserve\.
+
+
+.conf smtp@_accept@_max@_nonmail integer 10
+.index limit||non-mail SMTP commands
+.index SMTP||limiting non-mail commands
+Exim counts the number of `non-mail' commands in an SMTP session, and drops the
+connection if there are too many. This option defines `too many'. The check
+catches some denial-of-service attacks, repeated failing \\AUTH\\s, or a mad
+client looping sending \\EHLO\\, for example. The check is applied only if the
+client host matches \smtp@_accept@_max@_nonmail@_hosts\.
+
+When a new message is expected, one occurrence of \\RSET\\ is not counted. This
+allows a client to send one \\RSET\\ between messages (this is not necessary,
+but some clients do it). Exim also allows one uncounted occurence of \\HELO\\
+or \\EHLO\\, and one occurrence of \\STARTTLS\\ between messages. After
+starting up a TLS session, another \\EHLO\\ is expected, and so it too is not
+counted. The first occurrence of \\AUTH\\ in a connection, or immediately
+following \\STARTTLS\\ is not counted. Otherwise, all commands other than
+\\MAIL\\, \\RCPT\\, \\DATA\\, and \\QUIT\\ are counted.
+
+.conf smtp@_accept@_max@_nonmail@_hosts "host list$**$" $*$
+You can control which hosts are subject to the \smtp@_accept@_max@_nonmail\
+check by setting this option. The default value makes it apply to all hosts. By
+changing the value, you can exclude any badly-behaved hosts that you have to
+live with.
+
+
+.conf smtp@_accept@_max@_per@_connection integer 1000
+.index SMTP||incoming message count, limiting
+.index limit||messages per SMTP connection
+The value of this option limits the number of \\MAIL\\ commands that Exim is
+prepared to accept over a single SMTP connection, whether or not each command
+results in the transfer of a message. After the limit is reached, a 421
+response is given to subsequent \\MAIL\\ commands. This limit is a safety
+precaution against a client that goes mad (incidents of this type have been
+seen).
+
+.conf smtp@_accept@_max@_per@_host string$**$ unset
+.index limit||SMTP connections from one host
+.index host||limiting SMTP connections from
+This option restricts the number of simultaneous IP connections from a single
+host (strictly, from a single IP address) to the Exim daemon. The option is
+expanded, to enable different limits to be applied to different hosts by
+reference to \$sender@_host@_address$\. Once the limit is reached, additional
+connection attempts from the same host are rejected with error code 421. The
+default value of zero imposes no limit. If this option is set, it is required
+that \smtp@_accept@_max\ be non-zero.
+
+\**Warning**\: When setting this option you should not use any expansion
+constructions that take an appreciable amount of time. The expansion and test
+happen in the main daemon loop, in order to reject additional connections
+without forking additional processes (otherwise a denial-of-service attack
+could cause a vast number or processes to be created). While the daemon is
+doing this processing, it cannot accept any other incoming connections.
+
+
+.conf smtp@_accept@_queue integer 0
+.index SMTP||incoming connection count
+.index queueing incoming messages
+.index message||queueing by SMTP connection count
+If the number of simultaneous incoming SMTP calls handled via the listening
+daemon exceeds this value, messages received by SMTP are just placed on the
+queue; no delivery processes are started automatically. A value of zero implies
+no limit, and clearly any non-zero value is useful only if it is less than the
+\smtp@_accept@_max\ value (unless that is zero). See also \queue@_only\,
+\queue@_only@_load\, \queue@_smtp@_domains\, and the various \-od-\ command
+line options.
+
+.conf smtp@_accept@_queue@_per@_connection integer 10
+.index queueing incoming messages
+.index message||queueing by message count
+This option limits the number of delivery processes that Exim starts
+automatically when receiving messages via SMTP, whether via the daemon or by
+the use of \-bs-\ or \-bS-\. If the value of the option is greater than zero,
+and the number of messages received in a single SMTP session exceeds this
+number, subsequent messages are placed on the queue, but no delivery processes
+are started. This helps to limit the number of Exim processes when a server
+restarts after downtime and there is a lot of mail waiting for it on other
+systems. On large systems, the default should probably be increased, and on
+dial-in client systems it should probably be set to zero (that is, disabled).
+
+.conf smtp@_accept@_reserve integer 0
+.index SMTP||incoming call count
+.index host||reserved
+When \smtp@_accept@_max\ is set greater than zero, this option specifies a
+number of SMTP connections that are reserved for connections from the hosts
+that are specified in \smtp@_reserve@_hosts\. The value set in
+\smtp@_accept@_max\ includes this reserve pool. The specified hosts are not
+restricted to this number of connections; the option specifies a minimum number
+of connection slots for them, not a maximum. It is a guarantee that that group
+of hosts can always get at least \smtp@_accept@_reserve\ connections.
+
+For example, if \smtp@_accept@_max\ is set to 50 and \smtp@_accept@_reserve\ is
+set to 5, once there are 45 active connections (from any hosts), new
+connections are accepted only from hosts listed in \smtp@_reserve@_hosts\.
+See also \smtp@_accept@_max@_per@_host\.
+
+.em
+.conf smtp@_active@_hostname string$**$ unset
+.index host||name in SMTP responses
+.index SMTP||host name in responses
+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. 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 used. Other expansion failures cause a
+message to be written to the main and panic logs, and the SMTP command receives
+a temporary error. Typically, the value of \smtp@_active@_hostname\ depends on
+the incoming interface address. For example:
+.display asis
+smtp_active_hostname = ${if eq{$interface_address}{10.0.0.1}\
+ {cox.mydomain}{box.mydomain}}
+.endd
+If you set \smtp@_active@_hostname\, you probably also want to set
+\smtp@_banner\, since its default value references \$primary@_hostname$\.
+.nem
+
+.conf smtp@_banner string$**$ "see below"
+.index SMTP||welcome banner
+.index banner for SMTP
+.index welcome banner for SMTP
+.index customizing||SMTP banner
+This string, which is expanded every time it is used, is output as the initial
+positive response to an SMTP connection. The default setting is:
+.display asis
+smtp_banner = $primary_hostname ESMTP Exim $version_number \
+ $tod_full
+.endd
+Failure to expand the string causes a panic error. If you want to create a
+multiline response to the initial SMTP connection, use `@\n' in the string at
+appropriate points, but not at the end. Note that the 220 code is not included
+in this string. Exim adds it automatically (several times in the case of a
+multiline response).
+
+.conf smtp@_check@_spool@_space boolean true
+.index checking disk space
+.index disk space, checking
+.index spool directory||checking space
+When this option is set, if an incoming SMTP session encounters the \\SIZE\\
+option on a \\MAIL\\ command, it checks that there is enough space in the
+spool directory's partition to accept a message of that size, while still
+leaving free the amount specified by \check@_spool@_space\ (even if that value
+is zero). If there isn't enough space, a temporary error code is returned.
+
+.conf smtp@_connect@_backlog integer 20
+.index connection backlog
+.index SMTP||connection backlog
+.index backlog of connections
+This option specifies a maximum number of waiting SMTP connections. Exim passes
+this value to the TCP/IP system when it sets up its listener. Once this number
+of connections are waiting for the daemon's attention, subsequent connection
+attempts are refused at the TCP/IP level. At least, that is what the manuals
+say; in some circumstances such connection attempts have been observed to time
+out instead. For large systems it is probably a good idea to increase the
+value (to 50, say). It also gives some protection against denial-of-service
+attacks by SYN flooding.
+
+.conf smtp@_enforce@_sync boolean true
+.index SMTP||synchronization checking
+.index synchronization checking in SMTP
+The SMTP protocol specification requires the client to wait for a response from
+the server at certain points in the dialogue. Without \\PIPELINING\\ these
+synchronization points are after every command; with \\PIPELINING\\ they are
+fewer, but they still exist. Some spamming sites send out a complete set of
+SMTP commands without waiting for any response. Exim protects against this by
+rejecting a message if the client has sent further input when it should not
+have. The error response `554 SMTP synchronization error' is sent, and the
+connection is dropped. Testing for this error cannot be perfect because of
+transmission delays (unexpected input may be on its way but not yet received
+when Exim checks). However, it does detect many instances. The check can be
+disabled by setting \smtp@_enforce@_sync\ false.
+.em
+See also \pipelining@_advertise@_hosts\.
+.nem
+
+.conf smtp@_etrn@_command string$**$ unset
+.index \\ETRN\\||command to be run
+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
+independently expanded. The expansion variable \$domain$\ is set to the
+argument of the \\ETRN\\ command, and no syntax checking is done on it. For
+example:
+.display asis
+smtp_etrn_command = /etc/etrn_command $domain $sender_host_address
+.endd
+A new process is created to run the command, but Exim does not wait for it to
+complete. Consequently, its status cannot be checked. If the command cannot be
+run, a line is written to the panic log, but the \\ETRN\\ caller still receives
+a 250 success response. Exim is normally running under its own uid when
+receiving SMTP, so it is not possible for it to change the uid before running
+the command.
+
+.conf smtp@_etrn@_serialize boolean true
+.index \\ETRN\\||serializing
+When this option is set, it prevents the simultaneous execution of more than
+one identical command as a result of \\ETRN\\ in an SMTP connection. See
+section ~~SECTETRN for details.
+
+.conf smtp@_load@_reserve fixed-point unset
+.index load average
+If the system load average ever gets higher than this, incoming SMTP calls are
+accepted only from those hosts that match an entry in \smtp@_reserve@_hosts\.
+If \smtp@_reserve@_hosts\ is not set, no incoming SMTP calls are accepted when
+the load is over the limit. The option has no effect on ancient operating
+systems on which Exim cannot determine the load average. See also
+\deliver@_queue@_load@_max\ and \queue@_only@_load\.
+
+
+.conf smtp@_max@_synprot@_errors integer 3
+.index SMTP||limiting syntax and protocol errors
+.index limit||SMTP syntax and protocol errors
+Exim rejects SMTP commands that contain syntax or protocol errors. In
+particular, a syntactically invalid email address, as in this command:
+.display asis
+RCPT TO:<abc xyz@a.b.c>
+.endd
+causes immediate rejection of the command, before any other tests are done.
+(The ACL cannot be run if there is no valid address to set up for it.) An
+example of a protocol error is receiving \\RCPT\\ before \\MAIL\\. If there are
+too many syntax or protocol errors in one SMTP session, the connection is
+dropped. The limit is set by this option.
+
+.em
+.index \\PIPELINING\\||expected errors
+When the \\PIPELINING\\ extension to SMTP is in use, some protocol errors are
+`expected', for instance, a \\RCPT\\ command after a rejected \\MAIL\\ command.
+Exim assumes that \\PIPELINING\\ will be used if it advertises it (see
+\pipelining@_advertise@_hosts\), and in this situation, `expected' errors do
+not count towards the limit.
+.nem
+
+
+.conf smtp@_max@_unknown@_commands integer 3
+.index SMTP||limiting unknown commands
+.index limit||unknown SMTP commands
+If there are too many unrecognized commands in an incoming SMTP session, an
+Exim server drops the connection. This is a defence against some kinds of abuse
+that subvert web
+.em
+clients
+.nem
+into making connections to SMTP ports; in these circumstances, a number of
+non-SMTP command lines are sent first.
+
+
+.conf smtp@_ratelimit@_hosts "host list$**$" unset
+.index SMTP||rate limiting
+.index limit||rate of message arrival
+.index \\RCPT\\||rate limiting
+Some sites find it helpful to be able to limit the rate at which certain hosts
+can send them messages, and the rate at which an individual message can specify
+recipients. When a host matches \smtp@_ratelimit@_hosts\, the values of
+\smtp@_ratelimit@_mail\ and \smtp@_ratelimit@_rcpt\ are used to control the
+rate of acceptance of \\MAIL\\ and \\RCPT\\ commands in a single SMTP session,
+respectively. Each option, if set, must contain a set of four comma-separated
+values:
+.numberpars $.
+A threshold, before which there is no rate limiting.
+.nextp
+An initial time delay. Unlike other times in Exim, numbers with decimal
+fractional parts are allowed here.
+.nextp
+A factor by which to increase the delay each time.
+.nextp
+A maximum value for the delay. This should normally be less than 5 minutes,
+because after that time, the client is liable to timeout the SMTP command.
+.endp
+For example, these settings have been used successfully at the site which
+first suggested this feature, for controlling mail from their customers:
+.display asis
+smtp_ratelimit_mail = 2,0.5s,1.05,4m
+smtp_ratelimit_rcpt = 4,0.25s,1.015,4m
+.endd
+The first setting specifies delays that are applied to \\MAIL\\ commands after
+two have been received over a single connection. The initial delay is 0.5
+seconds, increasing by a factor of 1.05 each time. The second setting applies
+delays to \\RCPT\\ commands when more than four occur in a single message.
+
+It is also possible to configure delays explicitly in ACLs. See section
+~~SECTACLmodi for details.
+
+
+.conf smtp@_ratelimit@_mail string unset
+See \smtp@_ratelimit@_hosts\ above.
+
+.conf smtp@_ratelimit@_rcpt string unset
+See \smtp@_ratelimit@_hosts\ above.
+
+.conf smtp@_receive@_timeout time 5m
+.index timeout||for SMTP input
+.index SMTP||timeout, input
+This sets a timeout value for SMTP reception. It applies to all forms of SMTP
+input, including batch SMTP. If a line of input (either an SMTP command or a
+data line) is not received within this time, the SMTP connection is dropped and
+the message is abandoned.
+A line is written to the log containing one of the following messages:
+.display asis
+SMTP command timeout on connection from...
+SMTP data timeout on connection from...
+.endd
+The former means that Exim was expecting to read an SMTP command; the latter
+means that it was in the \\DATA\\ phase, reading the contents of a message.
+
+
+.index \-os-\ option
+The value set by this option can be overridden by the
+\-os-\ command-line option. A setting of zero time disables the timeout, but
+this should never be used for SMTP over TCP/IP. (It can be useful in some cases
+of local input using \-bs-\ or \-bS-\.) For non-SMTP input, the reception
+timeout is controlled by \receive@_timeout\ and \-or-\.
+
+.conf smtp@_reserve@_hosts "host list$**$" unset
+This option defines hosts for which SMTP connections are reserved; see
+\smtp@_accept@_reserve\ and \smtp@_load@_reserve\ above.
+
+.conf smtp@_return@_error@_details boolean false
+.index SMTP||details policy failures
+.index policy control||rejection, returning details
+In the default state, Exim uses bland messages such as
+`Administrative prohibition' when it rejects SMTP commands for policy
+reasons. Many sysadmins like this because it gives away little information
+to spammers. However, some other syadmins who are applying strict checking
+policies want to give out much fuller information about failures. Setting
+\smtp@_return@_error@_details\ true causes Exim to be more forthcoming. For
+example, instead of `Administrative prohibition', it might give:
+.display asis
+550-Rejected after DATA: '>' missing at end of address:
+550 failing address in "From" header is: <user@dom.ain
+.endd
+
+.conf split@_spool@_directory boolean false
+.index multiple spool directories
+.index spool directory||split
+.index directories, multiple
+If this option is set, it causes Exim to split its input directory into 62
+subdirectories, each with a single alphanumeric character as its name. The
+sixth character of the message id is used to allocate messages to
+subdirectories; this is the least significant base-62 digit of the time of
+arrival of the message.
+
+Splitting up the spool in this way may provide better performance on systems
+where there are long mail queues, by reducing the number of files in any one
+directory. The msglog directory is also split up in a similar way to the input
+directory; however, if \preserve@_message@_logs\ is set, all old msglog files
+are still placed in the single directory \(msglog.OLD)\.
+
+It is not necessary to take any special action for existing messages when
+changing \split@_spool@_directory\. Exim notices messages that are in the
+`wrong' place, and continues to process them. If the option is turned off after
+a period of being on, the subdirectories will eventually empty and be
+automatically deleted.
+
+When \split@_spool@_directory\ is set, the behaviour of queue runner processes
+changes. Instead of creating a list of all messages in the queue, and then
+trying to deliver each one in turn, it constructs a list of those in one
+sub-directory and tries to deliver them, before moving on to the next
+sub-directory. The sub-directories are processed in a random order. This
+spreads out the scanning of the input directories, and uses less memory. It is
+particularly beneficial when there are lots of messages on the queue. However,
+if \queue@_run@_in@_order\ is set, none of this new processing happens. The
+entire queue has to be scanned and sorted before any deliveries can start.
+
+.conf spool@_directory string$**$ "set at compile time"
+.index spool directory||path to
+This defines the directory in which Exim keeps its spool, that is, the messages
+it is waiting to deliver. The default value is taken from the compile-time
+configuration setting, if there is one. If not, this option must be set. The
+string is expanded, so it can contain, for example, a reference to
+\$primary@_hostname$\.
+
+If the spool directory name is fixed on your installation, it is recommended
+that you set it at build time rather than from this option, particularly if the
+log files are being written to the spool directory (see \log@_file@_path\).
+Otherwise log files cannot be used for errors that are detected early on, such
+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.
+
+.conf strip@_excess@_angle@_brackets boolean false
+.index angle brackets, excess
+If this option is set, redundant pairs of angle brackets round `route-addr'
+items in addresses are stripped. For example, \*@<@<xxx@@a.b.c.d@>@>*\ is treated
+as \*@<xxx@@a.b.c.d@>*\. If this is in the envelope and the message is passed on
+to another MTA, the excess angle brackets are not passed on. If this option is
+not set, multiple pairs of angle brackets cause a syntax error.
+
+.conf strip@_trailing@_dot boolean false
+.index trailing dot on domain
+.index dot||trailing on domain
+If this option is set, a trailing dot at the end of a domain in an address is
+ignored. If this is in the envelope and the message is passed on to another
+MTA, the dot is not passed on. If this option is not set, a dot at the end of a
+domain causes a syntax error.
+.em
+However, addresses in header lines are checked only when an ACL requests header
+syntax checking.
+.nem
+
+.conf syslog@_duplication boolean true
+.index syslog||duplicate log lines, suppressing
+When Exim is logging to syslog, it writes the log lines for its three
+separate logs at different syslog priorities so that they can in principle
+be separated on the logging hosts. Some installations do not require this
+separation, and in those cases, the duplication of certain log lines is a
+nuisance. If \syslog@_duplication\ is set false, only one copy of any
+particular log line is written to syslog. For lines that normally go to
+both the main log and the reject log, the reject log version (possibly
+containing message header lines) is written, at \\LOG@_NOTICE\\ priority.
+Lines that normally go to both the main and the panic log are written at
+the \\LOG@_ALERT\\ priority.
+
+.conf syslog@_facility string unset
+.index syslog||facility, setting
+This option sets the syslog `facility' name, used when Exim is logging to
+syslog. The value must be one of the strings `mail', `user', `news', `uucp',
+`daemon', or `local\*x*\' where \*x*\ is a digit between 0 and 7. If this
+option is unset, `mail' is used. See chapter ~~CHAPlog for details of Exim's
+logging.
+
+
+.conf syslog@_processname string "$tt{exim}"
+.index syslog||process name, setting
+This option sets the syslog `ident' name, used when Exim is logging to syslog.
+The value must be no longer than 32 characters. See chapter ~~CHAPlog for
+details of Exim's logging.
+
+
+.conf syslog@_timestamp boolean true
+.index syslog||timestamps
+If \syslog@_timestamp\ is set false, the timestamps on Exim's log lines are
+omitted when these lines are sent to syslog. See chapter ~~CHAPlog for
+details of Exim's logging.
+
+.conf system@_filter string$**$ unset
+.index filter||system filter
+.index system filter||specifying
+.index Sieve filter||not available for system filter
+This option specifies an Exim filter file that is applied to all messages at
+the start of each delivery attempt, before any routing is done. System filters
+must be Exim filters; they cannot be Sieve filters. If the system filter
+generates any deliveries to files or pipes, or any new mail messages, the
+appropriate \system@_filter@_...@_transport\ option(s) must be set, to define
+which transports are to be used. Details of this facility are given in chapter
+~~CHAPsystemfilter.
+
+.conf system@_filter@_directory@_transport string$**$ unset
+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.
+During the delivery, the variable \$address@_file$\ contains the path name.
+
+.conf system@_filter@_file@_transport string$**$ unset
+.index file||transport for system filter
+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 not ending in `/'. During
+the delivery, the variable \$address@_file$\ contains the path name.
+
+.index gid (group id)||system filter
+.conf system@_filter@_group string unset
+This option is used only when \system@_filter@_user\ is also set. It sets the
+gid under which the system filter is run, overriding any gid that is associated
+with the user. The value may be numerical or symbolic.
+
+.conf system@_filter@_pipe@_transport string$**$ unset 7
+.index \%pipe%\ transport||for system filter
+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.
+
+.conf system@_filter@_reply@_transport string$**$ unset
+.index \%autoreply%\ transport||for system filter
+This specifies the transport driver that is to be used when a \mail\ command is
+used in a system filter.
+
+.index uid (user id)||system filter
+.conf system@_filter@_user string unset
+If this option is not set, the system filter is run in the main Exim delivery
+process, as root. When the option is set, the system filter runs in a separate
+process, as the given user. Unless the string consists entirely of digits, it
+is looked up in the password data. Failure to find the named user causes a
+configuration error. The gid is either taken from the password data, or
+specified by \system@_filter@_group\. When the uid is specified numerically,
+\system@_filter@_group\ is required to be set.
+
+If the system filter generates any pipe, file, or reply deliveries, the uid
+under which the filter is run is used when transporting them, unless a
+transport option overrides.
+Normally you should set \system@_filter@_user\ if your system filter generates
+these kinds of delivery.
+
+.conf tcp@_nodelay boolean true
+.index daemon||\\TCP@_NODELAY\\ on sockets
+.index Nagle algorithm
+.index \\TCP@_NODELAY\\ on listening sockets
+If this option is set false, it stops the Exim daemon setting the
+\\TCP@_NODELAY\\ option on its listening sockets. Setting \\TCP@_NODELAY\\
+turns off the `Nagle algorithm', which is a way of improving network
+performance in interactive (character-by-character) situations. Turning it off
+should improve Exim's performance a bit, so that is what happens by default.
+However, it appears that some broken clients cannot cope, and time out. Hence
+this option. It affects only those sockets that are set up for listening by the
+daemon. Sockets created by the smtp transport for delivering mail always set
+\\TCP@_NODELAY\\.
+
+.conf timeout@_frozen@_after time 0s
+.index frozen messages||timing out
+.index timeout||frozen messages
+If \timeout@_frozen@_after\ is set to a time greater than zero, a frozen
+message of any kind that has been on the queue for longer than the given
+time is automatically cancelled at the next queue run. If it is a bounce
+message, it is just discarded; otherwise, a bounce is sent to the sender, in a
+similar manner to cancellation by the \-Mg-\ command line option. If you want
+to timeout frozen bounce messages earlier than other kinds of frozen message,
+see \ignore@_bounce@_errors@_after\.
+
+.conf timezone string unset
+.index timezone, setting
+The value of \timezone\ is used to set the environment variable \\TZ\\ while
+running Exim (if it is different on entry). This ensures that all timestamps
+created by Exim are in the required timezone. If you want all your timestamps
+to be in UTC (aka GMT) you should set
+.display asis
+timezone = UTC
+.endd
+The default value is taken from \\TIMEZONE@_DEFAULT\\ in \(Local/Makefile)\,
+or, if that is not set, from the value of the TZ environment variable when Exim
+is built. If \timezone\ is set to the empty string, either at build or run
+time, any existing \\TZ\\ variable is removed from the environment when Exim
+runs. This is appropriate behaviour for obtaining wall-clock time on some, but
+unfortunately not all, operating systems.
+
+.conf tls@_advertise@_hosts "host list$**$" unset
+.index TLS||advertising
+.index encryption||on SMTP connection
+.index SMTP||encrypted connection
+When Exim is built with support for TLS encrypted connections, the availability
+of the \\STARTTLS\\ command to set up an encrypted session is advertised in
+response to \\EHLO\\ only to those client hosts that match this option. See
+chapter ~~CHAPTLS for details of Exim's support for TLS.
+
+.conf tls@_certificate string$**$ unset
+.index TLS||server certificate, location of
+.index certificate||for server, location of
+The value of this option is expanded, and must then be the absolute path to a
+file which contains the server's certificates. The server's private key is also
+assumed to be in this file if \tls@_privatekey\ is unset. See chapter ~~CHAPTLS
+for further details.
+
+\**Note**\: The certificates defined by this option are used only when Exim is
+receiving incoming messages as a server. If you want to supply certificates for
+use when sending messages as a client, you must set the \tls@_certificate\
+option in the relevant \%smtp%\ transport.
+
+.em
+.conf tls@_crl string$**$ unset
+.index TLS||server certificate revocation list
+.index certificate||revocation list for server
+This option specifies a certificate revocation list. The expanded value must
+be the name of a file that contains a CRL in PEM format.
+.nem
+
+.conf tls@_dhparam string$**$ unset
+.index TLS||D-H parameters for server
+The value of this option is expanded, and must then be the absolute path to
+a file which contains the server's DH parameter values.
+This is used only for OpenSSL. When Exim is linked with GnuTLS, this option is
+ignored. See section ~~SECTopenvsgnu for further details.
+
+.conf tls@_privatekey string$**$ unset
+.index TLS||server private key, location of
+The value of this option is expanded, and must then be the absolute path to
+a file which contains the server's private key.
+If this option is unset, the private key is assumed to be in the same file as
+the server's certificates. See chapter ~~CHAPTLS for further details.
+
+.conf tls@_remember@_esmtp boolean false
+.index TLS||esmtp state, remembering
+.index TLS||broken clients
+If this option is set true, Exim violates the RFCs by remembering that it is in
+`esmtp' state after successfully negotiating a TLS session. This provides
+support for broken clients that fail to send a new \\EHLO\\ after starting a
+TLS session.
+
+.em
+.conf tls@_require@_ciphers string$**$ unset
+.index TLS||requiring specific ciphers
+.index cipher||requiring specific
+This option controls which ciphers can be used for incoming TLS connections.
+(The \%smtp%\ transport has an option of the same name for controlling outgoing
+connections.) This option is expanded for each connection, so can be varied for
+different clients if required. The value of this option must be a list of
+permitted cipher suites. The OpenSSL and GnuTLS libraries handle cipher control
+in somewhat different ways. Details are given in section ~~SECTreqciphsslgnu.
+.nem
+
+.conf tls@_try@_verify@_hosts "host list$**$" unset
+.index TLS||client certificate verification
+.index certificate||verification of client
+See \tls@_verify@_hosts\ below.
+
+.conf tls@_verify@_certificates string$**$ unset
+.index TLS||client certificate verification
+.index certificate||verification of client
+The value of this option is expanded, and must then be the absolute path to
+a file containing permitted certificates for clients that
+match \tls@_verify@_hosts\ or \tls@_try@_verify@_hosts\. Alternatively, if you
+are using OpenSSL, you can set \tls@_verify@_certificates\ to the name of a
+directory containing certificate files. This does not work with GnuTLS; the
+option must be set to the name of a single file if you are using GnuTLS.
+
+.conf tls@_verify@_hosts "host list$**$" unset
+.index TLS||client certificate verification
+.index certificate||verification of client
+This option, along with \tls@_try@_verify@_hosts\, controls the checking of
+certificates from clients.
+The expected certificates are defined by \tls@_verify@_certificates\, which
+must be set. A configuration error occurs if either \tls@_verify@_hosts\ or
+\tls@_try@_verify@_hosts\ is set and \tls@_verify@_certificates\ is not set.
+
+Any client that matches \tls@_verify@_hosts\ is constrained by
+\tls@_verify@_certificates\. The client must present one of the listed
+certificates. If it does not, the connection is aborted.
+
+A weaker form of checking is provided by \tls@_try@_verify@_hosts\. If a client
+matches this option (but not \tls@_verify@_hosts\), Exim requests a
+certificate and checks it against \tls@_verify@_certificates\, but does not
+abort the connection if there is no certificate or if it does not match. This
+state can be detected in an ACL, which makes it possible to implement policies
+such as `accept for relay only if a verified certificate has been received, but
+accept for local delivery if encrypted, even without a verified certificate'.
+
+Client hosts that match neither of these lists are not asked to present
+certificates.
+
+.conf trusted@_groups "string list" unset
+.index trusted group
+.index 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.
+
+.conf trusted@_users "string list" unset
+.index trusted user
+.index 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.
+
+.index uid (user id)||unknown caller
+.conf unknown@_login string$**$ unset
+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
+used in this circumstance. It is expanded, so values like \user@$caller@_uid\
+can be set. When \unknown@_login\ is used, the value of \unknown@_username\ is
+used for the user's real name (gecos field), unless this has been set by the
+\-F-\ option.
+
+.conf unknown@_username string unset
+See \unknown@_login\.
+
+.conf untrusted@_set@_sender "address list$**$" unset
+.index trusted user
+.index sender||setting by untrusted user
+.index untrusted user, setting sender
+.index user||untrusted setting sender
+.index envelope sender
+When an untrusted user submits a message to Exim using the standard input, Exim
+normally creates an envelope sender address from the user's login and the
+default qualification domain. Data from the \-f-\ option (for setting envelope
+senders on non-SMTP messages) or the SMTP \\MAIL\\ command (if \-bs-\ or \-bS-\
+is used) is ignored.
+
+However, untrusted users are permitted to set an empty envelope sender address,
+to declare that a message should never generate any bounces. For example:
+.display asis
+exim -f '<>' user@domain.example
+.endd
+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
+patterns in the list. Like all address lists, the string is expanded. The
+identity of the user is in \$sender@_ident$\, so you can, for example, restrict
+users to setting senders that start with their login ids
+followed by a hyphen
+by a setting like this:
+.display asis
+untrusted_set_sender = ^$sender_ident-
+.endd
+If you want to allow untrusted users to set envelope sender addresses without
+restriction, you can use
+.display asis
+untrusted_set_sender = *
+.endd
+The \untrusted@_set@_sender\ option applies to all forms of local input, but
+only to the setting of the envelope sender. It does not permit untrusted users
+to use the other options which trusted user can use to override message
+parameters. Furthermore, it does not stop Exim from removing an existing
+::Sender:: header in the message, or from adding a ::Sender:: header if
+necessary. See \local__sender__retain\ and \local@_from@_check\ for ways of
+overriding these actions. The handling of the ::Sender:: header is also
+described in section ~~SECTthesenhea.
+
+The log line for a message's arrival shows the envelope sender following `<='.
+For local messages, the user's login always follows, after `U='. In \-bp-\
+displays, and in the Exim monitor, if an untrusted user sets an envelope sender
+address, the user's login is shown in parentheses after the sender address.
+
+.conf uucp@_from@_pattern string "see below"
+.index `From' line
+.index UUCP||`From' line
+Some applications that pass messages to an MTA via a command line interface use
+an initial line starting with `From' to pass the envelope sender. In
+particular, this is used by UUCP software. Exim recognizes such a line by means
+of a regular expression that is set in \uucp@_from@_pattern\. When the pattern
+matches, the sender address is constructed by expanding the contents of
+\uucp@_from@_sender\, provided that the caller of Exim is a trusted user. The
+default pattern recognizes lines in the following two forms:
+.display asis
+ From ph10 Fri Jan 5 12:35 GMT 1996
+ From ph10 Fri, 7 Jan 97 14:00:00 GMT
+.endd
+The pattern can be seen by running
+.display asis
+exim -bP uucp_from_pattern
+.endd
+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
+\ignore@_fromline@_hosts\.
+
+.conf uucp@_from@_sender string$**$ "$tt{@$1}"
+See \uucp@_from@_pattern\ above.
+
+.conf warn@_message@_file string unset
+.index warning of delay||customizing the message
+.index customizing||warning message
+This option defines a template file containing paragraphs of text to be used
+for constructing the warning message which is sent by Exim when a message has
+been on the queue for a specified amount of time, as specified by
+\delay@_warning\. Details of the file's contents are given in chapter
+~~CHAPemsgcust. See also \bounce@_message@_file\.
+
+.em
+.conf write@_rejectlog boolean true
+.index reject log||disabling
+If this option is set false, Exim no longer writes anything to the reject log.
+See chapter ~~CHAPlog for details of what Exim writes to its logs.
+.nem
+
+.endconf
+
+
+
+.
+.
+.
+.
+. ============================================================================
+.chapter Generic options for routers
+.rset CHAProutergeneric "~~chapter"
+.set runningfoot "generic router options"
+.index options||generic, for routers
+.index generic options||router
+
+This chapter describes the generic options that apply to all routers,
+identifying those that are preconditions. For a general description of how a
+router operates, see sections ~~SECTrunindrou and ~~SECTrouprecon. The second
+of these sections specifies the order in which the preconditions are tested.
+The order of expansion of the options that provide data for a transport is:
+\errors@_to\, \headers@_add\, \headers@_remove\, \transport\.
+
+.startconf
+
+.conf address@_data string$**$ unset
+.index 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.
+
+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.
+
+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
+on a subsequent router. If a router generates child addresses, the value of
+\$address@_data$\ propagates to them. This also applies to the special kind of
+`child' that is generated by a router with the \unseen\ option.
+
+The idea of \address@_data\ is that you can use it to look up a lot of data for
+the address once, and then pick out parts of the data later. For example, you
+could use a single LDAP lookup to return a string of the form
+.display asis
+uid=1234 gid=5678 mailbox=/mail/xyz forward=/home/xyz/.forward
+.endd
+In the transport you could pick out the mailbox by a setting such as
+.display asis
+file = ${extract{mailbox}{$address_data}}
+.endd
+This makes the configuration file less messy, and also reduces the number of
+lookups. (Exim does cache the most recent lookup, but there may be several
+addresses in a message which cause lookups to occur.)
+
+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 an address from an ACL, its value is available for use in
+the rest of the ACL statement.
+
+
+.conf address@_test "boolean (precondition)" true
+.index \-bt-\ option
+.index router||skipping when address testing
+If this option is set false, the router is skipped when routing is being tested
+by means of the \-bt-\ command line option. This can be a convenience when your
+first router sends messages to an external scanner, because it saves you
+having to set the `already scanned' indicator when testing real address
+routing.
+
+
+.conf cannot@_route@_message string$**$ unset
+.index router||customizing `cannot route' message
+.index customizing||`cannot route' message
+This option specifies a text message that is used when an address cannot be
+routed because Exim has run out of routers. The default message is `Unrouteable
+address'. This option is useful only on routers that have \more\ set false, or
+on the very last router in a configuration, because the value that is used is
+taken from the last router that inspects an address. For example, using the
+default configuration, you could put:
+.display asis
+cannot_route_message = Remote domain not found in DNS
+.endd
+on the first (\%dnslookup%\) router, and
+.display asis
+cannot_route_message = Unknown local user
+.endd
+on the final router that checks for local users. If string expansion fails, the
+default message is used.
+Unless the expansion failure was explicitly forced, a message about the failure
+is written to the main and panic logs, in addition to the normal message about
+the routing failure.
+
+.conf caseful@_local@_part boolean false
+.index case of local parts
+.index router||case of local parts
+By default, routers handle the local parts of addresses in a case-insensitive
+manner, though the actual case is preserved for transmission with the message.
+If you want the case of letters to be significant in a router, you must set
+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.
+
+
+.conf check@_local@_user "boolean (precondition)" false
+.index local user, checking in router
+.index router||checking for local user
+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
+than trying to read \(/etc/passwd)\ directly. This means that other methods of
+holding password data (such as NIS) are supported. If the local part is a local
+user, \$home$\ is set from the password data, and can be tested in other
+preconditions that are evaluated after this one
+(the order of evaluation is given in section ~~SECTrouprecon). However, the
+value of \$home$\ can be overridden by \router@_home@_directory\.
+If the local part is not a local user, the router is skipped.
+
+If you want to check that the local part is either the name of a local user
+or matches something else, you cannot combine \check@_local@_user\ with a
+setting of \local@_parts\, because that specifies the logical \*and*\ of the
+two conditions. However, you can use a \%passwd%\ lookup in a \local@_parts\
+setting to achieve this. For example:
+.display asis
+local_parts = passwd;$local_part : lsearch;/etc/other/users
+.endd
+Note, however, that the side effects of \check@_local@_user\ (such as setting
+up a home directory) do not occur when a \%passwd%\ lookup is used in a
+\local@_parts\ (or any other) precondition.
+
+.conf condition "string$**$ (precondition)" unset
+.index router||customized precondition
+This option specifies a general precondition test that has to succeed for the
+router to be called. The string is expanded, and if the result is a forced
+failure or an empty string or one of the strings `0' or `no' or `false'
+(checked without regard to the case of the letters), the router is skipped, and
+the address is offered to the next one. This provides a means of applying
+special-purpose conditions to the running of routers.
+
+If the expansion fails (other than forced failure) delivery is deferred. Some
+of the other options below are common special cases that could in fact be
+specified using \condition\.
+Note that \condition\ is the last precondition to be evaluated (see
+section ~~SECTrouprecon).
+
+
+.conf debug@_print string$**$ unset
+.index testing||variables in drivers
+If this option is set and debugging is enabled (see the \-d-\ command line
+option), the string is expanded and included in the debugging output.
+If expansion of the string fails, the error message is written to the debugging
+output, and Exim carries on processing.
+This option is provided to help with checking out the values of variables and
+so on when debugging router configurations. For example, if a \condition\
+option appears not to be working, \debug@_print\ can be used to output the
+variables it references. The output happens after checks for \domains\,
+\local@_parts\, and \check@_local@_user\ but before any other preconditions are
+tested. A newline is added to the text if it does not end with one.
+
+
+.conf disable@_logging boolean false
+If this option is set true, nothing is logged for any routing errors
+.em
+or for any deliveries caused by this router. You should not set this option
+unless you really, really know what you are doing. See also the generic
+transport option of the same name.
+.nem
+
+.conf domains "domain list$**$ (precondition)" unset
+.index router||restricting to specific domains
+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.
+
+
+.conf driver string unset
+This option must always be set. It specifies which of the available routers is
+to be used.
+
+
+.conf errors@_to string$**$ unset
+.index envelope sender
+.index router||changing address for errors
+If a router successfully handles an address, it may queue the address for
+delivery or it may generate child addresses. In both cases, if there is a
+delivery problem during later processing, the resulting bounce message is sent
+to the address that results from expanding this string, provided that the
+address verifies successfully.
+\errors@_to\ is expanded before \headers@_add\, \headers@_remove\, and
+\transport\.
+
+If the option is unset, or the expansion is forced to fail, or the result of
+the expansion fails to verify, the errors address associated with the incoming
+address is used. At top level, this is the envelope sender. A non-forced
+expansion failure causes delivery to be deferred.
+
+If an address for which \errors@_to\ has been set ends up being delivered over
+SMTP, the envelope sender for that delivery is the \errors@_to\ value, so that
+any bounces that are generated by other MTAs on the delivery route are also
+sent there. The most common use of \errors@_to\ is probably to direct mailing
+list bounces to the manager of the list, as described in section
+~~SECTmailinglists.
+
+The \errors@_to\ setting associated with an address can be overridden if it
+subsequently passes through other routers that have their own \errors@_to\
+settings,
+or if it is delivered by a transport with a \return@_path\ setting.
+
+You can set \errors@_to\ to the empty string by either of these settings:
+.display asis
+errors_to =
+errors_to = ""
+.endd
+An expansion item that yields an empty string has the same effect. If you do
+this, a locally detected delivery error for addresses processed by this router
+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.
+
+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
+setting \return@_path\.
+
+
+.conf expn "boolean (precondition)" true
+.index address||testing
+.index testing||addresses
+.index \\EXPN\\||router skipping
+.index router||skipping for \\EXPN\\
+If this option is turned off, the router is skipped when testing an address
+as a result of processing an SMTP \\EXPN\\ command. You might, for example,
+want to turn it off on a router for users' \(.forward)\ files, while leaving it
+on for the system alias file.
+See section ~~SECTrouprecon for a list of the order in which preconditions
+are evaluated.
+
+The use of the SMTP \\EXPN\\ command is controlled by an ACL (see chapter
+~~CHAPACL). When Exim is running an \\EXPN\\ command, it is similar to testing
+an address with \-bt-\. Compare \\VRFY\\, whose counterpart is \-bv-\.
+
+
+.conf fail@_verify boolean false
+.index router||forcing verification failure
+Setting this option has the effect of setting both \fail@_verify@_sender\ and
+\fail@_verify@_recipient\ to the same value.
+
+
+.conf fail@_verify@_recipient boolean false
+If this option is true and an address is accepted by this router when
+verifying a recipient, verification fails.
+
+
+.conf fail@_verify@_sender boolean false
+If this option is true and an address is accepted by this router when
+verifying a sender, verification fails.
+
+
+.conf fallback@_hosts "string list" unset
+.index router||fallback hosts
+.index 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.
+
+.conf group string$**$ "see below"
+.index gid (group id)||local delivery
+.index local transports||uid and gid
+.index transport||local
+.index router||setting group
+When a router queues an address for a transport, and the transport does not
+specify a group, the group given here is used when running the delivery
+process.
+The group may be specified numerically or by name. If expansion fails, the
+error is logged and delivery is deferred.
+The default is unset, unless \check@_local@_user\ is set, when the default
+is taken from the password information. See also \initgroups\ and \user\ and
+the discussion in chapter ~~CHAPenvironment.
+
+
+.conf headers@_add string$**$ unset
+.index header lines||adding
+.index router||adding header lines
+This option specifies a string of text that is expanded at routing time, and
+associated with any addresses that are processed by the router
+when delivering a message. This option has no effect when an address is just
+being verified.
+
+The \headers@_add\ option is expanded after \errors@_to\, but before
+\headers@_remove\ and \transport\.
+If the expanded string is empty, or if the expansion is forced to fail, the
+option has no effect. Other expansion failures are treated as configuration
+errors. The expanded string must be in the form of one or more RFC 2822 header
+lines, separated by newlines (coded as `@\n'). For example:
+.display asis
+headers_add = X-added-header: added by $primary_hostname\n\
+ X-added-second: another added header line
+.endd
+Exim does not check the syntax of these added header lines. If an address
+passes through several routers as a result of aliasing or forwarding
+operations, any \headers@_add\ or \headers@_remove\ specifications are
+cumulative. This does not apply for multiple routers that result from the use
+of `unseen'.
+
+At transport time, all the original headers listed in \headers__remove\ are
+removed. If there are multiple instances of any listed header, they are all
+removed.
+Then the new headers specified by \headers@_add\ are added, in the order in
+which they were attached to the address. Finally, any additional headers
+specified by the transport are added. It is not possible to remove headers
+added to an address by \headers@_add\.
+
+Because the addition does not happen until transport time, header lines that
+are added by \headers@_add\ are not accessible by means of the \$header@_xxx$\
+expansion syntax. Conversely, header lines that are removed by
+\headers@_remove\ remain visible.
+
+Addresses with different \headers@_add\ or \headers@_remove\ settings cannot be
+delivered together in a batch. The \headers@_add\ option cannot be used for a
+\%redirect%\ router that has the \one@_time\ option set.
+
+
+.conf headers@_remove string$**$ unset
+.index header lines||removing
+.index router||removing header lines
+The string is expanded at routing time and is then associated with any
+addresses that are processed by the router when delivering a message. This
+option has no effect when an address is being verified. 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.
+
+.em
+After expansion, the string must consist of a colon-separated list of header
+names. This is confusing, because header names themselves are often terminated
+by colons. In this case, the colons are the list separators, not part of the
+names.
+.nem
+For example:
+.display asis
+headers_remove = return-receipt-to:acknowledge-to
+.endd
+The list is used at transport time as described under \headers@_add\ above. The
+\headers@_remove\ option cannot be used for a \%redirect%\ router that has the
+\one@_time\ option set.
+
+.conf ignore@_target@_hosts "host list$**$" unset
+.index IP address||discarding
+.index router||discarding IP addresses
+Although this option is a host list, it should normally contain IP address
+entries rather than names. If any host that is looked up by the router has an
+IP address that matches an item in this list, Exim behaves as if that IP
+address did not exist. This option allows you to cope with rogue DNS entries
+like
+.display asis
+remote.domain.example. A 127.0.0.1
+.endd
+by setting
+.display asis
+ignore_target_hosts = 127.0.0.1
+.endd
+on the relevant router.
+.em
+If all the hosts found by a \%dnslookup%\ router are discarded in this way, the
+router declines. In a conventional configuration, an attempt to mail to such a
+domain would then normally provoke the `unrouteable domain' error, and an
+attempt to verify an address in the domain would fail.
+
+Similarly, if \ignore@_target@_hosts\ is set on an \%ipliteral%\ router, the
+router declines if presented with one of the listed addresses.
+.nem
+
+This option may also be useful for ignoring link-local and site-local IPv6
+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.
+
+
+
+.index additional groups
+.index groups, additional
+.index local transports||uid and gid
+.index transport||local
+.conf initgroups boolean false
+If the router queues an address for a transport, and this option is true, and
+the uid supplied by the router is not overridden by the transport, the
+\*initgroups()*\ function is called when running the transport to ensure that
+any additional groups associated with the uid are set up. See also \group\ and
+\user\ and the discussion in chapter ~~CHAPenvironment.
+
+
+.conf local@_part@_prefix "string list (precondition)" unset
+.index router||prefix for local part
+.index 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.
+
+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.
+.index multiple mailboxes
+.index mailbox||multiple
+Wildcarding can be used to set up multiple user mailboxes, as described in
+section ~~SECTmulbox.
+
+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
+relevant transport.
+
+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
+tell a user their forwarding is broken -- by placing a router like this one
+immediately before the router that handles \(.forward)\ files:
+.display asis
+real_localuser:
+ driver = accept
+ local_part_prefix = real-
+ check_local_user
+ transport = local_delivery
+.endd
+If both \local@_part@_prefix\ and \local@_part@_suffix\ are set for a router,
+both conditions must be met if not optional. Care must be taken if wildcards
+are used in both a prefix and a suffix on the same router. Different
+separator characters must be used to avoid ambiguity.
+
+.conf local@_part@_prefix@_optional boolean false
+See \local@_part@_prefix\ above.
+
+
+.conf local@_part@_suffix "string list (precondition)" unset
+.index router||suffix for local part
+.index suffix for local part, used in router
+This option operates in the same way as \local@_part@_prefix\, except that the
+local part must end (rather than start) with the given string, the
+\local@_part@_suffix@_optional\ option determines whether the suffix is
+mandatory, and the wildcard $*$ character, if present, must be the last
+character of the suffix. This option facility is commonly used to handle local
+parts of the form \something-request\ and multiple user mailboxes of the form
+\username-foo\.
+
+.conf local@_part@_suffix@_optional boolean false
+See \local@_part@_suffix\ above.
+
+
+.conf local@_parts "local part list$**$ (precondition)" unset
+.index router||restricting to specific local parts
+.index local part||checking in router
+The router is run only if the local part of the address matches the list.
+See section ~~SECTrouprecon for a list of the order in which preconditions
+are evaluated, and
+section ~~SECTlocparlis for a discussion of local part lists. Because the
+string is expanded, it is possible to make it depend on the domain, for
+example:
+.display asis
+local_parts = dbm;/usr/local/specials/$domain
+.endd
+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
+example, if you have a large number of local virtual domains, and you want to
+send all postmaster mail to the same place without having to set up an alias in
+each virtual domain:
+.display asis
+postmaster:
+ driver = redirect
+ local_parts = postmaster
+ data = postmaster@real.domain.example
+.endd
+
+
+.conf log@_as@_local boolean "see below"
+.index log||delivery line
+.index delivery||log line format
+Exim has two logging styles for delivery, the idea being to make local
+deliveries stand out more visibly from remote ones. In the `local' style, the
+recipient address is given just as the local part, without a domain. The use of
+this style is controlled by this option. It defaults to true for the \%accept%\
+router, and false for all the others.
+
+
+.conf more boolean$**$ true
+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 (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.
+.index \self\ option
+However, if the router explicitly passes an address to the following router by
+means of the setting
+.display asis
+self = pass
+.endd
+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.
+
+
+.conf pass@_on@_timeout boolean false
+.index timeout||of router
+.index router||timeout
+If a router times out during a host lookup, it normally causes deferral of the
+address. If \pass@_on@_timeout\ is set, the address is passed on to the next
+router, overriding \no@_more\. This may be helpful for systems that are
+intermittently connected to the Internet, or those that want to pass to a smart
+host any messages that cannot immediately be delivered.
+
+There are occasional other temporary errors that can occur while doing DNS
+lookups. They are treated in the same way as a timeout, and this option
+applies to all of them.
+
+
+.conf pass@_router string unset
+.index router||go to after `pass'
+When a router returns `pass', the address is normally handed on to the next
+router in sequence. This can be changed by setting \pass@_router\ to the name
+of another router. However (unlike \redirect@_router\) the named router must be
+below the current router, to avoid loops. Note that this option applies only to
+the special case of `pass'. It does not apply when a router returns `decline'.
+
+
+.conf redirect@_router string unset
+.index router||start at after redirection
+Sometimes an administrator knows that it is pointless to reprocess addresses
+generated from alias or forward files with the same router again. For
+example, if an alias file translates real names into login ids there is no
+point searching the alias file a second time, especially if it is a large file.
+
+The \redirect@_router\ option can be set to the name of any router instance. It
+causes the routing of any generated addresses to start at the named router
+instead of at the first router. This option has no effect if the router in
+which it is set does not generate new addresses.
+
+
+.conf require@_files "string list$**$ (precondition)" unset
+.index file||requiring for router
+.index router||requiring file existence
+This option provides a general mechanism for predicating the running of a
+router on the existence or non-existence of certain files or directories.
+Before running a router, as one of its precondition tests, Exim works its way
+through the \require@_files\ list, expanding each item separately.
+
+Because the list is split before expansion, any colons in expansion items must
+be doubled, or the facility for using a different list separator must be used.
+If any expansion is forced to fail, the item is ignored. Other expansion
+failures cause routing of the address to be deferred.
+
+If any expanded string is empty, it is ignored. Otherwise, except as described
+below, each string must be a fully qualified file path, optionally preceded by
+`!'. The paths are passed to the \*stat()*\ function to test for the existence
+of the files or directories. The router is skipped if any paths not preceded by
+`!' do not exist, or if any paths preceded by `!' do exist.
+
+.index NFS
+If \*stat()*\ cannot determine whether a file exists or not, delivery of
+the message is deferred. This can happen when NFS-mounted filesystems are
+unavailable.
+
+This option is checked after the \domains\, \local@_parts\, and \senders\
+options, so you cannot use it to check for the existence of a file in which to
+look up a domain, local part, or sender. (See section ~~SECTrouprecon for a
+full list of the order in which preconditions are evaluated.) However, as
+these options are all expanded, you can use the \exists\ expansion condition to
+make such tests. The \require@_files\ option is intended for checking files
+that the router may be going to use internally, or which are needed by a
+transport (for example \(.procmailrc)\).
+
+During delivery, the \*stat()*\ function is run as root, but there is a
+facility for some checking of the accessibility of a file by another user.
+This is not a proper permissions check, but just a `rough' check that
+operates as follows:
+
+If an item in a \require@_files\ list does not contain any forward slash
+characters, it is taken to be the user (and optional group, separated by a
+comma) to be checked for subsequent files in the list. If no group is specified
+but the user is specified symbolically, the gid associated with the uid is
+used. For example:
+.display asis
+require_files = mail:/some/file
+require_files = $local_part:$home/.procmailrc
+.endd
+If a user or group name in a \require@_files\ list does not exist, the
+\require@_files\ condition fails.
+
+Exim performs the check by scanning along the components of the file path, and
+checking the access for the given uid and gid. It checks for `x' access on
+directories, and `r' access on the final file. Note that this means that file
+access control lists, if the operating system has them, are ignored.
+
+\**Warning 1**\: When the router is being run to verify addresses for an
+incoming SMTP message, Exim is not running as root, but under its own uid. This
+may affect the result of a \require@_files\ check. In particular, \*stat()*\
+may yield the error \\EACCES\\ (`Permission denied'). This means that the Exim
+user is not permitted to read one of the directories on the file's path.
+
+\**Warning 2**\: Even when Exim is running as root while delivering a message,
+\*stat()*\ can yield \\EACCES\\ for a file on an NFS directory that is mounted
+without root access.
+
+In both cases,
+the default action is to consider this a configuration error, and routing is
+deferred because the existence or non-existence of the file cannot be
+determined. However, in some circumstances it may be desirable to treat this
+condition as if the file did not exist. If the file name (or the exclamation
+mark that precedes the file name for non-existence) is preceded by a plus sign,
+the \\EACCES\\ error is treated as if the file did not exist. For example:
+.display asis
+require_files = +/some/file
+.endd
+If the router is not an essential part of verification (for example, it
+handles users' \(.forward)\ files), another solution is to set the \verify\
+option false so that the router is skipped when verifying.
+
+
+.conf retry@_use@_local@_part boolean "see below"
+.index hints database||retry keys
+.index local part||in retry keys
+When a delivery suffers a temporary routing failure, a retry record is created
+in Exim's hints database. For addresses whose routing depends only on the
+domain, the key for the retry record should not involve the local part, but for
+other addresses, both the domain and the local part should be included.
+Usually, remote routing is of the former kind, and local routing is of the
+latter kind.
+
+This option controls whether the local part is used to form the key for retry
+hints for addresses that suffer temporary errors while being handled by this
+router. The default value is true for any router that has \check@_local@_user\
+set, and false otherwise. Note that this option does not apply to hints keys
+for transport delays; they are controlled by a generic transport option of the
+same name.
+
+.em
+The setting of \retry@_use@_local@_part\ applies only to the router on which it
+appears. If the router generates child addresses, they are routed
+independently; this setting does not become attached to them.
+.nem
+
+
+.conf router@_home@_directory string$**$ unset
+.index router||home directory for
+.index home directory||for router
+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
+sets a value for \$home$\ while a filter is running. The value is expanded;
+forced expansion failure causes the option to be ignored -- other failures
+cause the router to defer.
+
+Expansion of \router@_home@_directory\ happens immediately after the
+\check@_local@_user\ test (if configured), before any further expansions take
+place.
+(See section ~~SECTrouprecon for a list of the order in which preconditions
+are evaluated.)
+While the router is running, \router__home@_directory\ overrides the value of
+\$home$\ that came from \check@_local@_user\.
+
+When a router accepts an address and routes it to a transport (including the
+cases when a redirect router generates a pipe, file, or autoreply delivery),
+the home directory setting for the transport is taken from the first of these
+values that is set:
+.numberpars $.
+The \home@_directory\ option on the transport;
+.nextp
+The \transport@_home@_directory\ option on the router;
+.nextp
+The password data if \check@_local@_user\ is set on the router;
+.nextp
+The \router@_home@_directory\ option on the router.
+.endp
+In other words, \router@_home@_directory\ overrides the password data for the
+router, but not for the transport.
+
+
+.conf self string "freeze"
+.index MX record||pointing to local host
+.index local host||MX pointing to
+This option applies to those routers that use a recipient address to find a
+list of remote hosts. Currently, these are the \%dnslookup%\, \%ipliteral%\,
+and \%manualroute%\ routers.
+Certain configurations of the \%queryprogram%\ router can also specify a list
+of remote hosts.
+Usually such routers are configured to send the message to a remote host via an
+\%smtp%\ transport. The \self\ option specifies what happens when the first
+host on the list turns out to be the local host.
+The way in which Exim checks for the local host is described in section
+~~SECTreclocipadd.
+
+Normally this situation indicates either an error in Exim's configuration (for
+example, the router should be configured not to process this domain), or an
+error in the DNS (for example, the MX should not point to this host). For this
+reason, the default action is to log the incident, defer the address, and
+freeze the message. The following alternatives are provided for use in special
+cases:
+.numberpars $.
+\defer\
+.newline
+Delivery of the message is tried again later, but the message is not frozen.
+.nextp
+\reroute: <<domain>>\
+.newline
+The domain is changed to the given domain, and the address is passed back to
+be reprocessed by the routers. No rewriting of headers takes place. This
+behaviour is essentially a redirection.
+.nextp
+\reroute: rewrite: <<domain>>\
+.newline
+The domain is changed to the given domain, and the address is passed back to be
+reprocessed by the routers. Any headers that contain the original domain are
+rewritten.
+.nextp
+\pass\
+.newline
+The router passes the address to the next router, or to the router named in the
+\pass@_router\ option if it is set.
+.index \more\ option
+This overrides \no@_more\.
+
+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 combination
+.display asis
+self = pass
+no_more
+.endd
+ensures that only those addresses that routed to the local host are passed on.
+Without \no@_more\, addresses that were declined for other reasons would also
+be passed to the next router.
+.nextp
+\fail\
+.newline
+Delivery fails and an error report is generated.
+.nextp
+\send\
+.newline
+.index local host||sending to
+The anomaly is ignored and the address is queued for the transport. This
+setting should be used with extreme caution. For an \%smtp%\ transport, it makes
+sense only in cases where the program that is listening on the SMTP port is not
+this version of Exim. That is, it must be some other MTA, or Exim with a
+different configuration file that handles the domain in another way.
+.endp
+
+.conf senders "address list$**$ (precondition)" unset
+.index router||checking senders
+If this option is set, the router is skipped unless the message's sender
+address matches something on the list.
+See section ~~SECTrouprecon for a list of the order in which preconditions
+are evaluated.
+
+There are issues concerning verification when the running of routers is
+dependent on the sender. When Exim is verifying the address in an \errors@_to\
+setting, it sets the sender to the null string. When using the \-bt-\ option to
+check a configuration file, it is necessary also to use the \-f-\ option to set
+an appropriate sender. For incoming mail, the sender is unset when verifying
+the sender, but is available when verifying any recipients. If the SMTP
+\\VRFY\\ command is enabled, it must be used after \\MAIL\\ if the sender
+address matters.
+
+.conf translate@_ip@_address string$**$ unset
+.index IP address||translating
+.index packet radio
+.index router||IP address translation
+There exist some rare networking situations (for example, packet radio) where
+it is helpful to be able to translate IP addresses generated by normal routing
+mechanisms into other IP addresses, thus performing a kind of manual IP
+routing. This should be done only if the normal IP routing of the TCP/IP stack
+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)\.
+
+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.
+For any other expansion error, delivery of the message is deferred.
+If the result of the expansion is an IP address, that replaces the original
+address; otherwise the result is assumed to be a host name -- this is looked up
+using \*gethostbyname()*\ (or \*getipnodebyname()*\ when available) to produce
+one or more replacement IP addresses. For example, to subvert all IP addresses
+in some specific networks, this could be added to a router:
+.display
+$smc{translate@_ip@_address = @\
+ @$@{lookup@{@$@{mask:@$host@_address/26@}@}lsearch@{/some/file@}@{@$value@}fail@}}
+.endd
+The file would contain lines like
+.display asis
+10.2.3.128/26 some.host
+10.8.4.34/26 10.44.8.15
+.endd
+You should not make use of this facility unless you really understand what you
+are doing.
+
+
+.conf transport string$**$ unset
+This option specifies the transport to be used when a router accepts an address
+and sets it up for delivery. A transport is never needed if a router is used
+only for verification. The value of the option is expanded at routing time,
+after the expansion of \errors@_to\,
+\headers@_add\, and \headers@_remove\,
+and result must be the name of one of the configured transports. If it is
+not, delivery is deferred.
+
+The \transport\ option is not used by the \%redirect%\ router, but it does have
+some private options that set up transports for pipe and file deliveries (see
+chapter ~~CHAPredirect).
+
+
+.conf transport@_current@_directory string$**$ unset
+.index current directory for local transport
+This option associates a current directory with any address that is routed
+to a local transport. This can happen either because a transport is
+explicitly configured for the router, or because it generates a delivery to a
+file or a pipe. During the delivery process (that is, at transport time), this
+option string is expanded and is set as the current directory, unless
+overridden by a setting on the transport.
+If the expansion fails for any reason, including forced failure, an error is
+logged, and delivery is deferred.
+See chapter ~~CHAPenvironment for details of the local delivery environment.
+
+
+
+.conf transport@_home@_directory string$**$ "see below"
+.index home directory||for local transport
+This option associates a home directory with any address that is routed to a
+local transport. This can happen either because a transport is explicitly
+configured for the router, or because it generates a delivery to a file or a
+pipe. During the delivery process (that is, at transport time), the option
+string is expanded and is set as the home directory, unless overridden by a
+setting of \home@_directory\ on the transport.
+If the expansion fails for any reason, including forced failure, an error is
+logged, and delivery is deferred.
+
+If the transport does not specify a home directory, and
+\transport@_home@_directory\ is not set for the router, the home directory for
+the tranport is taken from the password data if \check@_local@_user\ is set for
+the router. Otherwise it is taken from \router@_home@_directory\ if that option
+is set; if not, no home directory is set for the transport.
+
+See chapter ~~CHAPenvironment for further details of the local delivery
+environment.
+
+
+
+.conf unseen boolean$**$ false
+.index 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.
+
+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\
+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).
+
+The \unseen\ option can be used to cause
+.index copy of message (\unseen\ option)
+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.
+
+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.
+
+
+.conf user string$**$ "see below"
+.index uid (user id)||local delivery
+.index local transports||uid and gid
+.index transport||local
+.index router||user for filter processing
+.index filter||user for processing
+When a router queues an address for a transport, and the transport does not
+specify a user, the user given here is used when running the delivery process.
+The user may be specified numerically or by name. If expansion fails, the
+error is logged and delivery is deferred.
+This user is also used by the \%redirect%\ router when running a filter file.
+The default is unset, except when \check@_local@_user\ is set. In this case,
+the default is taken from the password information. If the user is specified as
+a name, and \group\ is not set, the group associated with the user is used. See
+also \initgroups\ and \group\ and the discussion in chapter ~~CHAPenvironment.
+
+
+.conf verify "boolean (precondition)" true
+Setting this option has the effect of setting \verify@_sender\ and
+\verify@_recipient\ to the same value.
+
+.conf verify@_only "boolean (precondition)" false
+.index \\EXPN\\||with \verify@_only\
+.index \-bv-\ option
+.index router||used only when verifying
+If this option is set, the router is used only when verifying an address or
+testing with the \-bv-\ option, not when actually doing a delivery, testing
+with the \-bt-\ option, or running the SMTP \\EXPN\\ command. It can be further
+restricted to verifying only senders or recipients by means of \verify@_sender\
+and \verify@_recipient\.
+
+\**Warning**\: When the router is being run to verify addresses for an incoming
+SMTP message, Exim is not running as root, but under its own uid. If the router
+accesses any files, you need to make sure that they are accessible to the Exim
+user or group.
+
+.conf verify@_recipient "boolean (precondition)" true
+If this option is false, the router is skipped when verifying recipient
+addresses
+or testing recipient verification using \-bv-\.
+See section ~~SECTrouprecon for a list of the order in which preconditions
+are evaluated.
+
+.conf verify@_sender "boolean (precondition)" true
+If this option is false, the router is skipped when verifying sender addresses
+or testing sender verification using \-bvs-\.
+See section ~~SECTrouprecon for a list of the order in which preconditions
+are evaluated.
+
+.endconf
+
+
+
+
+
+.
+.
+.
+.
+. ============================================================================
+.chapter The accept router
+.set runningfoot "accept router"
+.index \%accept%\ router
+.index routers||\%accept%\
+The \%accept%\ router has no private options of its own. Unless it is being used
+purely for verification (see \verify@_only\) a transport is required to be
+defined by the generic \transport\ option. If the preconditions that are
+specified by generic options are met, the router accepts the address and queues
+it for the given transport. The most common use of this router is for setting
+up deliveries to local mailboxes. For example:
+.display asis
+localusers:
+ driver = accept
+ domains = mydomain.example
+ check_local_user
+ transport = local_delivery
+.endd
+The \domains\ condition in this example checks the domain of the address, and
+\check@_local@_user\ checks that the local part is the login of a local user.
+When both preconditions are met, the \%accept%\ router runs, and queues the
+address for the \%local@_delivery%\ transport.
+
+
+
+
+
+
+.
+.
+.
+.
+. ============================================================================
+.chapter The dnslookup router
+.rset CHAPdnslookup "~~chapter"
+.set runningfoot "dnslookup router"
+.index \%dnslookup%\ router
+.index routers||\%dnslookup%\
+The \%dnslookup%\ router looks up the hosts that handle mail for the given
+domain in the DNS. A transport must always be set for this router, unless
+\verify@_only\ is set.
+
+.em
+If SRV support is configured (see \check@_srv\ below), Exim first searches for
+SRV records. If none are found, or if SRV support is not configured,
+MX records are looked up. If no MX records exist, address records are sought.
+However, \mx@_domains\ can be set to disable the direct use of address records.
+
+MX records of equal priority are sorted by Exim into a random order. Exim then
+looks for address records for the host names obtained from MX or SRV records.
+When a host has more than one IP address, they are sorted into a random order,
+except that IPv6 addresses are always sorted before IPv4 addresses. If all the
+IP addresses found are discarded by a setting of the \ignore@_target@_hosts\
+generic option, the router declines.
+
+Unless they have the highest priority (lowest MX value), MX records that point
+to the local host, or to any host name that matches \hosts__treat__as__local\,
+are discarded, together with any other MX records of equal or lower priority.
+.nem
+
+.index MX record||pointing to local host
+.index local host||MX pointing to
+.index \self\ option||in \%dnslookup%\ router
+If the host pointed to by the highest priority MX record, or looked up as an
+address record, is the local host, or matches \hosts__treat__as__local\, what
+happens is controlled by the generic \self\ option.
+
+There are a number of private options that can be used to vary the way the DNS
+lookup is handled.
+
+
+.startconf
+.index options||\%dnslookup%\ router
+.conf check@_secondary@_mx boolean false
+.index MX record||checking for secondary
+If this option is set, the router declines unless the local host is found in
+(and removed from) the list of hosts obtained by MX lookup. This can be used to
+process domains for which the local host is a secondary mail exchanger
+differently to other domains. The way in which Exim decides whether a host is
+the local host is described in section ~~SECTreclocipadd.
+
+.em
+.conf check@_srv string$**$ unset
+.index SRV record||enabling use of
+The dnslookup router supports the use of SRV records (see RFC 2782) in
+addition to MX and address records. The support is disabled by default. To
+enable SRV support, set the \check@_srv\ option to the name of the service
+required. For example,
+.display asis
+check_srv = smtp
+.endd
+looks for SRV records that refer to the normal smtp service. The option is
+expanded, so the service name can vary from message to message or address
+to address. This might be helpful if SRV records are being used for a
+submission service. If the expansion is forced to fail, the \check@_srv\
+option is ignored, and the router proceeds to look for MX records in the
+normal way.
+
+When the expansion succeeds, the router searches first for SRV records for
+the given service (it assumes TCP protocol). A single SRV record with the
+host name \"."\ indicates `no such service for this domain'; if this is
+encountered, the router declines. If other kinds of SRV record are found,
+they are used to construct a host list for delivery according to the rules
+of RFC 2782. MX records are not sought in this case.
+
+However, when no SRV records are found, MX records (and address records)
+are sought in the traditional way. In other words, SRV records take
+precedence over MX records, just as MX records take precedence over address
+records. Note that this behaviour is not sanctioned by RFC 2782, though a
+previous draft RFC defined it. It is apparently believed that MX records
+are sufficient for email and that SRV records should not be used for this
+purpose. However, SRV records have an additional `weight' feature which
+some people might find useful when trying to split an SMTP load between
+hosts of different power.
+.nem
+
+.conf mx@_domains "domain list$**$" unset
+.index MX record||required to exist
+.index SRV record||required to exist
+.em
+A domain that matches \mx@_domains\ is required to have either an MX or an SRV
+record in order to be recognised. (The name of this option could be improved.)
+.nem
+For example, if all the mail hosts in \*fict.example*\ are known to have MX
+records, except for those in \*discworld.fict.example*\, you could use this
+setting:
+.display asis
+mx_domains = ! *.discworld.fict.example : *.fict.example
+.endd
+This specifies that messages addressed to a domain that matches the list but
+has no MX record should be bounced immediately instead of being routed using
+the address record.
+
+.conf qualify@_single boolean true
+.index DNS||resolver options
+.index DNS||qualifying single-component names
+When this option is true, the resolver option \\RES@_DEFNAMES\\ is set for DNS
+lookups. Typically, but not standardly, this causes the resolver to qualify
+single-component names with the default domain. For example, on a machine
+called \*dictionary.ref.example*\, the domain \*thesaurus*\ would be changed to
+\*thesaurus.ref.example*\ inside the resolver. For details of what your resolver
+actually does, consult your man pages for \*resolver*\ and \*resolv.conf*\.
+
+
+.conf rewrite@_headers boolean true
+.index rewriting||header lines
+.index header lines||rewriting
+If the domain name in the address that is being processed is not fully
+qualified, it may be expanded to its full form by a DNS lookup. For example, if
+an address is specified as \*dormouse@@teaparty*\, the domain might be
+expanded to \*teaparty.wonderland.fict.example*\. Domain expansion can also
+occur as a result of setting the \widen@_domains\ option. If \rewrite@_headers\
+is true, all occurrences of the abbreviated domain name in any ::Bcc::, ::Cc::,
+::From::, ::Reply-to::, ::Sender::, and ::To:: header lines of the message are
+rewritten with the full domain name.
+
+This option should be turned off only when it is known that no message is
+ever going to be sent outside an environment where the abbreviation makes
+sense.
+
+When an MX record is looked up in the DNS and matches a wildcard record, name
+servers normally return a record containing the name that has been looked up,
+making it impossible to detect whether a wildcard was present or not. However,
+some name servers have recently been seen to return the wildcard entry. If the
+name returned by a DNS lookup begins with an asterisk, it is not used for
+header rewriting.
+
+.conf same@_domain@_copy@_routing boolean false
+.index address||copying routing
+Addresses with the same domain are normally routed by the \%dnslookup%\ router
+to the same list of hosts. However, this cannot be presumed, because the router
+options and preconditions may refer to the local part of the address. By
+default, therefore, Exim routes each address in a message independently. DNS
+servers run caches, so repeated DNS lookups are not normally expensive, and in
+any case, personal messages rarely have more than a few recipients.
+
+If you are running mailing lists with large numbers of subscribers at the same
+domain, and you are using a \%dnslookup%\ router which is independent of the
+local part, you can set \same__domain__copy@_routing\ to bypass repeated DNS
+lookups for identical domains in one message. In this case, when \%dnslookup%\
+routes an address to a remote transport, any other unrouted addresses in the
+message that have the same domain are automatically given the same routing
+without processing them independently,
+provided the following conditions are met:
+.numberpars $.
+No router that processed the address specified \headers@_add\ or
+\headers@_remove\.
+.nextp
+The router did not change the address in any way, for example, by `widening'
+the domain.
+.endp
+
+
+.conf search@_parents boolean false
+.index DNS||resolver options
+When this option is true, the resolver option \\RES@_DNSRCH\\ is set for DNS
+lookups. This is different from the \qualify@_single\ option in that it applies
+to domains containing dots. Typically, but not standardly, it causes the
+resolver to search for the name in the current domain and in parent domains.
+For example, on a machine in the \*fict.example*\ domain, if looking up
+\*teaparty.wonderland*\ failed, the resolver would try
+\*teaparty.wonderland.fict.example*\. For details of what your resolver
+actually does, consult your man pages for \*resolver*\ and \*resolv.conf*\.
+
+Setting this option true can cause problems in domains that have a wildcard MX
+record, because any domain that does not have its own MX record matches the
+local wildcard.
+
+.conf widen@_domains "string list" unset
+.index domain||partial, widening
+If a DNS lookup fails and this option is set, each of its strings in turn is
+added onto the end of the domain, and the lookup is tried again. For example,
+if
+.display asis
+widen_domains = fict.example:ref.example
+.endd
+is set and a lookup of \*klingon.dictionary*\ fails,
+\*klingon.dictionary.fict.example*\ is looked up, and if this fails,
+\*klingon.dictionary.ref.example*\ is tried. Note that the \qualify@_single\
+and \search@_parents\ options can cause some widening to be undertaken inside
+the DNS resolver.
+
+.endconf
+
+.em
+.section Effect of qualify@_single and search@_parents
+When a domain from an envelope recipient is changed by the resolver as a result
+of the \qualify@_single\ or \search@_parents\ options, Exim rewrites the
+corresponding address in the message's header lines unless \rewrite@_headers\
+is set false. Exim then re-routes the address, using the full domain.
+
+These two options affect only the DNS lookup that takes place inside the router
+for the domain of the address that is being routed. They do not affect lookups
+such as that implied by
+.display asis
+domains = @mx_any
+.endd
+that may happen while processing a router precondition before the router is
+entered. No widening ever takes place for these lookups.
+.nem
+
+
+
+
+
+
+
+
+
+.
+.
+.
+.
+. ============================================================================
+.chapter The ipliteral router
+.set runningfoot "ipliteral router"
+.index \%ipliteral%\ router
+.index domain literal||routing
+.index routers||\%ipliteral%\
+This router has no private options. Unless it is being used purely for
+verification (see \verify@_only\) a transport is required to be defined by the
+generic \transport\ option. The router accepts the address if its domain part
+takes the form of an RFC 2822 domain literal, that is, an IP address enclosed
+in square brackets. For example, this router handles the address
+.display asis
+root@[192.168.1.1]
+.endd
+by setting up delivery to the host with that IP address.
+
+.em
+If the IP address matches something in \ignore@_target@_hosts\, the router
+declines.
+.nem
+.index \self\ option||in \%ipliteral%\ router
+If an IP literal turns out to refer to the local host, the generic \self\
+option determines what happens.
+
+The RFCs require support for domain literals; however, their use is
+controversial in today's Internet. If you want to use this router, you must
+also set the main configuration option \allow@_domain@_literals\. Otherwise,
+Exim will not recognize the domain literal syntax in addresses.
+
+
+
+.
+.
+.
+.
+. ============================================================================
+.chapter The iplookup router
+.set runningfoot "iplookup router"
+.index \%iplookup%\ router
+.index routers||\%iplookup%\
+The \%iplookup%\ router was written to fulfil a specific requirement in
+Cambridge University. For this reason, it is not included in the binary of Exim
+by default. If you want to include it, you must set
+.display asis
+ROUTER_IPLOOKUP=yes
+.endd
+in your \(Local/Makefile)\ configuration file.
+
+The \%iplookup%\ router routes an address by sending it over a TCP or UDP
+connection to one or more specific hosts. The host can then return the same or
+a different address -- in effect rewriting the recipient address in the
+message's envelope. The new address is then passed on to subsequent routers.
+
+
+If this process fails, the address can be passed on to
+other routers, or delivery can be deferred.
+
+Background, for those that are interested: We have an Oracle database of all
+Cambridge users, and one of the items of data it maintains for each user is
+where to send mail addressed to \*user@@cam.ac.uk*\. The MX records for
+\*cam.ac.uk*\ point to a central machine that has a large alias list that is
+abstracted from the database. Mail from outside is switched by this system, and
+originally internal mail was also done this way. However, this resulted in a
+fair number of messages travelling from some of our larger systems to the
+switch and back again. The Oracle machine now runs a UDP service that can be
+called by the \%iplookup%\ router in Exim to find out where \*user@@cam.ac.uk*\
+addresses really have to go; this saves passing through the central switch, and
+in many cases saves doing any remote delivery at all.
+
+Since \%iplookup%\ is just a rewriting router, a transport must not be
+specified for it.
+
+.startconf
+.index options||\%iplookup%\ router
+
+.conf hosts string unset
+This option must be supplied. Its value is a colon-separated list of host
+names. The hosts are looked up using \*gethostbyname()*\
+(or \*getipnodebyname()*\ when available)
+and are tried in order until one responds to the query. If none respond, what
+happens is controlled by \optional\.
+
+.conf optional boolean false
+If \optional\ is true, if no response is obtained from any host, the address is
+passed to the next router, overriding \no@_more\. If \optional\ is false,
+delivery to the address is deferred.
+
+.conf port integer 0
+.index port||\%iplookup%\ router
+This option must be supplied. It specifies the port number for the TCP or UDP
+call.
+
+.conf protocol string "udp"
+This option can be set to `udp' or `tcp' to specify which of the two protocols
+is to be used.
+
+.conf query string$**$ "$tt{@$local@_part@@@$domain @$local@_part@@@$domain}"
+This defines the content of the query that is sent to the remote hosts. The
+repetition serves as a way of checking that a response is to the correct query
+in the default case (see \response@_pattern\ below).
+
+.conf reroute string$**$ unset
+If this option is not set, the rerouted address is precisely the byte string
+returned by the remote host, up to the first white space, if any. If set, the
+string is expanded to form the rerouted address. It can include parts matched
+in the response by \response@_pattern\ by means of numeric variables such as
+\$1$\, \$2$\, etc. The variable \$0$\ refers to the entire input string,
+whether or not a pattern is in use. In all cases, the rerouted address must end
+up in the form \*local@_part@@domain*\.
+
+.conf response@_pattern string unset
+This option can be set to a regular expression that is applied to the string
+returned from the remote host. If the pattern does not match the response, the
+router declines. If \response@_pattern\ is not set, no checking of the response
+is done, unless the query was defaulted, in which case there is a check that
+the text returned after the first white space is the original address. This
+checks that the answer that has been received is in response to the correct
+question. For example, if the response is just a new domain, the following
+could be used:
+.display asis
+response_pattern = ^([^@]+)$
+reroute = $local_part@$1
+.endd
+
+.conf timeout time 5s
+This specifies the amount of time to wait for a response from the remote
+machine. The same timeout is used for the \*connect()*\ function for a TCP
+call. It does not apply to UDP.
+
+.endconf
+
+
+
+
+.
+.
+.
+.
+. ============================================================================
+.chapter The manualroute router
+.set runningfoot "manualroute router"
+.index \%manualroute%\ router
+.index routers||\%manualroute%\
+.index domain||manually routing
+The \%manualroute%\ router is so-called because it provides a way of manually
+routing an address according to its domain. It is mainly used when you want to
+route addresses to remote hosts according to your own rules, bypassing the
+normal DNS routing that looks up MX records. However, \%manualroute%\ can also
+route to local transports, a facility that may be useful if you want to save
+messages for dial-in hosts in local files.
+
+The \%manualroute%\ router compares a list of domain patterns with the domain it
+is trying to route. If there is no match, the router declines. Each pattern has
+associated with it a list of hosts and some other optional data, which may
+include a transport. The combination of a pattern and its data is called a
+`routing rule'. For patterns that do not have an associated transport, the
+generic \transport\ option must specify a transport, unless the router is being
+used purely for verification (see \verify@_only\).
+
+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
+transport. If the transport is not a local one, a host list must be associated
+with the pattern; IP addresses are looked up for the hosts, and these are
+passed to the transport along with the mail address. For local transports, a
+host list is optional. If it is present, it is passed in \$host$\ as a single
+text string.
+
+The list of routing rules can be provided as an inline string in \route@_list\,
+or the data can be obtained by looking up the domain in a file or database by
+setting \route@_data\. Only one of these settings may appear in any one
+instance of \%manualroute%\. The format of routing rules is described below,
+following the list of private options.
+
+.section Private options for manualroute
+.rset SECTprioptman "~~chapter.~~section"
+
+The private options for the \%manualroute%\ router are as follows:
+
+.startconf
+.index options||\%manualroute%\ router
+
+.conf host@_find@_failed string "freeze"
+This option controls what happens when \%manualroute%\ tries to find an IP
+address for a host, and the host does not exist. The option can be set to one
+of
+.display asis
+decline
+defer
+fail
+freeze
+pass
+.endd
+The default assumes that this state is a serious configuration error. The
+difference between `pass' and `decline' is that the former forces the address
+to be passed to the next router (or the router defined by \pass@_router\),
+.index \more\ option
+overriding \no@_more\, whereas the latter passes the address to the next router
+only if \more\ is true.
+
+This option applies only to a definite `does not exist' state; if a host lookup
+gets a temporary error, delivery is deferred unless the generic
+\pass@_on@_timeout\ option is set.
+
+.conf hosts@_randomize boolean false
+.index randomized host list
+.index host||list of, randomized
+If this option is set, the order of the items in a host list in a routing rule
+is randomized each time the list is used, unless an option in the routing rule
+overrides (see below). Randomizing the order of a host list can be used to do
+crude load sharing. However, if more than one mail address is routed by the
+same router to the same host list, the host lists are considered to be the same
+(even though they may be randomized into different orders) for the purpose of
+deciding whether to batch the deliveries into a single SMTP transaction.
+
+When \hosts@_randomize\ is true, a host list may be split
+into groups whose order is separately randomized. This makes it possible to
+set up MX-like behaviour. The boundaries between groups are indicated by an
+item that is just \"+"\ in the host list. For example:
+.display asis
+route_list = * host1:host2:host3:+:host4:host5
+.endd
+The order of the first three hosts and the order of the last two hosts is
+randomized for each use, but the first three always end up before the last two.
+If \hosts@_randomize\ is not set, a \"+"\ item in the list is ignored. If a
+randomized host list is passed to an \%smtp%\ transport that also has
+\hosts@_randomize set\, the list is not re-randomized.
+
+.conf route@_data string$**$ unset
+If this option is set, it must expand to yield the data part of a routing rule.
+Typically, the expansion string includes a lookup based on the domain. For
+example:
+.display asis
+route_data = ${lookup{$domain}dbm{/etc/routes}}
+.endd
+If the expansion is forced to fail, or the result is an empty string, the
+router declines. Other kinds of expansion failure cause delivery to be
+deferred.
+
+.conf route@_list "string list, semicolon-separated" unset
+This string is a list of routing rules, in the form defined below. Note that,
+unlike most string lists, the items are separated by semicolons. This is so
+that they may contain colon-separated host lists.
+
+.conf same@_domain@_copy@_routing boolean false
+.index address||copying routing
+Addresses with the same domain are normally routed by the \%manualroute%\ router
+to the same list of hosts. However, this cannot be presumed, because the router
+options and preconditions may refer to the local part of the address. By
+default, therefore, Exim routes each address in a message independently. DNS
+servers run caches, so repeated DNS lookups are not normally expensive, and in
+any case, personal messages rarely have more than a few recipients.
+
+If you are running mailing lists with large numbers of subscribers at the same
+domain, and you are using a \%manualroute%\ router which is independent of the
+local part, you can set \same@_domain@_copy@_routing\ to bypass repeated DNS
+lookups for identical domains in one message. In this case, when \%manualroute%\
+routes an address to a remote transport, any other unrouted addresses in the
+message that have the same domain are automatically given the same routing
+without processing them independently. However, this is only done if
+\headers@_add\ and \headers@_remove\ are unset.
+
+.endconf
+
+
+.section 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
+.display
+<<domain pattern>> <<list of hosts>> <<options>>
+.endd
+The following example contains two rules, each with a simple domain pattern and
+no options:
+.display asis
+route_list = \
+ dict.ref.example mail-1.ref.example:mail-2.ref.example ; \
+ thes.ref.example mail-3.ref.example:mail-4.ref.example
+.endd
+The three parts of a rule are separated by white space. The pattern and the
+list of hosts can be enclosed in quotes if necessary, and if they are, the
+usual quoting rules apply. Each rule in a \route@_list\ must start with a
+single domain pattern, which is the only mandatory item in the rule. The
+pattern is in the same format as one item in a domain list (see section
+~~SECTdomainlist),
+except that it may not be the name of an interpolated file.
+That is, it may be wildcarded, or a regular expression, or a file or database
+lookup (with semicolons doubled, because of the use of semicolon as a separator
+in a \route@_list\).
+
+The rules in \route@_list\ are searched in order until one of the patterns
+matches the domain that is being routed. The list of hosts and then options are
+then used as described below. If there is no match, the router declines. When
+\route@_list\ is set, \route@_data\ must not be set.
+
+
+.section Routing rules in route@_data
+The use of \route@_list\ is convenient when there are only a small number of
+routing rules. For larger numbers, it is easier to use a file or database to
+hold the routing information, and use the \route@_data\ option instead.
+The value of \route@_data\ is a list of hosts, followed by (optional) options.
+Most commonly, \route@_data\ is set as a string that contains an
+expansion lookup. For example, suppose we place two routing rules in a file
+like this:
+.display asis
+dict.ref.example: mail-1.ref.example:mail-2.ref.example
+thes.ref.example: mail-3.ref.example:mail-4.ref.example
+.endd
+This data can be accessed by setting
+.display asis
+route_data = ${lookup{$domain}lsearch{/the/file/name}}
+.endd
+Failure of the lookup results in an empty string, causing the router to
+decline. However, you do not have to use a lookup in \route@_data\. The only
+requirement is that the result of expanding the string is a list of hosts,
+possibly followed by options, separated by white space. The list of hosts must
+be enclosed in quotes if it contains white space.
+
+
+
+.section Format of the list of hosts
+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.
+
+If the list of hosts was obtained from a \route@_list\ item, the following
+variables are set during its expansion:
+.index numerical variables (\$1$\, \$2$\, etc)||in \%manualroute%\ router
+.numberpars $.
+If the domain was matched against a regular expression, the numeric variables
+\$1$\, \$2$\, etc. may be set.
+.nextp
+\$0$\ is always set to the entire domain.
+.nextp
+\$1$\ is also set when partial matching is done in a file lookup.
+.nextp
+.index \$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$\.
+.endp
+
+
+.em
+.section How the list of hosts is used
+When an address is routed to an \%smtp%\ transport by \%manualroute%\, each of
+the hosts is tried, in the order specified, when carrying out the SMTP
+delivery. However, the order can be changed by setting the \hosts@_randomize\
+option, either on the router (see section ~~SECTprioptman above), or on the
+transport.
+
+Hosts may be listed by name or by IP address. An unadorned name in the list of
+hosts is interpreted as a host name. A name that is followed by \"/MX"\ is
+interpreted as an indirection to a sublist of hosts obtained by looking up MX
+records in the DNS. For example:
+.display asis
+route_list = * x.y.z:p.q.r/MX:e.f.g
+.endd
+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
+be an interface on the local host and the item is not the first in the list,
+Exim discards it and any subsequent items. If it is the first item, what
+happens is controlled by the
+.index \self\ option||in \%manualroute%\ router
+\self\ option of the router.
+
+A name on the list that is followed by \"/MX"\ is replaced with the list of
+hosts obtained by looking up MX records for the name. This is always a DNS
+lookup; the \bydns\ and \byname\ options (see section ~~SECThowoptused below)
+are not relevant here. The order of these hosts is determined by the preference
+values in the MX records, according to the usual rules. Because randomizing
+happens before the MX lookup, it does not affect the order that is defined by
+MX preferences.
+.nem
+
+If the local host is present in the sublist obtained from MX records, but is
+not the most preferred host in that list, it and any equally or less
+preferred hosts are removed before the sublist is inserted into the main list.
+
+If the local host is the most preferred host in the MX list, what happens
+depends on where in the original list of hosts the \"/MX"\ item appears. If it
+is not the first item (that is, there are previous hosts in the main list),
+Exim discards this name and any subsequent items in the main list.
+
+If the MX item is first in the list of hosts, and the local host is the
+most preferred host, what happens is controlled by the \self\ option of the
+router.
+
+DNS failures when lookup up the MX records are treated in the same way as DNS
+failures when looking up IP addresses: \pass@_on@_timeout\ and
+\host@_find@_failed\ are used when relevant.
+
+.em
+The generic \ignore@_target@_hosts\ option applies to all hosts in the list,
+whether obtained from an MX lookup or not.
+.nem
+
+
+.section How the options are used
+.rset SECThowoptused "~~chapter.~~section"
+The options are a sequence of words; in practice no more than three are ever
+present. One of the words can be the name of a transport; this overrides the
+\transport\ option on the router for this particular routing rule only. The
+other words (if present) control randomization of the list of hosts on a
+per-rule basis, and how the IP addresses of the hosts are to be found when
+routing to a remote transport. These options are as follows:
+.numberpars $.
+\randomize\: randomize the order of the hosts in this list, overriding the
+setting of \hosts@_randomize\ for this routing rule only.
+.nextp
+\no@_randomize\: do not randomize the order of the hosts in this list,
+overriding the setting of \hosts@_randomize\ for this routing rule only.
+.nextp
+\byname\: use \*getipnodebyname()*\ (\*gethostbyname()*\ on older systems) to
+find IP addresses. This function may ultimately cause a DNS lookup, but it may
+also look in \(/etc/hosts)\ or other sources of information.
+.nextp
+\bydns\: look up address records for the hosts directly in the DNS; fail if
+no address records are found. If there is a temporary DNS error (such as a
+timeout), delivery is deferred.
+.endp
+For example:
+.display asis
+route_list = domain1 host1:host2:host3 randomize bydns;\
+ domain2 host4:host5
+.endd
+If neither \byname\ nor \bydns\ is given, Exim behaves as follows: First, a DNS
+lookup is done. If this yields 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.
+
+\**Warning**\: It has been discovered that on some systems, if a DNS lookup
+called via \*getipnodebyname()*\ times out, \\HOST@_NOT@_FOUND\\ is returned
+instead of \\TRY@_AGAIN\\. That is why the default action is to try a DNS
+lookup first. Only if that gives a definite `no such host' is the local
+function called.
+
+
+
+If no IP address for a host can be found, what happens is controlled by the
+\host@_find@_failed\ option.
+
+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.
+
+
+.section Manualroute examples
+In some of the examples that follow, the presence of the \remote@_smtp\
+transport, as defined in the default configuration file, is assumed:
+
+.numberpars $.
+.index smart host||example router
+The \%manualroute%\ router can be used to forward all external mail to a
+\*smart host*\. If you have set up, in the main part of the configuration, a
+named domain list that contains your local domains, for example,
+.display asis
+domainlist local_domains = my.domain.example
+.endd
+you can arrange for all other domains to be routed to a smart host by making
+your first router something like this:
+.display asis
+smart_route:
+ driver = manualroute
+ domains = !+local_domains
+ transport = remote_smtp
+ route_list = * smarthost.ref.example
+.endd
+This causes all non-local addresses to be sent to the single host
+\*smarthost.ref.example*\. If a colon-separated list of smart hosts is given,
+they are tried in order
+(but you can use \hosts@_randomize\ to vary the order each time).
+Another way of configuring the same thing is this:
+.display asis
+smart_route:
+ driver = manualroute
+ transport = remote_smtp
+ route_list = !+local_domains smarthost.ref.example
+.endd
+There is no difference in behaviour between these two routers as they stand.
+However, they behave differently if \no@_more\ is added to them. In the first
+example, the router is skipped if the domain does not match the \domains\
+precondition; the following router is always tried. If the router runs, it
+always matches the domain and so can never decline. Therefore, \no@_more\ would
+have no effect. In the second case, the router is never skipped; it always
+runs. However, if it doesn't match the domain, it declines. In this case
+\no@_more\ would prevent subsequent routers from running.
+
+.nextp
+.index mail hub example
+A \*mail hub*\ is a host which receives mail for a number of domains via MX
+records in the DNS and delivers it via its own private routing mechanism. Often
+the final destinations are behind a firewall, with the mail hub being the one
+machine that can connect to machines both inside and outside the firewall. The
+\%manualroute%\ router is usually used on a mail hub to route incoming messages
+to the correct hosts. For a small number of domains, the routing can be inline,
+using the \route@_list\ option, but for a larger number a file or database
+lookup is easier to manage.
+
+If the domain names are in fact the names of the machines to which the mail is
+to be sent by the mail hub, the configuration can be quite simple. For
+example,
+.display asis
+hub_route:
+ driver = manualroute
+ transport = remote_smtp
+ route_list = *.rhodes.tvs.example $domain
+.endd
+This configuration routes domains that match \"*.rhodes.tvs.example"\ to hosts
+whose names are the same as the mail domains. A similar approach can be taken
+if the host name can be obtained from the domain name by a string manipulation
+that the expansion facilities can handle. Otherwise, a lookup based on the
+domain can be used to find the host:
+.display asis
+through_firewall:
+ driver = manualroute
+ transport = remote_smtp
+ route_data = ${lookup {$domain} cdb {/internal/host/routes}}
+.endd
+The result of the lookup must be the name or IP address of the host (or
+hosts) to which the address is to be routed. If the lookup fails, the route
+data is empty, causing the router to decline. The address then passes to the
+next router.
+
+.nextp
+.index batched SMTP output example
+.index SMTP||batched outgoing, example
+You can use \%manualroute%\ to deliver messages to pipes or files in batched
+SMTP format for onward transportation by some other means. This is one way of
+storing mail for a dial-up host when it is not connected. The route list entry
+can be as simple as a single domain name in a configuration like this:
+.display asis
+save_in_file:
+ driver = manualroute
+ transport = batchsmtp_appendfile
+ route_list = saved.domain.example
+.endd
+though often a pattern is used to pick up more than one domain. If there are
+several domains or groups of domains with different transport requirements,
+different transports can be listed in the routing information:
+.display asis
+save_in_file:
+ driver = manualroute
+ route_list = \
+ *.saved.domain1.example $domain batch_appendfile; \
+ *.saved.domain2.example \
+ ${lookup{$domain}dbm{/domain2/hosts}{$value}fail} \
+ batch_pipe
+.endd
+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
+the address if the lookup fails.
+.nextp
+.index UUCP||example of router for
+Routing mail directly to UUCP software is a specific case of the use of
+\%manualroute%\ in a gateway to another mail environment. This is an example of
+one way it can be done:
+.display asis
+# Transport
+uucp:
+ driver = pipe
+ user = nobody
+ command = /usr/local/bin/uux -r - \
+ ${substr_-5:$host}!rmail ${local_part}
+ return_fail_output = true
+.endd
+.display asis
+# Router
+uucphost:
+ transport = uucp
+ driver = manualroute
+ route_data = \
+ ${lookup{$domain}lsearch{/usr/local/exim/uucphosts}}
+.endd
+The file \(/usr/local/exim/uucphosts)\ contains entries like
+.display asis
+darksite.ethereal.example: darksite.UUCP
+.endd
+It can be set up more simply without adding and removing `.UUCP' but this way
+makes clear the distinction between the domain name
+\*darksite.ethereal.example*\ and the UUCP host name \*darksite*\.
+.endp
+
+
+
+
+
+
+.
+.
+.
+.
+. ============================================================================
+.chapter The queryprogram router
+.set runningfoot "queryprogram router"
+.rset CHAPdriverlast "~~chapter"
+.index \%queryprogram%\ router
+.index routers||\%queryprogram%\
+.index routing||by external program
+The \%queryprogram%\ router routes an address by running an external command and
+acting on its output. This is an expensive way to route, and is intended mainly
+for use in lightly-loaded systems, or for performing experiments. However, if
+it is possible to use the precondition options (\domains\, \local@_parts\,
+etc) to skip this router for most addresses, it could sensibly be used in
+special cases, even on a busy host. There are the following private options:
+
+.startconf
+.index options||\%queryprogram%\ router
+.conf command string$**$ unset
+This option must be set. It specifies the command that is to be run. The
+command is split up into a command name and arguments, and then each is
+expanded separately (exactly as for a \%pipe%\ transport, described in chapter
+~~CHAPpipetransport).
+
+.conf command@_group string unset
+.index gid (group id)||in \%queryprogram%\ router
+This option specifies a gid to be set when running the command. It must be set
+if \command@_user\ specifies a numerical uid. If it begins with a digit, it is
+interpreted as the numerical value of the gid. Otherwise it is looked up using
+\*getgrnam()*\.
+
+.conf command@_user string unset
+.index uid (user id)||for \%queryprogram%\
+This option must be set. It specifies the uid which is set when running the
+command. If it begins with a digit it is interpreted as the numerical value of
+the uid. Otherwise, it is looked up using \*getpwnam()*\ to obtain a value for
+the uid and, if \command@_group\ is not set, a value for the gid also.
+
+.conf current@_directory string /
+This option specifies an absolute path which is made the current directory
+before running the command.
+
+.conf timeout time 1h
+If the command does not complete within the timeout period, its process group
+is killed and the message is frozen. A value of zero time specifies no
+timeout.
+
+.endconf
+
+The standard output of the command is connected to a pipe, which is read when
+the command terminates. It should consist of a single line of output,
+containing up to five fields, separated by white space. The first field is one
+of the following words (case-insensitive):
+.numberpars $.
+\*Accept*\: routing succeeded; the remaining fields specify what to do (see
+below).
+.nextp
+\*Decline*\: the router declines; pass the address to the next router, unless
+\no@_more\ is set.
+.nextp
+\*Fail*\: routing failed; do not pass the address to any more routers. Any
+subsequent text on the line is an error message. If the router is run as part
+of address verification during an incoming SMTP message, the message is
+included in the SMTP response.
+.nextp
+\*Defer*\: routing could not be completed at this time; try again later. Any
+subsequent text on the line is an error message which is logged. It is not
+included in any SMTP response.
+.nextp
+\*Freeze*\: the same as \*defer*\, except that the message is frozen.
+.nextp
+\*Pass*\: pass the address to the next router (or the router specified by
+\pass@_router\), overriding \no@_more\.
+.nextp
+\*Redirect*\: the message is redirected. The remainder of the line is a list of
+new addresses, which are routed independently, starting with the first router,
+or the router specified by \redirect@_router\, if set.
+.endp
+When the first word is \*accept*\, the remainder of the line consists of a
+number of keyed data values, as follows (split into two lines here, to fit on
+the page):
+.display
+ACCEPT TRANSPORT=<<transport>> HOSTS=<<list of hosts>>
+ LOOKUP=byname|bydns DATA=<<text>>
+.endd
+The data items can be given in any order, and all are optional. If no transport
+is included, the transport specified by the generic \transport\ option is used.
+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.
+
+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
+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.
+
+If the DATA field is set, its value is placed in the \$address@_data$\
+variable. For example, this return line
+.display asis
+accept hosts=x1.y.example:x2.y.example data="rule1"
+.endd
+routes the address to the default transport, with a host list containing two
+hosts. When the transport runs, the string `rule1' is in \$address@_data$\.
+
+
+
+.
+.
+.
+.
+. ============================================================================
+.chapter The redirect router
+.set runningfoot "redirect router"
+.rset CHAPredirect "~~chapter"
+.index \%redirect%\ router
+.index routers||\%redirect%\
+.index alias file||in a \%redirect%\ router
+.index address redirection||\%redirect%\ router
+The \%redirect%\ router handles several kinds of address redirection. Its most
+common uses are for resolving local part aliases from a central alias file
+(usually called \(/etc/aliases)\) and for handling users' personal \(.forward)\
+files, but it has many other potential uses. The incoming address can be
+redirected in several different ways:
+.numberpars $.
+It can be replaced by one or more new addresses which are themselves routed
+independently.
+.nextp
+It can be routed to be delivered to a given file or directory.
+.nextp
+It can be routed to be delivered to a specified pipe command.
+.nextp
+It can cause an automatic reply to be generated.
+.nextp
+It can be forced to fail, with a custom error message.
+.nextp
+It can be temporarily deferred.
+.nextp
+It can be discarded.
+.endp
+The generic \transport\ option must not be set for \%redirect%\ routers.
+However, there are some private options which define transports for delivery to
+files and pipes, and for generating autoreplies. See the \file@_transport\,
+\pipe@_transport\ and \reply@_transport\ descriptions below.
+
+
+.section Redirection data
+The router operates by interpreting a text string which it obtains either by
+expanding the contents of the \data\ option, or by reading the entire contents
+of a file whose name is given in the \file\ option. These two options are
+mutually exclusive. The first is commonly used for handling system aliases, in
+a configuration like this:
+.display asis
+system_aliases:
+ driver = redirect
+ data = ${lookup{$local_part}lsearch{/etc/aliases}}
+.endd
+.em
+If the lookup fails, the expanded string in this example is empty. When the
+expansion of \data\ results in an empty string, the router declines. A forced
+expansion failure also causes the router to decline; other expansion failures
+cause delivery to be deferred.
+.nem
+
+A configuration using \file\ is commonly used for handling users' \(.forward)\
+files, like this:
+.display asis
+userforward:
+ driver = redirect
+ check_local_user
+ file = $home/.forward
+ no_verify
+.endd
+If the file does not exist, or causes no action to be taken (for example, it is
+empty or consists only of comments), the router declines. \**Warning**\: This
+is not the case when the file contains syntactically valid items that happen to
+yield empty addresses, for example, items containing only RFC 2822 address
+comments.
+
+
+.section Forward files and address verification
+.index address redirection||while verifying
+It is usual to set \no@_verify\ on \%redirect%\ routers which handle users'
+\(.forward)\ files, as in the example above. There are two reasons for this:
+.numberpars $.
+When Exim is receiving an incoming SMTP message from a remote host, it is
+running under the Exim uid, not as root.
+No additional groups are set up, even if the Exim uid is a member of other
+groups (that is, the \*initgroups()*\ function is not run).
+Exim is unable to change uid to read the file as the user, and it may not be
+able to read it as the Exim user. So in practice the router may not be able to
+operate.
+.nextp
+However, even when the router can operate, the existence of a \(.forward)\ file
+is unimportant when verifying an address. What should be checked is whether the
+local part is a valid user name or not. Cutting out the redirection processing
+saves some resources.
+.endp
+
+
+
+
+.section Interpreting redirection data
+.index Sieve filter||specifying in redirection data
+.index filter||specifying in redirection data
+The contents of the data string, whether obtained from \data\ or \file\, can be
+interpreted in two different ways:
+.numberpars $.
+If the \allow@_filter\ option is set true, and the data begins with the text
+`@#Exim filter' or `@#Sieve filter', it is interpreted as a list of
+\*filtering*\ instructions in the form of an Exim or Sieve filter file,
+respectively. Details of the syntax and semantics of filter files are described
+in a separate document entitled \*Exim's interfaces to mail filtering*\; this
+document is intended for use by end users.
+.nextp
+Otherwise, the data must be a comma-separated list of redirection items, as
+described in the next section.
+.endp
+When a message is redirected to a file (a `mail folder'), the file name given
+in a non-filter redirection list must always be an absolute path. A filter may
+generate a relative path -- how this is handled depends on the transport's
+configuration. See section ~~SECTfildiropt for a discussion of this issue for
+the \%appendfile%\ transport.
+
+
+.section Items in a non-filter redirection list
+.rset SECTitenonfilred "~~chapter.~~section"
+.index address redirection||non-filter list items
+When the redirection data is not an Exim or Sieve filter, for example, if it
+comes from a conventional alias or forward file, it consists of a list of
+addresses, file names, pipe commands, or certain special items (see section
+~~SECTspecitredli below). The special items can be individually enabled or
+disabled by means of options whose names begin with \allow@_\ or \forbid@_\,
+depending on their default values. The items in the list are separated by
+commas or newlines.
+If a comma is required in an item, the entire item must be enclosed in double
+quotes.
+
+Lines starting with a @# character are comments, and are ignored, and @# may
+also appear following a comma, in which case everything between the @# and the
+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.
+
+\**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
+\*obsolete.example*\, retaining the existing local part, you could use this
+setting:
+.display asis
+data = ${quote:$local_part}@newdomain.example
+.endd
+
+
+.section Redirecting to a local mailbox
+.rset SECTredlocmai "~~chapter.~~section"
+.index routing||loops in
+.index loop||while routing, avoidance of
+.index address redirection||to local mailbox
+A redirection item may safely be the same as the address currently under
+consideration. This does not cause a routing loop, because a router is
+automatically skipped if any ancestor of the address that is being processed
+.em
+is the same as the current address and was processed by the current router.
+.nem
+Such an address is therefore passed to the following routers, so it is handled
+as if there were no redirection. When making this loop-avoidance test, the
+complete local part, including any prefix or suffix, is used.
+
+.index address redirection||local part without domain
+Specifying the same local part without a domain is a common usage in personal
+filter files when the user wants to have messages delivered to the local
+mailbox and also forwarded elsewhere. For example, the user whose login is
+\*cleo*\ might have a \(.forward)\ file containing this:
+.display asis
+cleo, cleopatra@egypt.example
+.endd
+.index backslash in alias file
+.index alias file||backslash in
+For compatibility with other MTAs, such unqualified local parts may be
+preceeded by `@\', but this is not a requirement for loop prevention. However,
+it does make a difference if more than one domain is being handled
+synonymously.
+
+If an item begins with `@\' and the rest of the item parses as a valid RFC 2822
+address that does not include a domain, the item is qualified using the domain
+of the incoming address. In the absence of a leading `@\', unqualified
+addresses are qualified using the value in \qualify@_recipient\, but you can
+force the incoming domain to be used by setting \qualify__preserve@_domain\.
+
+Care must be taken if there are alias names for local users.
+.em
+Consider an MTA handling a single local domain where the system alias file
+contains:
+.display asis
+Sam.Reman: spqr
+.endd
+Now suppose that Sam (whose login id is \*spqr*\) wants to save copies of
+messages in the local mailbox, and also forward copies elsewhere. He creates
+this forward file:
+.display asis
+Sam.Reman, spqr@reme.elsewhere.example
+.endd
+With these settings, an incoming message addressed to \*Sam.Reman*\ fails. The
+\%redirect%\ router for system aliases does not process \*Sam.Reman*\ the
+second time round, because it has previously routed it,
+.nem
+and the following routers presumably cannot handle the alias. The forward file
+should really contain
+.display asis
+spqr, spqr@reme.elsewhere.example
+.endd
+but because this is such a common error, the \check@_ancestor\ option (see
+below) exists to provide a way to get round it. This is normally set on a
+\%redirect%\ router that is handling users' \(.forward)\ files.
+
+
+.section Special items in redirection lists
+.rset SECTspecitredli "~~chapter.~~section"
+In addition to addresses, the following types of item may appear in redirection
+lists (that is, in non-filter redirection data):
+
+.numberpars $.
+.index pipe||in redirection list
+.index address redirection||to pipe
+An item is treated as a pipe command if it begins with `|' and does not parse
+as a valid RFC 2822 address that includes a domain. A transport for running the
+command must be specified by the \pipe@_transport\ option.
+.em
+Normally, either the router or the transport specifies a user and a group under
+which to run the delivery. The default is to use the Exim user and group.
+.nem
+
+Single or double quotes can be used for enclosing the individual arguments of
+the pipe command; no interpretation of escapes is done for single quotes. If
+the command contains a comma character, it is necessary to put the whole item
+in double quotes, for example:
+.display asis
+"|/some/command ready,steady,go"
+.endd
+since items in redirection lists are terminated by commas. Do not, however,
+quote just the command. An item such as
+.display asis
+|"/some/command ready,steady,go"
+.endd
+is interpreted as a pipe with a rather strange command name, and no arguments.
+.nextp
+.index file||in redirection list
+.index address redirection||to file
+An item is interpreted as a path name if it begins with `/' and does not parse
+as a valid RFC 2822 address that includes a domain. For example,
+.display asis
+/home/world/minbari
+.endd
+is treated as a file name, but
+.display asis
+/s=molari/o=babylon/@x400gate.way
+.endd
+is treated as an address. For a file name, a transport must be specified using
+the \file@_transport\ option. However, if the generated path name ends with a
+forward slash character, it is interpreted as a directory name rather than a
+file name, and \directory@_transport\ is used instead.
+
+.em
+Normally, either the router or the transport specifies a user and a group under
+which to run the delivery. The default is to use the Exim user and group.
+.index \(/dev/null)\
+However, if a redirection item is the path \(/dev/null)\, delivery to it is
+bypassed at a high level, and the log entry shows `$*$$*$bypassed$*$$*$'
+instead of a transport name. In this case the user and group are not used.
+.nem
+.nextp
+.index included address list
+.index address redirection||included external list
+If an item is of the form
+.display
+:include:<<path name>>
+.endd
+a list of further items is taken from the given file and included at that
+point.
+\**Note**\: such a file can not be a filter file; it is just an out-of-line
+addition to the list.
+The items in the included list are separated by commas or newlines and are not
+subject to expansion. If this is the first item in an alias list in an
+\%lsearch%\ file, a colon must be used to terminate the alias name. This
+example is incorrect:
+.display asis
+list1 :include:/opt/lists/list1
+.endd
+It must be given as
+.display asis
+list1: :include:/opt/lists/list1
+.endd
+.nextp
+.index address redirection||to black hole
+Sometimes you want to throw away mail to a particular local part. Making the
+\data\ option expand to an empty string does not work, because that causes the
+router to decline. Instead, the alias item
+.index black hole
+.index abandoning mail
+.display
+:blackhole:
+.endd
+can be used. It does what its name implies. No delivery is done, and no error
+message is generated. This has the same effect as specifing \(/dev/null)\, but
+can be independently disabled.
+
+\**Warning**\: If \":blackhole:"\ appears anywhere in a redirection list, no
+delivery is done for the original local part, even if other redirection items
+are present. If you are generating a multi-item list (for example, by reading a
+database) and need the ability to provide a no-op item, you must use
+\(/dev/null)\.
+
+.nextp
+.index delivery||forcing failure
+.index delivery||forcing deferral
+.index failing delivery||forcing
+.index deferred delivery, forcing
+.index customizing||failure message
+An attempt to deliver a particular address can be deferred or forced to fail by
+redirection items of the form
+.display
+:defer:
+$rm{or}
+:fail:
+.endd
+respectively. When a redirection list contains such an item, it applies to the
+entire redirection; any other items in the list are ignored (:::blackhole:: is
+different). Any text following :::fail:: or :::defer:: is placed in the error
+text associated with the failure. For example, an alias file might contain:
+.display asis
+X.Employee: :fail: Gone away, no forwarding address
+.endd
+In the case of an address that is being verified from an ACL or as the subject
+of a \\VRFY\\ command, the text is included in the SMTP error response by
+default. 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 SMTP code for a :::defer::, and 550 for :::fail::. In non-SMTP cases the
+text is included in the error message that Exim generates.
+
+
+
+Normally the error text is the rest of the redirection list -- a comma does not
+terminate it -- but a newline does act as a terminator. Newlines are not
+normally present in alias expansions. In \%lsearch%\ lookups they are removed as
+part of the continuation process, but they may exist in other kinds of lookup
+and in :::include:: files.
+
+During routing for message delivery (as opposed to verification), a redirection
+containing :::fail:: causes an immediate failure of the incoming address,
+whereas :::defer:: causes the message to remain on the queue so that a
+subsequent delivery attempt can happen at a later time. If an address is
+deferred for too long, it will ultimately fail, because the normal retry
+rules still apply.
+.nextp
+.index alias file||exception to default
+Sometimes it is useful to use a single-key search type with a default (see
+chapter ~~CHAPfdlookup) to look up aliases. However, there may be a need for
+exceptions to the default. These can be handled by aliasing them to
+.display asis
+:unknown:
+.endd
+This differs from :::fail:: in that it causes the \%redirect%\ router to decline,
+whereas :::fail:: forces routing to fail. A lookup which results in an empty
+redirection list has the same effect.
+.endp
+
+.section Duplicate addresses
+.index duplicate addresses
+.index address||duplicate, discarding
+.index pipe||duplicated
+Exim removes duplicate addresses from the list to which it is delivering, so as
+to deliver just one copy to each address. This does not apply to deliveries
+routed to pipes by different immediate parent addresses, but an indirect
+aliasing scheme of the type
+.display asis
+pipe: |/some/command $local_part
+localpart1: pipe
+localpart2: pipe
+.endd
+does not work with a message that is addressed to both local parts, because
+when the second is aliased to the intermediate local part `pipe' it gets
+discarded as being the same as a previously handled address. However, a scheme
+such as
+.display asis
+localpart1: |/some/command $local_part
+localpart2: |/some/command $local_part
+.endd
+does result in two different pipe deliveries, because the immediate parents of
+the pipes are distinct.
+
+
+.section Repeated redirection expansion
+.index repeated redirection expansion
+.index address redirection||repeated for each delivery attempt
+When a message cannot be delivered to all of its recipients immediately,
+leading to two or more delivery attempts, redirection expansion is carried out
+afresh each time for those addresses whose children were not all previously
+delivered. If redirection is being used as a mailing list, this can lead to new
+members of the list receiving copies of old messages. The \one@_time\ option
+can be used to avoid this.
+
+.section Errors in redirection lists
+.index address redirection||errors
+If \skip@_syntax@_errors\ is set, a malformed address that causes a parsing
+error is skipped, and an entry is written to the main log. This may be useful
+for mailing lists that are automatically managed. Otherwise, if an error is
+detected while generating the list of new addresses, the original address is
+deferred. See also \syntax@_errors@_to\.
+
+
+.section Private options for the redirect router
+
+The private options for the \%redirect%\ router are as follows:
+
+.startconf
+.index options||\%redirect%\ router
+
+.conf allow@_defer boolean false
+Setting this option allows the use of :::defer:: in non-filter redirection
+data,
+or the \defer\ command in an Exim filter file.
+
+.conf allow@_fail boolean false
+.index failing delivery||from filter
+If this option is true, the :::fail:: item can be used in a redirection list,
+and the \fail\ command may be used in a filter file.
+
+.conf allow@_filter boolean false
+.index filter||enabling use of
+.index Sieve filter||enabling use of
+Setting this option allows Exim to interpret redirection data that starts with
+`@#Exim filter' or `@#Sieve filter' as a set of filtering instructions. There
+are some features of Exim filter files that some administrators may wish to
+lock out; see the \forbid@_filter@_xxx\ options below. The filter is run using
+the uid and gid set by the generic \user\ and \group\ options. These take their
+defaults from the password data if \check@_local@_user\ is set, so in the
+normal case of users' personal filter files, the filter is run as the relevant
+user. When \allow@_filter\ is set true, Exim insists that either
+\check@_local@_user\ or \user\ is set.
+
+
+.conf allow@_freeze boolean false
+.index freezing messages||allowing in filter
+Setting this option allows the use of the \freeze\ command in an Exim filter.
+This command is more normally encountered in system filters, and is disabled by
+default for redirection filters because it isn't something you usually want to
+let ordinary users do.
+
+
+.conf check@_ancestor boolean false
+This option is concerned with handling generated addresses that are the same
+as some address in the list of redirection ancestors of the current address.
+Although it is turned off by default in the code, it is set in the default
+configuration file for handling users' \(.forward)\ files. It is recommended
+for this use of the \%redirect%\ router.
+
+.em
+When \check@_ancestor\ is set, if a generated address (including the domain) is
+the same as any ancestor of the current address, it is replaced by a copy of
+the current address. This helps in the case where local part A is aliased to B,
+and B has a \(.forward)\ file pointing back to A. For example, within a single
+domain, the local part `Joe.Bloggs' is aliased to `jb' and \(@~jb/.forward)\
+contains:
+.nem
+.display
+@\Joe.Bloggs, <<other item(s)>>
+.endd
+Without the \check@_ancestor\ setting, either local part (`jb' or `joe.bloggs')
+gets processed once by each router and so ends up as it was originally. If `jb'
+is the real mailbox name, mail to `jb' gets delivered (having been turned into
+`joe.bloggs' by the \(.forward)\ file and back to `jb' by the alias), but mail
+to `joe.bloggs' fails. Setting \check@_ancestor\ on the \%redirect%\ router that
+handles the \(.forward)\ file prevents it from turning `jb' back into
+`joe.bloggs' when that was the original address. See also the \repeat@_use\
+option below.
+
+.conf check@_group boolean "see below"
+When the \file\ option is used, the group owner of the file is checked only
+when this option is set. The permitted groups are those listed in the
+\owngroups\ option, together with the user's default group if
+\check@_local@_user\ is set. If the file has the wrong group, routing is
+deferred. The default setting for this option is true if \check@_local@_user\
+is set and the \modemask\ option permits the group write bit, or if the
+\owngroups\ option is set. Otherwise it is false, and no group check occurs.
+
+
+.conf check@_owner boolean "see below"
+When the \file\ option is used, the owner of the file is checked only when this
+option is set. If \check@_local@_user\ is set, the local user is permitted;
+otherwise the owner must be one of those listed in the \owners\ option. The
+default value for this option is true if \check@_local@_user\ or \owners\ is
+set. Otherwise the default is false, and no owner check occurs.
+
+.conf data string$**$ unset
+This option is mutually exclusive with \file\. One or other of them must be
+set, but not both. The contents of \data\ are expanded, and then used as the
+list of forwarding items, or as a set of filtering instructions. If the
+expansion is forced to fail, or the result is an empty string or a string that
+has no effect (consists entirely of comments), the router declines.
+
+When filtering instructions are used, the string must begin with `@#Exim
+filter', and all comments in the string, including this initial one, must be
+terminated with newline characters. For example:
+.display asis
+data = #Exim filter\n\
+ if $h_to: contains Exim then save $home/mail/exim endif
+.endd
+If you are reading the data from a database where newlines cannot be included,
+you can use the \$@{sg@}$\ expansion item to turn the escape string of your
+choice into a newline.
+
+.conf directory@_transport string$**$ unset
+A \%redirect%\ router sets up a direct delivery to a directory when a path name
+ending with 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.
+
+.conf file string$**$ unset
+This option specifies the name of a file that contains the redirection data. It
+is mutually exclusive with the \data\ option. The string is expanded before
+use; if the expansion is forced to fail, the router declines. Other expansion
+failures cause delivery to be deferred. The result of a successful expansion
+must be an absolute path. The entire file is read and used as the redirection
+data. If the data is an empty string or a string that has no effect (consists
+entirely of comments), the router declines.
+
+.index NFS||checking for file existence
+If the attempt to open the file fails with a `does not exist' error, Exim
+runs a check on the containing directory,
+unless \ignore@_enotdir\ is true (see below).
+If the directory does not appear to exist, delivery is deferred. This can
+happen when users' \(.forward)\ files are in NFS-mounted directories, and there
+is a mount problem. If the containing directory does exist, but the file does
+not, the router declines.
+
+.conf file@_transport string$**$ unset
+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$\.
+
+.conf forbid@_blackhole boolean false
+If this option is true, the :::blackhole:: item may not appear in a redirection
+list.
+
+.conf forbid@_file boolean false
+.index delivery||to file, forbidding
+.index Sieve filter||forbidding delivery to a file
+.index Sieve filter||`keep' facility, disabling
+If this option is true, this router may not generate a new address that
+specifies delivery to a local file or directory, either from a filter or from a
+conventional forward file. This option is forced to be true if \one@_time\ is
+set. It applies to Sieve filters as well as to Exim filters, but if true, it
+locks out the Sieve's `keep' facility.
+
+.conf forbid@_filter@_existstest boolean false
+.index filter||locking out certain features
+If this option is true, string expansions in Exim filters are not allowed to
+make use of the \exists\ condition.
+
+.conf forbid@_filter@_logwrite boolean false
+If this option is true, use of the logging facility in Exim filters is not
+permitted. Logging is in any case available only if the filter is being run
+under some unprivileged uid (which is normally the case for ordinary users'
+\(.forward)\ files).
+
+.conf forbid@_filter@_lookup boolean false
+If this option is true, string expansions in Exim filter files are not allowed
+to make use of \lookup\ items.
+
+.conf forbid@_filter@_perl boolean false
+This option is available 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.
+
+.conf forbid@_filter@_readfile boolean false
+If this option is true, string expansions in Exim filter files are not allowed
+to make use of \readfile\ items.
+
+.conf forbid@_filter@_readsocket boolean false
+If this option is true, string expansions in Exim filter files are not allowed
+to make use of \readsocket\ items.
+
+.conf forbid@_filter@_reply boolean false
+If this option is true, this router may not generate an automatic reply
+message. Automatic replies can be generated only from Exim filter files, not
+from traditional forward files or Sieve filters. This option is forced to be
+true if \one@_time\ is set.
+
+.conf forbid@_filter@_run boolean false
+If this option is true, string expansions in Exim filter files are not allowed
+to make use of \run\ items.
+
+.conf forbid@_include boolean false
+If this option is true, items of the form
+.display
+:include:<<path name>>
+.endd
+are not permitted in non-filter redirection lists.
+
+.conf forbid@_pipe boolean false
+.index delivery||to pipe, forbidding
+If this option is true, this router may not generate a new address which
+specifies delivery to a pipe, either from an Exim filter or from a conventional
+forward file. This option is forced to be true if \one@_time\ is set.
+
+.conf hide@_child@_in@_errmsg boolean false
+.index bounce message||redirection details, suppressing
+If this option is true, it prevents Exim from quoting a child address if it
+generates a bounce or delay message for it. Instead it says `an address
+generated from <<the top level address>>'. Of course, this applies only to
+bounces generated locally. If a message is forwarded to another host, $it{its}
+bounce may well quote the generated address.
+
+.conf ignore@_eacces boolean false
+.index \\EACCES\\
+If this option is set and an attempt to open a redirection file yields the
+\\EACCES\\ error (permission denied), the \%redirect%\ router behaves as if the
+file did not exist.
+
+.conf ignore@_enotdir boolean false
+.index \\ENOTDIR\\
+If this option is set and an attempt to open a redirection file yields the
+\\ENOTDIR\\ error (something on the path is not a directory), the \%redirect%\
+router behaves as if the file did not exist.
+
+Setting \ignore@_enotdir\ has another effect as well: When a \%redirect%\
+router that has the \file\ option set discovers that the file does not exist
+(the \\ENOENT\\ error), it tries to \*stat()*\ the parent directory, as a check
+against unmounted NFS directories. If the parent can not be statted, delivery
+is deferred. However, it seems wrong to do this check when \ignore@_enotdir\ is
+set, because that option tells Exim to ignore `something on the path is not a
+directory' (the \\ENOTDIR\\ error). This is a confusing area, because it seems
+that some operating systems give \\ENOENT\\ where others give \\ENOTDIR\\.
+
+
+.conf include@_directory string unset
+If this option is set, the path names of any :::include:: items in a redirection
+list must start with this directory.
+
+.conf modemask "octal integer" 022
+This specifies mode bits which must not be set for a file specified by the
+\file\ option. If any of the forbidden bits are set, delivery is deferred.
+
+.conf one@_time boolean false
+.index one-time aliasing/forwarding expansion
+.index alias file||one-time expansion
+.index forward file||one-time expansion
+.index mailing lists||one-time expansion
+.index 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.
+
+\**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 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.
+
+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
+\all__parents\ log selector is set. It is expected that \one@_time\ will
+typically be used for mailing lists, where there is normally just one level of
+expansion.
+
+.conf owners "string list" unset
+.index ownership||alias file
+.index ownership||forward file
+.index alias file||ownership
+.index forward file||ownership
+This specifies a list of permitted owners for the file specified by \file\.
+This list is in addition to the local user when \check@_local@_user\ is set.
+See \check@_owner\ above.
+
+.conf owngroups "string list" unset
+This specifies a list of permitted groups for the file specified by \file\. The
+list is in addition to the local user's primary group when \check@_local@_user\
+is set. See \check@_group\ above.
+
+.em
+.conf qualify@_domain string$**$ unset
+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,
+the router declines. If you want to revert to the default, you can have the
+expansion generate \$qualify@_recipient$\.
+.nem
+
+.conf pipe@_transport string$**$ unset
+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$\.
+
+.conf qualify@_preserve@_domain boolean false
+.index domain||in redirection, preserving
+.index preserving domain in redirection
+.index address redirection||domain, preserving
+If this is set and an unqualified address (one without a domain) is generated,
+it is qualified with the domain of the
+.em
+parent address (the immediately preceding ancestor) instead of the local
+\qualify@_domain\ or global \qualify@_recipient\ value.
+.nem
+
+.conf repeat@_use boolean true
+If this option is set false, the router is skipped for a child address that has
+any ancestor that was routed by this router. This test happens before any of
+the other preconditions are tested. Exim's default anti-looping rules skip
+only when the ancestor is the same as the current address. See also
+\check@_ancestor\ above and the generic \redirect@_router\ option.
+
+.conf reply@_transport string$**$ unset
+A \%redirect%\ router sets up an automatic reply when a \mail\ or \vacation\
+command is used in a filter file. The transport used is specified by this
+option, which, after expansion, must be the name of a configured transport.
+This should normally be an \%autoreply%\ transport. Other transports are
+unlikely to do anything sensible or useful.
+
+.conf rewrite boolean true
+.index address redirection||disabling rewriting
+If this option is set false, addresses generated by the router are not
+subject to address rewriting. Otherwise, they are treated like new addresses
+and are rewritten according to the global rewriting rules.
+
+.conf skip@_syntax@_errors boolean false
+.index forward file||broken
+.index address redirection||broken files
+.index alias file||broken
+.index broken alias or forward files
+.index ignoring faulty addresses
+.index skipping faulty addresses
+.index error||skipping bad syntax
+If \skip@_syntax@_errors\ is set, syntactically malformed addresses in
+non-filter redirection data are skipped, and each failing address is logged. If
+\syntax@_errors@_to\ is set, a message is sent to the address it defines,
+giving details of the failures. If \syntax@_errors@_text\ is set, its contents
+are expanded and placed at the head of the error message generated by
+\syntax@_errors@_to\. Usually it is appropriate to set \syntax@_errors@_to\ to
+be the same address as the generic \errors@_to\ option. The
+\skip@_syntax@_errors\ option is often used when handling mailing lists.
+
+If all the addresses in a redirection list are skipped because of syntax
+errors, the router declines to handle the original address, and it is passed to
+the following routers.
+
+If \skip@_syntax@_errors\ is set when an Exim filter is interpreted, any syntax
+error in the filter causes filtering to be abandoned without any action being
+taken. The incident is logged, and the router declines to handle the address,
+so it is passed to the following routers.
+
+.index Sieve filter||syntax errors in
+Currently, any syntax errors in a Sieve filter file cause the `keep' action to
+occur. The values of \skip@_syntax@_errors\, \syntax@_errors@_to\, and
+\syntax@_errors@_text\ are not used.
+
+\skip@_syntax@_errors\ can be used to specify that errors in users' forward
+lists or filter files should not prevent delivery. The \syntax@_errors@_to\
+option, used with an address that does not get redirected, can be used to
+notify users of these errors, by means of a router like this:
+.display flow asis
+userforward:
+ driver = redirect
+ allow_filter
+ check_local_user
+ file = $home/.forward
+ file_transport = address_file
+ pipe_transport = address_pipe
+ reply_transport = address_reply
+ no_verify
+ skip_syntax_errors
+ syntax_errors_to = real-$local_part@$domain
+ syntax_errors_text = \
+ This is an automatically generated message. An error has\n\
+ been found in your .forward file. Details of the error are\n\
+ reported below. While this error persists, you will receive\n\
+ a copy of this message for every message that is addressed\n\
+ to you. If your .forward file is a filter file, or if it is\n\
+ a non-filter file containing no valid forwarding addresses,\n\
+ a copy of each incoming message will be put in your normal\n\
+ mailbox. If a non-filter file contains at least one valid\n\
+ forwarding address, forwarding to the valid addresses will\n\
+ happen, and those will be the only deliveries that occur.
+.endd
+You also need a router to ensure that local addresses that are prefixed by
+\"real-"\ are recognized, but not forwarded or filtered. For example, you could
+put this immediately before the \%userforward%\ router:
+.display asis
+real_localuser:
+ driver = accept
+ check_local_user
+ local_part_prefix = real-
+ transport = local_delivery
+.endd
+
+.conf syntax@_errors@_text string$**$ unset
+See \skip@_syntax@_errors\ above.
+
+.conf syntax@_errors@_to string unset
+See \skip@_syntax@_errors\ above.
+
+.endconf
+
+
+
+
+
+.
+.
+.
+. ============================================================================
+.chapter Environment for running local transports
+.rset CHAPenvironment "~~chapter"
+.set runningfoot "local transport environment"
+.index local transports||environment for
+.index environment for local transports
+.index transport||local, environment for
+Local transports handle deliveries to files and pipes. (The \%autoreply%\
+transport can be thought of as similar to a pipe.) Exim always runs transports
+in subprocesses, under specified uids and gids. Typical deliveries to local
+mailboxes run under the uid and gid of the local user.
+
+Exim also sets a specific current directory while running the transport; for
+some transports a home directory setting is also relevant. The \%pipe%\
+transport is the only one which sets up environment variables; see section
+~~SECTpipeenv for details.
+
+The values used for the uid, gid, and the directories may come from several
+different places. In many cases, the router that handles the address associates
+settings with that address as a result of its \check@_local@_user\, \group\, or
+\user\ options. However, values may also be given in the transport's own
+configuration, and these override anything that comes from the router.
+
+.section Uids and gids
+.rset SECTenvuidgid "~~chapter.~~section"
+.index local transports||uid and gid
+.index transport||local, uid and gid
+All transports have the options \group\ and \user\. If \group\ is set, it
+overrides any group that the router set in the address, even if \user\ is not
+set for the transport. This makes it possible, for example, to run local mail
+delivery under the uid of the recipient (set by the router), but in a special
+group (set by the transport). For example:
+.display asis
+# Routers ...
+# User/group are set by check_local_user in this router
+local_users:
+ driver = accept
+ check_local_user
+ transport = group_delivery
+
+# Transports ...
+# This transport overrides the group
+group_delivery:
+ driver = appendfile
+ file = /var/spool/mail/$local_part
+ group = mail
+.endd
+If \user\ is set for a transport, its value overrides what is set in the
+address. If \user\ is non-numeric and \group\ is not set, the gid associated
+with the user is used. If \user\ is numeric, \group\ must be set.
+
+.index \initgroups\ option
+When the uid is taken from the transport's configuration, the \*initgroups()*\
+function is called for the groups associated with that uid if the \initgroups\
+option is set for the transport. When the uid is not specified by the
+transport, but is associated with the address by a router, the option for
+calling \*initgroups()*\ is taken from the router configuration.
+
+.index \%pipe%\ transport||uid for
+The \%pipe%\ transport contains the special option \pipe@_as@_creator\. If this
+is set and \user\ is not set, the uid of the process that called Exim to
+receive the message is used, and if \group\ is not set, the corresponding
+original gid is also used.
+
+
+.section Current and home directories
+.index current directory for local transport
+.index home directory||for local transport
+.index transport||local, home directory for
+.index transport||local, current directory for
+Routers may set current and home directories for local transports by means of
+the \transport__current@_directory\ and \transport@_home@_directory\ options.
+However, if the transport's \current__directory\ or \home@_directory\ options
+are set, they override the router's values. In detail, the home directory
+for a local transport is taken from the first of these values that is set:
+.numberpars $.
+The \home@_directory\ option on the transport;
+.nextp
+The \transport@_home@_directory\ option on the router;
+.nextp
+The password data if \check@_local@_user\ is set on the router;
+.nextp
+The \router@_home@_directory\ option on the router.
+.endp
+The current directory is taken from the first of these values that is set:
+.numberpars $.
+The \current@_directory\ option on the transport;
+.nextp
+The \transport@_current@_directory\ option on the router.
+.endp
+
+If neither the router nor the transport sets a current directory, Exim uses the
+value of the home directory, if it is set. Otherwise it sets the current
+directory to \(/)\ before running a local transport.
+
+
+.section Expansion variables derived from the address
+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.
+
+
+
+
+
+
+
+.
+.
+.
+. ============================================================================
+.chapter Generic options for transports
+.rset CHAPtransportgeneric "~~chapter"
+.set runningfoot "generic transport options"
+
+.index generic options||transport
+.index options||generic, for transports
+.index transport||generic options for
+The following generic options apply to all transports:
+
+.startconf
+.conf body@_only boolean false
+.index transport||body only
+.index message||transporting body only
+.index body of message||transporting
+If this option is set, the message's headers are not transported. It is
+mutually exclusive with \headers@_only\. If it is used with the \%appendfile%\ or
+\%pipe%\ transports, the settings of \message@_prefix\ and \message@_suffix\
+should be checked, because this option does not automatically suppress them.
+
+.conf current@_directory string$**$ unset
+.index transport||current directory for
+This specifies the current directory that is to be set while running the
+transport, overriding any value that may have been set by the router.
+If the expansion fails for any reason, including forced failure, an error is
+logged, and delivery is deferred.
+
+.conf disable@_logging boolean false
+If this option is set true, nothing is logged for any
+.em
+deliveries by the transport or for any
+.nem
+transport errors. You should not set this option unless you really, really know
+what you are doing.
+
+.conf debug@_print string$**$ unset
+.index testing||variables in drivers
+If this option is set and debugging is enabled (see the \-d-\ command line
+option), the string is expanded and included in the debugging output when the
+transport is run.
+If expansion of the string fails, the error message is written to the debugging
+output, and Exim carries on processing.
+This facility is provided to help with checking out the values of variables and
+so on when debugging driver configurations. For example, if a \headers@_add\
+option is not working properly, \debug@_print\ could be used to output the
+variables it references. A newline is added to the text if it does not end with
+one.
+
+.conf delivery@_date@_add boolean false
+.index ::Delivery-date:: header line
+If this option is true, a ::Delivery-date:: header is added to the message. This
+gives the actual time the delivery was made. As this is not a standard header,
+Exim has a configuration option (\delivery@_date@_remove\) which requests its
+removal from incoming messages, so that delivered messages can safely be resent
+to other recipients.
+
+.conf driver string unset
+This specifies which of the available transport drivers is to be used.
+There is no default, and this option must be set for every transport.
+
+.conf envelope@_to@_add boolean false
+.index ::Envelope-to:: header line
+If this option is true, an ::Envelope-to:: header is added to the message. This
+gives the original address(es) in the incoming envelope that caused this
+delivery to happen. More than one address may be present if the transport is
+configured to handle several addresses at once, or if more than one original
+address was redirected to the same final address. As this is not a standard
+header, Exim has a configuration option (\envelope@_to@_remove\) which requests
+its removal from incoming messages, so that delivered messages can safely be
+resent to other recipients.
+
+.conf group string$**$ "Exim group"
+.index transport||group, specifying
+This option specifies a gid for running the transport process, overriding any
+value that the router supplies, and also overriding any value associated with
+\user\ (see below).
+
+.conf headers@_add string$**$ unset
+.index header lines||adding in transport
+.index transport||header lines, adding
+This option specifies a string of text which is expanded and added to the
+header portion of a message as it is transported. If the result of the
+expansion is an empty string, or if the expansion is forced to fail, no action
+is taken. Other expansion failures are treated as errors and cause the delivery
+to be deferred. The expanded string should be in the form of one or more RFC
+2822 header lines, separated by newlines (coded as `@\n'), for example:
+.display asis
+headers_add = X-added: this is a header added at $tod_log\n\
+ X-added: this is another
+.endd
+Exim does not check the syntax of these added header lines. They are added at
+the end of the existing header lines. If you include a blank line within the
+string, you can subvert this facility into adding text at the start of the
+message's body. This is not recommended. Additional header lines can also be
+specified by routers. See chapter ~~CHAProutergeneric and section
+~~SECTheadersaddrem.
+
+.conf headers@_only boolean false
+.index transport||header lines only
+.index message||transporting headers only
+.index header lines||transporting
+If this option is set, the message's body is not transported. It is mutually
+exclusive with \body@_only\. If it is used with the \%appendfile%\ or \%pipe%\
+transports, the settings of \message@_prefix\ and \message__suffix\ should be
+checked, since this option does not automatically suppress them.
+
+.conf headers@_remove string$**$ unset
+.index header lines||removing
+.index transport||header lines, removing
+This option is expanded; the result must consist of a colon-separated list of
+header names, not including the terminating colon, for example:
+.display asis
+headers_remove = return-receipt-to:acknowledge-to
+.endd
+Any existing headers matching those names are not included in any message that
+is transmitted by the transport.
+If the result of the expansion is an empty string, or if the expansion is
+forced to fail, no action is taken. Other expansion failures are treated as
+errors and cause the delivery to be deferred.
+
+If there are multiple instances of a header, they are all removed. However,
+added headers may have these names. Thus it is possible to replace a header by
+specifying it in \headers@_remove\ and supplying the replacement in
+\headers@_add\. Headers to be removed can also be specified by routers. See
+chapter ~~CHAProutergeneric and section ~~SECTheadersaddrem.
+
+.conf headers@_rewrite string unset
+.index transport||header lines, rewriting
+.index rewriting||at transport time
+This option allows addresses in header lines to be rewritten at transport time,
+that is, as the message is being copied to its destination. The contents of the
+option are a colon-separated list of rewriting rules. Each rule is in exactly
+the same form as one of the general rewriting rules that are applied when a
+message is received. These are described in chapter ~~CHAPrewrite. For example,
+.display asis
+headers_rewrite = a@b c@d f : \
+ x@y w@z
+.endd
+changes \a@@b\ into \c@@d\ in ::From:: header lines, and \x@@y\ into \w@@z\ in
+all address-bearing header lines. The rules are applied to the header lines
+just before they are written out at transport time, so they affect only those
+copies of the message that pass through the transport. However, only the
+message's original header lines, and any that were added by a system filter,
+are rewritten. If a router or transport adds header lines, they are
+not affected by this option. These rewriting rules are $it{not} applied to the
+envelope. You can change the return path using \return@_path\, but you cannot
+change envelope recipients at this time.
+
+.conf home@_directory string$**$ unset
+.index transport||home directory for
+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
+the current directory if no current directory is set by the
+\current__directory\ option on the transport or the
+\transport__current__directory\ option on the router.
+If the expansion fails for any reason, including forced failure, an error is
+logged, and delivery is deferred.
+
+
+.index additional groups
+.index groups, additional
+.index transport||group, additional
+.conf initgroups boolean false
+If this option is true and the uid for the delivery process is provided by the
+transport, the \*initgroups()*\ function is called when running the transport
+to ensure that any additional groups associated with the uid are set up.
+
+.conf message@_size@_limit string$**$ 0
+.index limit||message size per transport
+.index size||of message, limit
+.index transport||message size, limiting
+This option controls the size of messages passed through the transport. It is
+expanded before use; the result of the expansion must be a sequence of digits,
+optionally followed by K or M.
+If the expansion fails for any reason, including forced failure, or if the
+result is not of the required form, delivery is deferred.
+If the value is greater than zero and the size of a message exceeds this
+limit, the address is failed. If there is any chance that the resulting bounce
+message could be routed to the same transport, you should ensure that
+\return@_size@_limit\ is less than the transport's \message@_size@_limit\, as
+otherwise the bounce message will fail to get delivered.
+
+
+.conf rcpt@_include@_affixes boolean false
+.index prefix||for local part, including in envelope
+.index suffix||for local part, including in envelope
+.index local part||prefix
+.index local part||suffix
+When this option is false (the default), and an address that has had any
+affixes (prefixes or suffixes) removed from the local part is delivered by any
+form of SMTP or LMTP, the affixes are not included. For example, if a router
+that contains
+.display asis
+local_part_prefix = *-
+.endd
+routes the address \*abc-xyz@@some.domain*\ to an SMTP transport, the envelope
+is delivered with
+.display asis
+RCPT TO:<xyz@some.domain>
+.endd
+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%\
+transports.
+
+.conf retry@_use@_local@_part boolean "see below"
+.index hints database||retry keys
+When a delivery suffers a temporary failure, a retry record is created
+in Exim's hints database. For remote deliveries, the key for the retry record
+is based on the name and/or IP address of the failing remote host. For local
+deliveries, the key is normally the entire address, including both the local
+part and the domain. This is suitable for most common cases of local delivery
+temporary failure -- for example, exceeding a mailbox quota should delay only
+deliveries to that mailbox, not to the whole domain.
+
+However, in some special cases you may want to treat a temporary local delivery
+as a failure associated with the domain, and not with a particular local part.
+(For example, if you are storing all mail for some domain in files.) You can do
+this by setting \retry@_use@_local@_part\ false.
+
+For all the local transports, its default value is true. For remote transports,
+the default value is false for tidiness, but changing the value has no effect
+on a remote transport in the current implementation.
+
+.conf return@_path string$**$ unset
+.index envelope sender
+.index transport||return path, changing
+.index return path||changing in transport
+If this option is set, the string is expanded at transport time and replaces
+the existing return path (envelope sender) value in the copy of the message
+that is being delivered. An empty return path is permitted. This feature is
+designed for remote deliveries, where the value of this option is used in the
+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).
+
+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
+replacement occurs; if it fails for another reason, delivery is deferred. This
+option can be used to support VERP (Variable Envelope Return Paths) -- see
+chapter ~~CHAPSMTP.
+
+\**Note**\: If a delivery error is detected locally,
+.em
+including the case when a remote server rejects a message at SMTP time,
+the bounce message is not sent to the value of this option, but to the
+previously set errors address (which defaults to the incoming sender address).
+.nem
+
+
+.conf return@_path@_add boolean false
+.index ::Return-path:: header line
+If this option is true, a ::Return-path:: header is added to the message.
+Although the return path is normally available in the prefix line of BSD
+mailboxes, this is commonly not displayed by MUAs, and so the user does not
+have easy access to it.
+
+RFC 2821 states that the ::Return-path:: header is added to a message `when the
+delivery SMTP server makes the final delivery'. This implies that this header
+should not be present in incoming messages. Exim has a configuration option,
+\return@_path@_remove\, which requests removal of this header from incoming
+messages, so that delivered messages can safely be resent to other recipients.
+
+.conf shadow@_condition string$**$ unset
+See \shadow@_transport\ below.
+
+.conf shadow@_transport string unset
+.index shadow transport
+.index transport||shadow
+A local transport may set the \shadow@_transport\ option to the name of another
+local transport. Shadow remote transports are not supported.
+
+Whenever a delivery to the main transport succeeds, and either
+\shadow@_condition\ is unset, or its expansion does not result in the empty
+string or one of the strings `0' or `no' or `false', the message is also passed
+to the shadow transport, with the same delivery address or addresses.
+If expansion fails, no action is taken except that non-forced expansion
+failures cause a log line to be written.
+
+The result of the shadow transport is discarded and does not affect the
+subsequent processing of the message. Only a single level of shadowing is
+provided; the \shadow@_transport\ option is ignored on any transport when it is
+running as a shadow. Options concerned with output from pipes are also ignored.
+
+The log line for the successful delivery has an item added on the end, of the
+form
+.display
+ST=<<shadow transport name>>
+.endd
+If the shadow transport did not succeed, the error message is put in
+parentheses afterwards.
+
+Shadow transports can be used for a number of different purposes, including
+keeping more detailed log information than Exim normally provides, and
+implementing automatic acknowledgement policies based on message headers that
+some sites insist on.
+
+.conf transport@_filter string$**$ unset
+.index transport||filter
+.index filter||transport filter
+This option sets up a filtering (in the Unix shell sense) process for messages
+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.
+
+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 filter's standard output is read and written to the message's 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.
+
+.index SMTP||\\SIZE\\
+A problem might arise if the filter increases the size of a message that is
+being sent down an SMTP connection. If the receiving SMTP server has indicated
+support for the \\SIZE\\ parameter, Exim will have sent the size of the message
+at the start of the SMTP session. If what is actually sent is substantially
+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.
+
+The value of the option is the command string for starting up 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: Exim breaks it up
+into arguments and then expands each argument separately. The special argument
+\$pipe@_addresses$\ is replaced by a number of arguments, one for each address
+that applies to this delivery. (This isn't an ideal name for this feature here,
+but as it was already implemented for the \%pipe%\ transport, it seemed sensible
+not to change it.)
+
+.index \$host$\
+.index \$host@_address$\
+The expansion variables \$host$\ and \$host@_address$\ are available when the
+transport is a remote one. They contain the name and IP address of the host to
+which the message is being sent. For example:
+.display asis
+transport_filter = /some/directory/transport-filter.pl \
+ $host $host_address $sender_address $pipe_addresses
+.endd
+The filter process is run under the same uid and gid as the normal delivery.
+For remote deliveries this is the Exim uid/gid by default.
+
+If a transport filter is set on an autoreply transport, the original message is
+passed through the filter as it is being copied into the newly generated
+message, which happens if the \return@_message\ option is set.
+
+.conf transport@_filter@_timeout time 5m
+.index 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.
+
+
+.conf user string$**$ "Exim user"
+.index uid (user id)||local delivery
+.index transport||user, specifying
+This option specifies the user under whose uid the delivery process is to be
+run, overriding any uid that may have been set by the router. If the user is
+given as a name, the uid is looked up from the password data, and the
+associated group is taken as the value of the gid to be used if the \group\
+option is not set.
+
+.em
+For deliveries that use local transports, a user and group are normally
+specified explicitly or implicitly (for example, as a result of
+\check@_local@_user\) by the router or transport.
+.nem
+
+.index hints database||access by remote transport
+For remote transports, you should leave this option unset unless you really are
+sure you know what you are doing. When a remote transport is running, it needs
+to be able to access Exim's hints databases, because each host may have its own
+retry data.
+
+.endconf
+
+
+
+
+
+.
+.
+.
+. ============================================================================
+.chapter Address batching in local transports
+.set runningfoot "address batching"
+.rset CHAPbatching ~~chapter
+.index transport||local, address batching in
+The only remote transport (\%smtp%\) is normally configured to handle more than
+one address at a time, so that when several addresses are routed to the same
+remote host, just one copy of the message is sent. Local transports, however,
+normally handle one address at a time. That is, a separate instance of the
+transport is run for each address that is routed to the transport. A separate
+copy of the message is delivered each time.
+
+.index batched local delivery
+.index \batch@_max\
+.index \batch@_id\
+In special cases, it may be desirable to handle several addresses at once in a
+local transport, for example:
+.numberpars $.
+In an \%appendfile%\ transport, when storing messages in files for later
+delivery by some other means, a single copy of the message with multiple
+recipients saves space.
+.nextp
+In an \%lmtp%\ transport, when delivering over `local SMTP' to some process,
+a single copy saves time, and is the normal way LMTP is expected to work.
+.nextp
+In a \%pipe%\ transport, when passing the message
+to a scanner program or
+to some other delivery mechanism such as UUCP, multiple recipients may be
+acceptable.
+.endp
+The three local transports (\%appendfile%\, \%lmtp%\, and \%pipe%\) all have
+the same options for controlling multiple (`batched') deliveries, namely
+\batch@_max\ and \batch@_id\. To save repeating the information for each
+transport, these options are described here.
+
+The \batch@_max\ option specifies the maximum number of addresses that can be
+delivered together in a single run of the transport. Its default value is one.
+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:
+.numberpars $.
+If any of the transport's options contain a reference to \$local@_part$\, no
+batching is possible.
+.nextp
+If any of the transport's options contain a reference to \$domain$\, only
+addresses with the same domain are batched.
+.nextp
+.index customizing||batching condition
+If \batch@_id\ is set, it is expanded for each address, and only those
+addresses with the same expanded value are batched. This allows you to specify
+customized batching conditions.
+Failure of the expansion for any reason, including forced failure, disables
+batching, but it does not stop the delivery from taking place.
+.nextp
+Batched addresses must also have the same errors address (where to send
+delivery errors), the same header additions and removals, the same user and
+group for the transport, and if a host list is present, the first host must
+be the same.
+.endp
+.index ::Envelope-to:: header line
+If the generic \envelope@_to@_add\ option is set for the transport, the
+::Envelope-to:: header that is added to the message contains all the addresses
+that are batched together.
+
+The \%appendfile%\ and \%pipe%\ transports have an option called \use@_bsmtp\,
+which causes them to deliver the message in `batched SMTP' format, with the
+envelope represented as SMTP commands. The \check@_string\ and \escape@_string\
+options are forced to the values
+.display asis
+check_string = "."
+escape_string = ".."
+.endd
+when batched SMTP is in use. A full description of the batch SMTP mechanism is
+given in section ~~SECTbatchSMTP. The \%lmtp%\ transport does not have a
+\use@_bsmtp\ option, because it always delivers using the SMTP protocol.
+
+.index \%pipe%\ transport||with multiple 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
+the command as a separate argument. This provides a way of accessing all the
+addresses that are being delivered in the batch.
+
+If you are using a batching \%appendfile%\ transport without \use@_bsmtp\, the
+only way to preserve the recipient addresses is to set the \envelope@_to@_add\
+option. This causes an ::Envelope-to:: header line to be added to the message,
+containing all the recipients.
+
+
+
+.
+.
+.
+. ============================================================================
+.chapter The appendfile transport
+.set runningfoot "appendfile transport"
+.rset CHAPappendfile ~~chapter
+.index \%appendfile%\ transport
+.index transports||\%appendfile%\
+.index directory creation
+.index creating directories
+The \%appendfile%\ transport delivers a message by appending it to an existing
+file, or by creating an entirely new file in a specified directory. Single
+files to which messages are appended can be in the traditional Unix mailbox
+format, or optionally in the MBX format supported by the Pine MUA and
+University of Washington IMAP daemon, $it{inter alia}. When each message is
+being delivered as a separate file, `maildir' format can optionally be used to
+give added protection against failures that happen part-way through the
+delivery. A third form of separate-file delivery known as `mailstore' is also
+supported. For all file formats, Exim attempts to create as many levels of
+directory as necessary, provided that \create@_directory\ is set.
+
+The code for the optional formats is not included in the Exim binary by
+default. It is necessary to set \\SUPPORT@_MBX\\, \\SUPPORT@_MAILDIR\\ and/or
+\\SUPPORT@_MAILSTORE\\ in \(Local/Makefile)\ to have the appropriate code
+included.
+
+.index quota||system
+Exim recognises system quota errors, and generates an appropriate message. Exim
+also supports its own quota control within the transport, for use when the
+system facility is unavailable or cannot be used for some reason.
+
+If there is an error while appending to a file (for example, quota exceeded or
+partition filled), Exim attempts to reset the file's length and last
+modification time back to what they were before. If there is an error while
+creating an entirely new file, the new file is removed.
+
+Before appending to a file, a number of security checks are made, and the
+file is locked. A detailed description is given below, after the list of
+private options.
+
+\%appendfile%\ is most commonly used for local deliveries to users' mailboxes.
+However, it can also be used as a pseudo-remote transport for putting messages
+into files for remote delivery by some means other than Exim. `Batch SMTP'
+format is often used in this case (see the \use@_bsmtp\ option).
+
+
+.section The file and directory options
+.rset SECTfildiropt "~~chapter.~~section"
+The \file\ option specifies a single file, to which the message is appended;
+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.
+
+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
+Exim filter). When such a transport is running, \$local@_part$\ contains the
+local part that was aliased or forwarded, and \$address@_file$\ contains the
+name (or partial name) of the file or directory generated by the redirection
+operation. There are two cases:
+.numberpars $.
+If neither \file\ nor \directory\ is set, the redirection operation
+must specify an absolute path (one that begins with \"/"\). This is the most
+common case when users with local accounts use filtering to sort mail into
+different folders. See for example, the \%address@_file%\ transport in the
+default configuration. If the path ends with a slash, it is assumed to be the
+name of a directory. A delivery to a directory can also be forced by setting
+\maildir@_format\ or \mailstore@_format\.
+.nextp
+If \file\ or \directory\ is set for a delivery from a redirection, it is used
+to determine the file or directory name for the delivery. Normally, the
+contents of \$address@_file$\ are used in some way in the string expansion.
+.endp
+
+.index Sieve filter||configuring \%appendfile%\
+.index Sieve filter||relative mailbox path handling
+As an example of the second case, consider an environment where users do not
+have home directories. They may be permitted to use Exim filter commands of the
+form:
+.display asis
+save folder23
+.endd
+or Sieve filter commands of the form:
+.display asis
+require "fileinto";
+fileinto "folder23";
+.endd
+In this situation, the expansion of \file\ or \directory\ in the transport must
+transform the relative path into an appropriate absolute file name. In the case
+of Sieve filters, the name \*inbox*\ must be handled. It is the name that is
+used as a result of a `keep' action in the filter. This example shows one way
+of handling this requirement:
+.display asis
+file = ${if eq{$address_file}{inbox} \
+ {/var/mail/$local_part} \
+ {${if eq{${substr_0_1:$address_file}}{/} \
+ {$address_file} \
+ {$home/mail/$address_file} \
+ }} \
+ }
+.endd
+With this setting of \file\, \*inbox*\ refers to the standard mailbox location,
+absolute paths are used without change, and other folders are in the \(mail)\
+directory within the home directory.
+
+\**Note 1**\: While processing an Exim filter, a relative path such as
+\(folder23)\ is turned into an absolute path if a home directory is known to
+the router. In particular, this is the case if \check@_local@_user\ is set. If
+you want to prevent this happening at routing time, you can set
+\router@_home@_directory\ empty. This forces the router to pass the relative
+path to the transport.
+
+\**Note 2**\: An absolute path in \$address@_file$\ is not treated specially;
+the \file\ or \directory\ option is still used if it is set.
+
+
+
+.section Private options for appendfile
+.index options||\%appendfile%\ transport
+
+.startconf
+
+.conf allow@_fifo boolean false
+.index fifo (named pipe)
+.index named pipe (fifo)
+.index pipe||named (fifo)
+Setting this option permits delivery to named pipes (FIFOs) as well as to
+regular files. If no process is reading the named pipe at delivery time, the
+delivery is deferred.
+
+.conf allow@_symlink boolean false
+.index symbolic link||to mailbox
+.index mailbox||symbolic link
+By default, \%appendfile%\ will not deliver if the path name for the file is
+that of a symbolic link. Setting this option relaxes that constraint, but there
+are security issues involved in the use of symbolic links. Be sure you know
+what you are doing if you set this. Details of exactly what this option affects
+are included in the discussion which follows this list of options.
+
+.conf batch@_id string$**$ unset
+See the description of local delivery batching in chapter ~~CHAPbatching.
+However, batching is automatically disabled for \%appendfile%\ deliveries that
+happen as a result of forwarding or aliasing or other redirection directly to a
+file.
+
+.conf batch@_max integer 1
+See the description of local delivery batching in chapter ~~CHAPbatching.
+
+.conf check@_group boolean false
+When this option is set, the group owner of the file defined by the \file\
+option is checked to see that it is the same as the group under which the
+delivery process is running. The default setting is false because the default
+file mode is 0600, which means that the group is irrelevant.
+
+.conf check@_owner boolean true
+When this option is set, the owner of the file defined by the \file\ option is
+checked to ensure that it is the same as the user under which the delivery
+process is running.
+
+.conf check@_string string "see below"
+.index `From' line
+As \%appendfile%\ writes the message, the start of each line is tested for
+matching \check@_string\, and if it does, the initial matching characters are
+replaced by the contents of \escape@_string\. The value of \check@_string\ is a
+literal string, not a regular expression, and the case of any letters it
+contains is significant.
+
+If \use@_bsmtp\ is set the values of \check@_string\ and \escape@_string\ are
+forced to `.' and `..' respectively, and any settings in the configuration are
+ignored. Otherwise, they default to `From ' and `>From ' when the \file\ option
+is set, and unset when
+any of the \directory\, \maildir\, or \mailstore\ options are set.
+
+The default settings, along with \message@_prefix\ and \message@_suffix\, are
+suitable for traditional `BSD' mailboxes, where a line beginning with `From '
+indicates the start of a new message. All four options need changing if another
+format is used. For example, to deliver to mailboxes in MMDF format:
+.index MMDF format mailbox
+.index mailbox||MMDF format
+.display asis
+check_string = "\1\1\1\1\n"
+escape_string = "\1\1\1\1 \n"
+message_prefix = "\1\1\1\1\n"
+message_suffix = "\1\1\1\1\n"
+.endd
+
+.index directory creation
+.conf create@_directory boolean true
+When this option is true, Exim attempts to create any missing superior
+directories for the file that it is about to write. A created directory's mode
+is given by the \directory@_mode\ option.
+
+.conf create@_file string "anywhere"
+This option constrains the location of files and directories that are created
+by this transport. It applies to files defined by the \file\ option and
+directories defined by the \directory\ option. In the case of maildir delivery,
+it applies to the top level directory, not the maildir directories beneath.
+
+The option must be set to one of the words `anywhere', `inhome', or
+`belowhome'. In the second and third cases, a home directory must have been set
+for the transport. This option is not useful when an explicit file name is
+given for normal mailbox deliveries. It is intended for the case when file
+names are generated from users' \(.forward)\ files. These are usually handled
+by an \%appendfile%\ transport called \address@_file\. See also
+\file@_must@_exist\.
+
+.conf directory string$**$ unset
+This option is mutually exclusive with the \file\ option, but one of \file\ or
+\directory\ must be set, unless the delivery is the direct result of a
+redirection (see section ~~SECTfildiropt).
+
+When \directory\ is set, the string is expanded, and the message is delivered
+into a new file or files in or below the given directory, instead of being
+appended to a single mailbox file. A number of different formats are provided
+(see \maildir@_format\ and \mailstore@_format\), and see section ~~SECTopdir
+for further details of this form of delivery.
+
+.conf directory@_file string$**$ "$tt{q@$@{base62:@$tod@_epoch@}-@$inode}"
+.index base62
+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
+current time, in base 62 form, and the inode of the file. The variable
+\$inode$\ is available only when expanding this option.
+
+.conf directory@_mode "octal integer" 0700
+If \%appendfile%\ creates any directories as a result of the \create@_directory\
+option, their mode is specified by this option.
+
+.conf escape@_string string "see description"
+See \check@_string\ above.
+
+.conf file string$**$ unset
+This option is mutually exclusive with the \directory\ option, but one of
+\file\ or \directory\ must be set, unless the delivery is the direct result of
+a redirection (see section ~~SECTfildiropt). The \file\ option specifies a
+single file, to which the message is appended. One or more of
+\use@_fcntl@_lock\, \use@_flock@_lock\, or \use@_lockfile\ must be set with
+\file\.
+.index NFS||lock file
+.index locking files
+.index lock files
+If you are using more than one host to deliver over NFS into the same
+mailboxes, you should always use lock files.
+
+The string value is expanded for each delivery, and must yield an absolute
+path. The most common settings of this option are variations on one of these
+examples:
+.display asis
+file = /var/spool/mail/$local_part
+file = /home/$local_part/inbox
+file = $home/inbox
+.endd
+.index `sticky' bit
+In the first example, all deliveries are done into the same directory. If Exim
+is configured to use lock files (see \use@_lockfile\ below) it must be able to
+create a file in the directory, so the `sticky' bit must be turned on for
+deliveries to be possible, or alternatively the \group\ option can be used to
+run the delivery under a group id which has write access to the directory.
+
+
+.conf file@_format string unset
+.index file||mailbox, checking existing format
+This option requests the transport to check the format of an existing file
+before adding to it. The check consists of matching a specific string at the
+start of the file. The value of the option consists of an even number of
+colon-separated strings. The first of each pair is the test string, and the
+second is the name of a transport. If the transport associated with a matched
+string is not the current transport, control is passed over to the other
+transport. For example, suppose the standard \%local@_delivery%\ transport has
+this added to it:
+.display asis
+file_format = "From : local_delivery :\
+ \1\1\1\1\n : local_mmdf_delivery"
+.endd
+Mailboxes that begin with `From' are still handled by this transport, but if a
+mailbox begins with four binary ones followed by a newline, control is passed
+to a transport called \local__mmdf__delivery\, which presumably is configured
+to do the delivery in MMDF format. If a mailbox does not exist or is empty, it
+is assumed to match the current transport. If the start of a mailbox doesn't
+match any string, or if the transport named for a given string is not defined,
+delivery is deferred.
+
+.conf file@_must@_exist boolean false
+If this option is true, the file specified by the \file\ option must exist, and
+an error occurs if it does not. Otherwise, it is created if it does not exist.
+
+.conf lock@_fcntl@_timeout time 0s
+.index timeout||mailbox locking
+.index mailbox locking||blocking and non-blocking
+.index locking files
+By default, the \%appendfile%\ transport uses non-blocking calls to \*fcntl()*\
+when locking an open mailbox file. If the call fails, the delivery process
+sleeps for \lock@_interval\ and tries again, up to \lock@_retries\ times.
+Non-blocking calls are used so that the file is not kept open during the wait
+for the lock; the reason for this is to make it as safe as possible for
+deliveries over NFS in the case when processes might be accessing an NFS
+mailbox without using a lock file. This should not be done, but
+misunderstandings and hence misconfigurations are not unknown.
+
+On a busy system, however, the performance of a non-blocking lock approach is
+not as good as using a blocking lock with a timeout. In this case, the waiting
+is done inside the system call, and Exim's delivery process acquires the lock
+and can proceed as soon as the previous lock holder releases it.
+
+If \lock@_fcntl@_timeout\ is set to a non-zero time, blocking locks, with that
+timeout, are used. There may still be some retrying: the maximum number of
+retries is
+.display asis
+(lock_retries * lock_interval) / lock_fcntl_timeout
+.endd
+rounded up to the next whole number. In other words, the total time during
+which \%appendfile%\ is trying to get a lock is roughly the same, unless
+\lock@_fcntl@_timeout\ is set very large.
+
+You should consider setting this option if you are getting a lot of delayed
+local deliveries because of errors of the form
+.display asis
+failed to lock mailbox /some/file (fcntl)
+.endd
+
+.conf lock@_flock@_timeout time 0s
+This timeout applies to file locking when using \*flock()*\ (see \use@_flock\);
+the timeout operates in a similar manner to \lock@_fcntl@_timeout\.
+
+.conf lock@_interval time 3s
+This specifies the time to wait between attempts to lock the file. See below
+for details of locking.
+
+.conf lock@_retries integer 10
+This specifies the maximum number of attempts to lock the file. A value of zero
+is treated as 1. See below for details of locking.
+
+.conf lockfile@_mode "octal integer" 0600
+This specifies the mode of the created lock file, when a lock file is being
+used (see \use@_lockfile\).
+
+.conf lockfile@_timeout time 30m
+.index timeout||mailbox locking
+When a lock file is being used (see \use@_lockfile\), if a lock file already
+exists and is older than this value, it is assumed to have been left behind by
+accident, and Exim attempts to remove it.
+
+.conf maildir@_format boolean false
+.index maildir format||specifying
+If this option is set with the \directory\ option, the delivery is into a new
+file, in the `maildir' format that is used by other mail software. When the
+transport is activated directly from a \%redirect%\ router (for example, the
+\%address@_file%\ transport in the default configuration), setting
+\maildir@_format\ causes the path received from the router to be treated as a
+directory, whether or not it ends with \"/"\. This option is available only if
+\\SUPPORT@_MAILDIR\\ is present in \(Local/Makefile)\. See section
+~~SECTmaildirdelivery below for further details.
+
+.em
+.conf maildir@_quota@_directory@_regex string "See below"
+.index maildir format||quota, directories included in
+.index quota||maildir, directories included in
+This option is relevant only when \maildir@_use@_size@_file\ is set. It defines
+a regular expression for specifying directories that should be included in the
+quota calculation. The default value is
+.display asis
+maildir_quota_directory_regex = ^(?:cur|new|\..*)$
+.endd
+which includes the \(cur)\ and \(new)\ directories, and any maildir++ folders
+(directories whose names begin with a dot). If you want to exclude the
+\(Trash)\
+folder from the count (as some sites do), you need to change this setting to
+.display asis
+maildir_quota_directory_regex = ^(?:cur|new|\.(?!Trash).*)$
+.endd
+This uses a negative lookahead in the regular expression to exclude the
+directory whose name is \(.Trash)\.
+.nem
+
+.conf maildir@_retries integer 10
+This option specifies the number of times to retry when writing a file in
+`maildir' format. See section ~~SECTmaildirdelivery below.
+
+.conf maildir@_tag string$**$ unset
+This option applies only to deliveries in maildir format, and is described in
+section ~~SECTmaildirdelivery below.
+
+.conf maildir@_use@_size@_file boolean false
+.index maildir format||\(maildirsize)\ file
+Setting this option true enables support for \(maildirsize)\ files. Exim
+creates a \(maildirsize)\ file in a maildir if one does not exist, taking the
+quota from the \quota\ option of the transport. If \quota\ is unset, the value
+is zero. See section ~~SECTmaildirdelivery below for further details.
+
+.conf mailstore@_format boolean false
+.index mailstore format||specifying
+If this option is set with the \directory\ option, the delivery is into two new
+files in `mailstore' format. The option is available only if
+\\SUPPORT@_MAILSTORE\\ is present in \(Local/Makefile)\. See section
+~~SECTopdir below for further details.
+
+.conf mailstore@_prefix string$**$ unset
+This option applies only to deliveries in mailstore format, and is described in
+section ~~SECTopdir below.
+
+.conf mailstore@_suffix string$**$ unset
+This option applies only to deliveries in mailstore format, and is described in
+section ~~SECTopdir below.
+
+.conf mbx@_format boolean false
+.index locking files
+.index file||locking
+.index file||MBX format
+.index MBX format, specifying
+This option is available only if Exim has been compiled with \\SUPPORT@_MBX\\
+set in \(Local/Makefile)\. If \mbx@_format\ is set with the \file\ option,
+the message is appended to the mailbox file in MBX format instead of
+traditional Unix format. This format is supported by Pine4 and its associated
+IMAP and POP daemons, by means of the \*c-client*\ library that they all use.
+
+\**Note**\: The \message@_prefix\ and \message@_suffix\ options are not
+automatically changed by the use of \mbx@_format\. They should normally be set
+empty when using MBX format, so this option almost always appears in this
+combination:
+.display asis
+mbx_format = true
+message_prefix =
+message_suffix =
+.endd
+
+If none of the locking options are mentioned in the configuration,
+\use@_mbx@_lock\ is assumed and the other locking options default to false. It
+is possible to specify the other kinds of locking with \mbx@_format\, but
+\use@_fcntl@_lock\ and \use@_mbx@_lock\ are mutually exclusive. MBX locking
+interworks with \*c-client*\, providing for shared access to the mailbox. It
+should not be used if any program that does not use this form of locking is
+going to access the mailbox, nor should it be used if the mailbox file is NFS
+mounted, because it works only when the mailbox is accessed from a single host.
+
+If you set \use@_fcntl@_lock\ with an MBX-format mailbox, you cannot use
+the standard version of \*c-client*\, because as long as it has a mailbox open
+(this means for the whole of a Pine or IMAP session), Exim will not be able to
+append messages to it.
+
+.conf message@_prefix string$**$ "see below"
+.index `From' line
+The string specified here is expanded and output at the start of every message.
+The default is unset unless \file\ is specified and \use@_bsmtp\ is not set, in
+which case it is:
+.display asis
+message_prefix = "From ${if def:return_path{$return_path}\
+ {MAILER-DAEMON}} $tod_bsdinbox\n"
+.endd
+
+.conf message@_suffix string$**$ "see below"
+The string specified here is expanded and output at the end of every message.
+The default is unset unless \file\ is specified and \use@_bsmtp\ is not set, in
+which case it is a single newline character. The suffix can be suppressed by
+setting
+.display asis
+message_suffix =
+.endd
+
+.conf mode "octal integer" 0600
+If the output file is created, it is given this mode. If it already exists and
+has wider permissions, they are reduced to this mode. If it has narrower
+permissions, an error occurs unless \mode__fail__narrower\ is false. However,
+if the delivery is the result of a \save\ command in a filter file specifing a
+particular mode, the mode of the output file is always forced to take that
+value, and this option is ignored.
+
+.conf mode@_fail@_narrower boolean true
+This option applies in the case when an existing mailbox file has a narrower
+mode than that specified by the \mode\ option. If \mode@_fail@_narrower\ is
+true, the delivery is deferred (`mailbox has the wrong mode'); otherwise Exim
+continues with the delivery attempt, using the existing mode of the file.
+
+.conf notify@_comsat boolean false
+If this option is true, the \*comsat*\ daemon is notified after every successful
+delivery to a user mailbox. This is the daemon that notifies logged on users
+about incoming mail.
+
+.conf quota string$**$ unset
+.index quota||imposed by Exim
+This option imposes a limit on the size of the file to which Exim is appending,
+or to the total space used in the directory tree when the \directory\ option is
+set. In the latter case, computation of the space used is expensive, because
+all the files in the directory (and any sub-directories) have to be
+individually inspected and their sizes summed.
+.em
+(See \quota@_size@_regex\ and \maildir@_use@_size@_file\ for ways to avoid this
+in environments where users have no shell access to their mailboxes).
+
+As there is no interlock against two simultaneous deliveries into a
+multi-file mailbox, it is possible for the quota to be overrun in this case.
+For single-file mailboxes, of course, an interlock is a necessity.
+.nem
+
+A file's size is taken as its \*used*\ value. Because of blocking effects, this
+may be a lot less than the actual amount of disk space allocated to the file.
+If the sizes of a number of files are being added up, the rounding effect can
+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.
+
+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.
+
+.em
+\**Note**\: A value of zero is interpreted as `no quota'.
+.nem
+
+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
+during message delivery. When a mailbox is nearly full, large messages may get
+refused even though small ones are accepted, because the size of the current
+message is added to the quota when the check is made. This behaviour can be
+changed by setting \quota@_is@_inclusive\ false. When this is done, the check
+for exceeding the quota does not include the current message. Thus, deliveries
+continue until the quota has been exceeded; thereafter, no further messages are
+delivered. See also \quota@_warn@_threshold\.
+
+.conf quota@_directory string$**$ unset
+This option defines the directory to check for quota purposes when delivering
+into individual files. The default is the delivery directory, or, if a file
+called \(maildirfolder)\ exists in a maildir directory, the parent of the
+delivery directory.
+
+.conf quota@_filecount string$**$ 0
+This option applies when the \directory\ option is set. It limits the total
+number of files in the directory (compare the inode limit in system quotas). It
+can only be used if \quota\ is also set. The value is expanded; an expansion
+failure causes delivery to be deferred.
+
+.conf quota@_is@_inclusive boolean true
+See \quota\ above.
+
+.conf quota@_size@_regex string unset
+This option applies when one of the delivery modes that writes a separate file
+for each message is being used. When Exim wants to find the size of one of
+these files in order to test the quota, it first checks \quota@_size@_regex\.
+If this is set to a regular expression that matches the file name, and it
+captures one string, that string is interpreted as a representation of the
+file's size. The value of \quota@_size@_regex\ is not expanded.
+
+This feature is useful only when users have no shell access to their mailboxes
+-- otherwise they could defeat the quota simply by renaming the files. This
+facility can be used with maildir deliveries, by setting \maildir@_tag\ to add
+the file length to the file name. For example:
+.display asis
+maildir_tag = ,S=$message_size
+quota_size_regex = ,S=(\d+)
+.endd
+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.
+
+.conf quota@_warn@_message string$**$ "see below"
+See below for the use of this option. If it is not set when
+\quota@_warn@_threshold\ is set, it defaults to
+.display asis
+quota_warn_message = "\
+ To: $local_part@$domain\n\
+ Subject: Your mailbox\n\n\
+ This message is automatically created \
+ by mail delivery software.\n\n\
+ The size of your mailbox has exceeded \
+ a warning threshold that is\n\
+ set by the system administrator.\n"
+.endd
+
+.conf quota@_warn@_threshold string$**$ 0
+.index quota||warning threshold
+.index mailbox||size warning
+.index size||of mailbox
+This option is expanded in the same way as \quota\ (see above). If the
+resulting value is greater than zero, and delivery of the message causes the
+size of the file or total space in the directory tree to cross the given
+threshold, a warning message is sent. If \quota\ is also set, the threshold may
+be specified as a percentage of it by following the value with a percent sign.
+For example:
+.display asis
+quota = 10M
+quota_warn_threshold = 75%
+.endd
+If \quota\ is not set, a setting of \quota@_warn@_threshold\ that ends with a
+percent sign is ignored.
+
+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.
+
+.conf use@_bsmtp boolean false
+.index envelope sender
+If this option is set true, \%appendfile%\ writes messages in `batch SMTP'
+format, with the envelope sender and recipient(s) included as SMTP commands. If
+you want to include a leading \\HELO\\ command with such messages, you can do
+so by setting the \message@_prefix\ option. See section ~~SECTbatchSMTP for
+details of batch SMTP.
+
+.conf use@_crlf boolean false
+.index carriage return
+.index linefeed
+This option causes lines to be terminated with the two-character CRLF sequence
+(carriage return, linefeed) instead of just a linefeed character. In the case
+of batched SMTP, the byte sequence written to the file is then an exact image
+of what would be sent down a real SMTP connection.
+
+The contents of the \message@_prefix\ and \message@_suffix\ options are written
+verbatim, so must contain their own carriage return characters if these are
+needed. In cases where these options have non-empty defaults, the values end
+with a single linefeed, so they
+must
+be changed to end with \"@\r@\n"\ if \use@_crlf\ is set.
+
+.conf use@_fcntl@_lock boolean "see below"
+This option controls the use of the \*fcntl()*\ function to lock a file for
+exclusive use when a message is being appended. It is set by default unless
+\use@_flock@_lock\ is set. Otherwise, it should be turned off only if you know
+that all your MUAs use lock file locking. When both \use@_fcntl@_lock\ and
+\use@_flock@_lock\ are unset, \use@_lockfile\ must be set.
+
+.conf use@_flock@_lock boolean false
+This option is provided to support the use of \*flock()*\ for file locking, for
+the few situations where it is needed. Most modern operating systems support
+\*fcntl()*\ and \*lockf()*\ locking, and these two functions interwork with
+each other. Exim uses \*fcntl()*\ locking by default.
+
+This option is required only if you are using an operating system where
+\*flock()*\ is used by programs that access mailboxes (typically MUAs), and
+where \*flock()*\ does not correctly interwork with \*fcntl()*\. You can use
+both \*fcntl()*\ and \*flock()*\ locking simultaneously if you want.
+
+.index Solaris||\*flock()*\ support
+Not all operating systems provide \*flock()*\. Some versions of Solaris do not
+have it (and some, I think, provide a not quite right version built on top of
+\*lockf()*\). If the OS does not have \*flock()*\, Exim will be built without
+the ability to use it, and any attempt to do so will cause a configuration
+error.
+
+\**Warning**\: \*flock()*\ locks do not work on NFS files (unless \*flock()*\
+is just being mapped onto \*fcntl()*\ by the OS).
+
+.conf use@_lockfile boolean "see below"
+If this option is turned off, Exim does not attempt to create a lock file when
+appending to a mailbox file. In this situation, the only locking is by
+\*fcntl()*\. You should only turn \use@_lockfile\ off if you are absolutely
+sure that every MUA that is ever going to look at your users' mailboxes uses
+\*fcntl()*\ rather than a lock file, and even then only when you are not
+delivering over NFS from more than one host.
+
+.index NFS||lock file
+In order to append to an NFS file safely from more than one host, it is
+necessary to take out a lock $it{before} opening the file, and the lock file
+achieves this. Otherwise, even with \*fcntl()*\ locking, there is a risk of
+file corruption.
+
+The \use@_lockfile\ option is set by default unless \use@_mbx@_lock\ is set. It
+is not possible to turn both \use@_lockfile\ and \use@_fcntl@_lock\ off, except
+when \mbx@_format\ is set.
+
+.conf use@_mbx@_lock boolean "see below"
+This option is available only if Exim has been compiled with \\SUPPORT@_MBX\\
+set in \(Local/Makefile)\. Setting the option specifies that special MBX
+locking rules be used. It is set by default if \mbx@_format\ is set and none of
+the locking options are mentioned in the configuration. The locking rules are
+the same as are used by the \*c-client*\ library that underlies Pine and the
+IMAP4 and POP daemons that come with it (see the discussion below). The rules
+allow for shared access to the mailbox. However, this kind of locking does not
+work when the mailbox is NFS mounted.
+
+You can set \use@_mbx@_lock\ with either (or both) of \use@_fcntl@_lock\ and
+\use@_flock@_lock\ to control what kind of locking is used in implementing the
+MBX locking rules. The default is to use \*fcntl()*\ if \use@_mbx@_lock\ is set
+without \use@_fcntl@_lock\ or \use@_flock@_lock\.
+.endconf
+
+
+.section Operational details for appending
+.rset SECTopappend "~~chapter.~~section"
+.index appending to a file
+.index file||appending
+Before appending to a file, the following preparations are made:
+.numberpars $.
+If the name of the file is \(/dev/null)\, no action is taken, and a success
+return is given.
+.nextp
+.index directory creation
+If any directories on the file's path are missing, Exim creates them if the
+\create@_directory\ option is set. A created directory's mode is given by the
+\directory@_mode\ option.
+.nextp
+If \file@_format\ is set, the format of an existing file is checked. If this
+indicates that a different transport should be used, control is passed to that
+transport.
+.nextp
+.index file||locking
+.index locking files
+.index NFS||lock file
+If \use@_lockfile\ is set, a lock file is built in a way that will work
+reliably over NFS, as follows:
+.numberpars $.
+Create a `hitching post' file whose name is that of the lock file with the
+current time, primary host name, and process id added, by opening for writing
+as a new file. If this fails with an access error, delivery is deferred.
+.nextp
+Close the hitching post file, and hard link it to the lock file name.
+.nextp
+If the call to \*link()*\ succeeds, creation of the lock file has succeeded.
+Unlink the hitching post name.
+.nextp
+Otherwise, use \*stat()*\ to get information about the hitching post file, and
+then unlink hitching post name. If the number of links is exactly two, creation
+of the lock file succeeded but something (for example, an NFS server crash and
+restart) caused this fact not to be communicated to the \*link()*\ call.
+.nextp
+If creation of the lock file failed, wait for \lock@_interval\ and try again,
+up to \lock@_retries\ times. However, since any program that writes to a
+mailbox should complete its task very quickly, it is reasonable to time out old
+lock files that are normally the result of user agent and system crashes. If an
+existing lock file is older than \lockfile@_timeout\ Exim attempts to unlink it
+before trying again.
+.endp
+.nextp
+A call is made to \*lstat()*\ to discover whether the main file exists, and if
+so, what its characteristics are. If \*lstat()*\ fails for any reason other
+than non-existence, delivery is deferred.
+.nextp
+.index symbolic link||to mailbox
+.index mailbox||symbolic link
+If the file does exist and is a symbolic link, delivery is deferred, unless the
+\allow@_symlink\ option is set, in which case the ownership of the link is
+checked, and then \*stat()*\ is called to find out about the real file, which
+is then subjected to the checks below. The check on the top-level link
+ownership prevents one user creating a link for another's mailbox in a sticky
+directory, though allowing symbolic links in this case is definitely not a good
+idea. If there is a chain of symbolic links, the intermediate ones are not
+checked.
+.nextp
+If the file already exists but is not a regular file, or if the file's owner
+and group (if the group is being checked -- see \check@_group\ above) are
+different from the user and group under which the delivery is running,
+delivery is deferred.
+.nextp
+If the file's permissions are more generous than specified, they are reduced.
+If they are insufficient, delivery is deferred, unless \mode@_fail@_narrower\
+is set false, in which case the delivery is tried using the existing
+permissions.
+.nextp
+The file's inode number is saved, and the file is then opened for appending. If
+this fails because the file has vanished, \%appendfile%\ behaves as if it hadn't
+existed (see below). For any other failures, delivery is deferred.
+.nextp
+If the file is opened successfully, check that the inode number hasn't
+changed, that it is still a regular file, and that the owner and permissions
+have not changed. If anything is wrong, defer delivery and freeze the message.
+.nextp
+If the file did not exist originally, defer delivery if the \file@_must@_exist\
+option is set. Otherwise, check that the file is being created in a permitted
+directory if the \create@_file\ option is set (deferring on failure), and then
+open for writing as a new file, with the \\O@_EXCL\\ and \\O@_CREAT\\ options,
+except when dealing with a symbolic link (the \allow@_symlink\ option must be
+set). In this case, which can happen if the link points to a non-existent file,
+the file is opened for writing using \\O@_CREAT\\ but not \\O@_EXCL\\, because
+that prevents link following.
+.nextp
+.index loop||while file testing
+If opening fails because the file exists, obey the tests given above for
+existing files. However, to avoid looping in a situation where the file is
+being continuously created and destroyed, the exists/not-exists loop is broken
+after 10 repetitions, and the message is then frozen.
+.nextp
+If opening fails with any other error, defer delivery.
+.nextp
+.index file||locking
+.index locking files
+Once the file is open, unless both \use@_fcntl@_lock\ and \use@_flock@_lock\
+are false, it is locked using \*fcntl()*\ or \*flock()*\ or both. If
+\use@_mbx@_lock\ is false, an exclusive lock is requested in each case.
+However, if \use@_mbx@_lock\ is true,
+Exim takes out a shared lock on the open file,
+and an exclusive lock on the file whose name is
+.display
+/tmp/.<<device-number>>.<<inode-number>>
+.endd
+using the device and inode numbers of the open mailbox file, in accordance with
+the MBX locking rules.
+
+If Exim fails to lock the file, there are two possible courses of action,
+depending on the value of the locking timeout. This is obtained from
+\lock@_fcntl@_timeout\ or \lock@_flock@_timeout\, as appropriate.
+
+If the timeout value is zero, the file is closed, Exim waits for
+\lock@_interval\, and then goes back and re-opens the file as above and tries
+to lock it again. This happens up to \lock@_retries\ times, after which the
+delivery is deferred.
+
+If the timeout has a value greater than zero, blocking calls to \*fcntl()*\ or
+\*flock()*\ are used (with the given timeout), so there has already been some
+waiting involved by the time locking fails. Nevertheless, Exim does not give up
+immediately. It retries up to
+.display
+(lock@_retries * lock@_interval) / <<timeout>>
+.endd
+times (rounded up).
+.endp
+
+At the end of delivery, Exim closes the file (which releases the \*fcntl()*\
+and/or \*flock()*\ locks) and then deletes the lock file if one was created.
+
+.section Operational details for delivery to a new file
+.rset SECTopdir "~~chapter.~~section"
+.index delivery||to single file
+.index `From' line
+When the \directory\ option is set instead of \file\, each message is delivered
+into a newly-created file or set of files. When \%appendfile%\ is activated
+directly from a \%redirect%\ router, neither \file\ nor \directory\ is normally
+set, because the path for delivery is supplied by the router. (See for example,
+the \%address@_file%\ transport in the default configuration.) In this case,
+delivery is to a new file if either the path name ends in \"/"\, or the
+\maildir@_format\ or \mailstore@_format\ option is set.
+
+No locking is required while writing the message to a new file, so the various
+locking options of the transport are ignored. The `From' line that by default
+separates messages in a single file is not normally needed, nor is the escaping
+of message lines that start with `From', and there is no need to ensure a
+newline at the end of each message. Consequently, the default values for
+\check@_string\, \message@_prefix\, and \message@_suffix\ are all unset when
+any of \directory\, \maildir@_format\, or \mailstore@_format\ is set.
+
+If Exim is required to check a \quota\ setting, it adds up the sizes of all the
+files in the delivery directory by default. However, you can specify a
+different directory by setting \quota@_directory\. Also, for maildir deliveries
+(see below) the \(maildirfolder)\ convention is honoured.
+
+
+.index maildir format
+.index mailstore format
+There are three different ways in which delivery to individual files can be
+done, controlled by the settings of the \maildir@_format\ and
+\mailstore@_format\ options. Note that code to support maildir or mailstore
+formats is not included in the binary unless \\SUPPORT@_MAILDIR\\ or
+\\SUPPORT@_MAILSTORE\\, respectively, is set in \(Local/Makefile)\.
+
+.index directory creation
+In all three cases an attempt is made to create the directory and any necessary
+sub-directories if they do not exist, provided that the \create@_directory\
+option is set (the default). The location of a created directory can be
+constrained by setting \create@_file\. A created directory's mode is given by
+the \directory@_mode\ option. If creation fails, or if the \create@_directory\
+option is not set when creation is required, delivery is deferred.
+
+
+.section Maildir delivery
+.rset SECTmaildirdelivery "~~chapter.~~section"
+.index maildir format||description of
+If the \maildir@_format\ option is true, Exim delivers each message by writing
+it to a file whose name is \(tmp/<<stime>>.H<<mtime>>P<<pid>>.<<host>>)\ in the
+given directory. If the delivery is successful, the file is renamed into the
+\(new)\ subdirectory.
+
+In the file name, <<stime>> is the current time of day in seconds, and
+<<mtime>> is the microsecond fraction of the time. After a maildir delivery,
+Exim checks that the time-of-day clock has moved on by at least one microsecond
+before terminating the delivery process. This guarantees uniqueness for the
+file name. However, as a precaution, Exim calls \*stat()*\ for the file before
+opening it. If any response other than \\ENOENT\\ (does not exist) is given,
+Exim waits 2 seconds and tries again, up to \maildir@_retries\ times.
+
+.index quota||in maildir delivery
+.index maildir++
+If Exim is required to check a \quota\ setting before a maildir delivery, and
+\quota@_directory\ is not set, it looks for a file called \(maildirfolder)\ in
+the maildir directory (alongside \(new)\, \(cur)\, \(tmp)\). If this exists,
+Exim assumes the directory is a maildir++ folder directory, which is one level
+down from the user's top level mailbox directory. This causes it to start at
+the parent directory instead of the current directory when calculating the
+amount of space used.
+
+
+.section Using tags to record message sizes
+If \maildir@_tag\ is set, the string is expanded for each delivery.
+When the maildir file is renamed into the \(new)\ sub-directory, the
+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.
+
+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 `/'.
+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.
+
+
+.em
+.section Using a maildirsize file
+.index quota||in maildir delivery
+.index maildir format||\(maildirsize)\ file
+If \maildir@_use@_size@_file\ is true, Exim implements the maildir++ rules for
+storing quota and message size information in a file called \(maildirsize)\
+within the maildir directory. If this file does not exist, Exim creates it,
+setting the quota from the \quota\ option of the transport. If the maildir
+directory itself does not exist, it is created before any attempt to write a
+\(maildirsize)\ file.
+
+The \(maildirsize)\ file is used to hold information about the sizes of
+messages in the maildir, thus speeding up quota calculations. The quota value
+in the file is just a cache; if the quota is changed in the transport, the new
+value overrides the cached value when the next message is delivered. The cache
+is maintained for the benefit of other programs that access the maildir and
+need to know the quota.
+
+If the \quota\ option in the transport is unset or zero, the \(maildirsize)\
+file is maintained (with a zero quota setting), but no quota is imposed.
+
+A regular expression is available for controlling which directories in the
+maildir participate in quota calculations. See the description of the
+\maildir@_quota@_directory@_regex\ option above for details.
+.nem
+
+
+.section Mailstore delivery
+.index mailstore format||description of
+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.
+
+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
+\(.tmp)\ file is renamed as the \(.env)\ file. Programs that access messages in
+mailstore format should wait for the presence of both a \(.msg)\ and a \(.env)\
+file before accessing either of them. An alternative approach is to wait for
+the absence of a \(.tmp)\ file.
+
+The envelope file starts with any text defined by the \mailstore@_prefix\
+option, expanded and terminated by a newline if there isn't one. Then follows
+the sender address on one line, then all the recipient addresses, one per line.
+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.
+
+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.
+
+
+.section Non-special new file delivery
+If neither \maildir@_format\ nor \mailstore@_format\ is set, a single new file
+is created directly in the named directory. For example, when delivering
+messages into files in batched SMTP format for later delivery to some host (see
+section ~~SECTbatchSMTP), a setting such as
+.display asis
+directory = /var/bsmtp/$host
+.endd
+might be used. A message is written to a file with a temporary name, which is
+then renamed when the delivery is complete. The final name is obtained by
+expanding the contents of the \directory@_file\ option.
+
+
+
+
+
+.
+.
+.
+.
+. ============================================================================
+.chapter The autoreply transport
+.set runningfoot "autoreply transport"
+.index transports||\%autoreply%\
+.index \%autoreply%\ transport
+The \%autoreply%\ transport is not a true transport in that it does not cause
+the message to be transmitted. Instead, it generates another mail message. It
+is usually run as the result of mail filtering, a `vacation' message being the
+standard example. However, it can also be run directly from a router like any
+other transport. To reduce the possibility of message cascades, messages
+created by the \%autoreply%\ transport always have empty envelope sender
+addresses, like bounce messages.
+
+The parameters of the message to be sent can be specified in the configuration
+by options described below. However, these are used only when the address
+passed to the transport does not contain its own reply information. When the
+transport is run as a consequence of a
+\mail\
+or \vacation\ command in a filter file, the parameters of the message are
+supplied by the filter, and passed with the address. The transport's options
+that define the message are then ignored (so they are not usually set in this
+case). The message is specified entirely by the filter or by the transport; it
+is never built from a mixture of options. However, the \file@_optional\,
+\mode\, and \return@_message\ options apply in all cases.
+
+\%Autoreply%\ is implemented as a local transport. When used as a result of a
+command in a user's filter file, \%autoreply%\ normally runs under the uid and
+gid of the user, and with appropriate current and home directories (see chapter
+~~CHAPenvironment).
+
+There is a subtle difference between routing a message to a \%pipe%\ transport
+that generates some text to be returned to the sender, and routing it to an
+\%autoreply%\ transport. This difference is noticeable only if more than one
+address from the same message is so handled. In the case of a pipe, the
+separate outputs from the different addresses are gathered up and returned to
+the sender in a single message, whereas if \%autoreply%\ is used, a separate
+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,
+the transport defers.
+Whether characters with the top bit set count as printing characters or not is
+controlled by the \print@_topbitchars\ global option.
+
+If any of the generic options for manipulating headers (for example,
+\headers@_add\) are set on an \%autoreply%\ transport, they apply to the copy of
+the original message that is included in the generated message when
+\return@_message\ is set. They do not apply to the generated message itself.
+
+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
+is empty (because the incoming message is a bounce message) do not cause
+problems. They are just discarded.
+
+
+.section Private options for autoreply
+
+.startconf
+.index options||\%autoreply%\ transport
+.conf bcc string$**$ unset
+This specifies the addresses that are to receive `blind carbon copies' of the
+message when the message is specified by the transport.
+
+.conf cc string$**$ unset
+This specifies recipients of the message and the contents of the ::Cc:: header
+when the message is specified by the transport.
+
+.conf file string$**$ unset
+The contents of the file are sent as the body of the message when the message
+is specified by the transport. If both \file\ and \text\ are set, the text
+string comes first.
+
+.conf file@_expand boolean false
+If this is set, the contents of the file named by the \file\ option are
+subjected to string expansion as they are added to the message.
+
+.conf file@_optional boolean false
+If this option is true, no error is generated if the file named by the \file\
+option or passed with the address does not exist or cannot be read.
+
+.conf from string$**$ unset
+This specifies the contents of the ::From:: header when the message is specified
+by the transport.
+
+.conf headers string$**$ unset
+This specifies additional RFC 2822 headers that are to be added to the message when
+the message is specified by the transport. Several can be given by using `@\n'
+to separate them. There is no check on the format.
+
+.conf log string$**$ unset
+This option names a file in which a record of every message sent is logged when
+the message is specified by the transport.
+
+.conf mode "octal integer" 0600
+If either the log file or the `once' file has to be created, this mode is used.
+
+.conf once string$**$ unset
+This option names a file or DBM database in which a record of each
+::To:: recipient is kept when the message is specified by the transport.
+\**Note**\: This does not apply to ::Cc:: or ::Bcc:: recipients.
+If \once@_file@_size\ is not set, a DBM database is used, and it is allowed to
+grow as large as necessary. If a potential recipient is already in the
+database, no message is sent by default. However, if \once@_repeat\ specifies a
+time greater than zero, the message is sent if that much time has elapsed since
+a message was last sent to this recipient. If \once\ is unset, the message is
+always sent.
+
+If \once@_file@_size\ is set greater than zero, it changes the way Exim
+implements the \once\ option. Instead of using a DBM file to record every
+recipient it sends to, it uses a regular file, whose size will never get larger
+than the given value. In the file, it keeps a linear list of recipient
+addresses and times at which they were sent messages. If the file is full when
+a new address needs to be added, the oldest address is dropped. If
+\once@_repeat\ is not set, this means that a given recipient may receive
+multiple messages, but at unpredictable intervals that depend on the rate of
+turnover of addresses in the file. If \once@_repeat\ is set, it specifies a
+maximum time between repeats.
+
+.conf once@_file@_size integer 0
+See \once\ above.
+
+.conf once@_repeat time$**$ 0s
+See \once\ above.
+After expansion, the value of this option must be a valid time value.
+
+.conf reply@_to string$**$ unset
+This specifies the contents of the ::Reply-To:: header when the message is
+specified by the transport.
+
+.conf return@_message boolean false
+If this is set, a copy of the original message is returned with the new
+message, subject to the maximum size set in the \return@_size@_limit\ global
+configuration option.
+
+.conf subject string$**$ unset
+This specifies the contents of the ::Subject:: header when the message is
+specified by the transport.
+
+.conf text string$**$ unset
+This specifies a single string to be used as the body of the message when the
+message is specified by the transport. If both \text\ and \file\ are set, the
+text comes first.
+
+.conf to string$**$ unset
+This specifies recipients of the message and the contents of the ::To:: header
+when the message is specified by the transport.
+
+.endconf
+
+
+
+.
+.
+.
+.
+. ============================================================================
+.chapter The lmtp transport
+.set runningfoot "lmtp transport"
+.index transports||\%lmtp%\
+.index \%lmtp%\ transport
+.index LMTP||over a pipe
+.index LMTP||over a socket
+.rset CHAPLMTP "~~chapter"
+The \%lmtp%\ transport runs the LMTP protocol (RFC 2033) over a pipe to a
+specified command
+or by interacting with a Unix domain socket.
+This transport is something of a cross between the \%pipe%\ and \%smtp%\
+transports. Exim also has support for using LMTP over TCP/IP; this is
+implemented as an option for the \%smtp%\ transport. Because LMTP is expected
+to be of minority interest, the default build-time configure in \(src/EDITME)\
+has it commented out. You need to ensure that
+.display asis
+TRANSPORT_LMTP=yes
+.endd
+is present in your \(Local/Makefile)\ in order to have the \%lmtp%\ transport
+included in the Exim binary.
+
+The private options of the \%lmtp%\ transport are as follows:
+
+.startconf
+.index options||\%lmtp%\ transport
+
+.conf batch@_id string$**$ unset
+See the description of local delivery batching in chapter ~~CHAPbatching.
+
+.conf batch@_max integer 1
+This limits the number of addresses that can be handled in a single delivery.
+Most LMTP servers can handle several addresses at once, so it is normally a
+good idea to increase this value. See the description of local delivery
+batching in chapter ~~CHAPbatching.
+
+.conf command string$**$ 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.
+
+.conf socket string$**$ unset
+This option must be set if \command\ is not set. The result of expansion must
+be the name of a Unix domain socket. The transport connects to the socket and
+delivers the message to it using the LMTP protocol.
+
+.conf timeout time 5m
+The transport is aborted if the created process
+or Unix domain socket
+does not respond to LMTP commands or message input within this timeout.
+
+.endconf
+
+Here is an example of a typical LMTP transport:
+.display asis
+lmtp:
+ driver = lmtp
+ command = /some/local/lmtp/delivery/program
+ batch_max = 20
+ user = exim
+.endd
+This delivers up to 20 addresses at a time, in a mixture of domains if
+necessary, running as the user \*exim*\.
+
+
+
+.
+.
+.
+.
+. ============================================================================
+.chapter The pipe transport
+.rset CHAPpipetransport "~~chapter"
+.set runningfoot "pipe transport"
+.index transports||\%pipe%\
+.index \%pipe%\ transport
+The \%pipe%\ transport is used to deliver messages via a pipe to a command
+running in another process. This can happen in one of two ways:
+.numberpars $.
+A router routes an address to a transport in the normal way, and the transport
+is configured as a \%pipe%\ transport. In this case, \$local@_part$\ contains
+the address (as usual), and the command which is run is specified by the
+\command\ option on the transport. An example of this is the use of \%pipe%\ as
+a pseudo-remote transport for passing messages to some other delivery mechanism
+(such as UUCP).
+.nextp
+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.
+.endp
+
+The \%pipe%\ transport is a non-interactive delivery method. Exim can also
+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.
+
+.section Returned status and data
+.index \%pipe%\ transport||returned data
+If the command exits with a non-zero return code, the delivery is deemed to
+have failed, unless either the \ignore@_status\ option is set (in which case
+the return code is treated as zero), or the return code is one of those listed
+in the \temp@_errors\ option, which are interpreted as meaning `try again
+later'. In this case, delivery is deferred. Details of a permanent failure are
+logged, but are not included in the bounce message, which merely contains
+`local delivery failed'.
+
+If the return code is greater than 128 and the command being run is a shell
+script, it normally means that the script was terminated by a signal whose
+value is the return code minus 128.
+
+If Exim is unable to run the command (that is, if \*execve()*\ fails), the
+return code is set to 127. This is the value that a shell returns if it is
+asked to run a non-existent command. The wording for the log line suggests that
+a non-existent command may be the problem.
+
+The \return@_output\ option can affect the result of a pipe delivery. If it is
+set and the command produces any output on its standard output or standard
+error streams, the command is considered to have failed, even if it gave a zero
+return code or if \ignore@_status\ is set. The output from the command is
+included as part of the bounce message. The \return@_fail@_output\ option is
+similar, except that output is returned only when the command exits with a
+failure return code, that is, a value other than zero or a code that matches
+\temp@_errors\.
+
+
+.section How the command is run
+.rset SECThowcommandrun "~~chapter.~~section"
+.index \%pipe%\ transport||path for command
+The command line is (by default) broken down into a command name and arguments
+by the \%pipe%\ transport itself. The \allow@_commands\ and \restrict@_to@_path\
+options can be used to restrict the commands that may be run.
+.index quoting||in pipe command
+Unquoted arguments are delimited by white space. If an argument appears in
+double quotes, backslash is interpreted as an escape character in the usual
+way. If an argument appears in single quotes, no escaping is done.
+
+String expansion is applied to the command line except when it comes from a
+traditional \(.forward)\ file (commands from a filter file are expanded). The
+expansion is applied to each argument in turn rather than to the whole line.
+For this reason, any string expansion item that contains white space must be
+quoted so as to be contained within a single argument. A setting such as
+.display asis
+command = /some/path ${if eq{$local_part}{postmaster}{xxx}{yyy}}
+.endd
+will not work, because the expansion item gets split between several
+arguments. You have to write
+.display asis
+command = /some/path "${if eq{$local_part}{postmaster}{xxx}{yyy}}"
+.endd
+to ensure that it is all in one argument. The expansion is done in this way,
+argument by argument, so that the number of arguments cannot be changed as a
+result of expansion, and quotes or backslashes in inserted variables do not
+interact with external quoting.
+
+.index transport||filter
+.index filter||transport filter
+Special handling takes place when an argument consists of precisely the text
+`$tt{@$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
+transport filter command. It causes each address that is being handled to be
+inserted in the argument list at that point $it{as a separate argument}. This
+avoids any problems with spaces or shell metacharacters, and is of use when a
+\%pipe%\ transport is handling groups of addresses in a batch.
+
+After splitting up into arguments and expansion, the resulting command is run
+in a subprocess directly from the transport, $it{not} under a shell. The
+message that is being delivered is supplied on the standard input, and the
+standard output and standard error are both connected to a single pipe that is
+read by Exim. The \max@_output\ option controls how much output the command may
+produce, and the \return@_output\ and \return@_fail@_output\ options control
+what is done with it.
+
+Not running the command under a shell (by default) lessens the security risks
+in cases when a command from a user's filter file is built out of data that was
+taken from an incoming message. If a shell is required, it can of course be
+explicitly specified as the command to be run. However, there are circumstances
+where existing commands (for example, in \(.forward)\ files) expect to be run
+under a shell and cannot easily be modified. To allow for these cases, there is
+an option called \use@_shell\, which changes the way the \%pipe%\ transport
+works. Instead of breaking up the command line as just described, it expands it
+as a single string and passes the result to \(/bin/sh)\. The
+\restrict@_to@_path\ option and the \$pipe@_addresses$\ facility cannot be used
+with \use@_shell\, and the whole mechanism is inherently less secure.
+
+
+.section Environment variables
+.rset SECTpipeenv "~~chapter.~~section"
+.index \%pipe%\ transport||environment for command
+.index environment for pipe transport
+The environment variables listed below are set up when the command is invoked.
+This list is a compromise for maximum compatibility with other MTAs. Note that
+the \environment\ option can be used to add additional variables to this
+environment.
+.display flow
+.tabs 20
+DOMAIN $t $rm{the domain of the address}
+HOME $t $rm{the home directory, if set}
+HOST $t $rm{the host name when called from a router (see below)}
+LOCAL@_PART $t $rm{see below}
+LOCAL@_PART@_PREFIX $t $rm{see below}
+LOCAL@_PART@_SUFFIX $t $rm{see below}
+LOGNAME $t $rm{see below}
+MESSAGE@_ID $t $rm{the message's id}
+PATH $t $rm{as specified by the \path\ option below}
+QUALIFY@_DOMAIN $t $rm{the sender qualification domain}
+RECIPIENT $t $rm{the complete recipient address}
+SENDER $t $rm{the sender of the message (empty if a bounce)}
+SHELL $t `$tt{/bin/sh}'
+TZ $t $rm{the value of the \timezone\ option, if set}
+USER $t $rm{see below}
+.endd
+
+When a \%pipe%\ transport is called directly from (for example) an \%accept%\
+router, \\LOCAL@_PART\\ is set to the local part of the address. When it is
+called as a result of a forward or alias expansion, \\LOCAL@_PART\\ is set to
+the local part of the address that was expanded. In both cases, any affixes are
+removed from the local part, and made available in \\LOCAL@_PART@_PREFIX\\ and
+\\LOCAL@_PART@_SUFFIX\\, respectively. \\LOGNAME\\ and \\USER\\ are set to the
+same value as \\LOCAL@_PART\\ for compatibility with other MTAs.
+
+.index \\HOST\\
+\\HOST\\ is set only when a \%pipe%\ transport is called from a router that
+associates hosts with an address, typically when using \%pipe%\ as a
+pseudo-remote transport. \\HOST\\ is set to the first host name specified by
+the router.
+
+.index \\HOME\\
+If the transport's generic \home@_directory\ option is set, its value is used
+for the \\HOME\\ environment variable. Otherwise, a home directory may be set
+by the router's \transport@_home@_directory\ option, which defaults to the
+user's home directory if \check@_local@_user\ is set.
+
+.section Private options for pipe
+.index options||\%pipe%\ transport
+.startconf
+
+.conf allow@_commands "string list$**$" unset
+.index \%pipe%\ transport||permitted commands
+The string is expanded, and is then interpreted as a colon-separated list of
+permitted commands. If \restrict@_to@_path\ is not set, the only commands
+permitted are those in the \allow@_commands\ list. They need not be absolute
+paths; the \path\ option is still used for relative paths. If
+\restrict@_to@_path\ is set with \allow@_commands\, the command must either be
+in the \allow@_commands\ list, or a name without any slashes that is found on
+the path. In other words, if neither \allow@_commands\ nor \restrict@_to@_path\
+is set, there is no restriction on the command, but otherwise only commands
+that are permitted by one or the other are allowed. For example, if
+.display asis
+allow_commands = /usr/bin/vacation
+.endd
+and \restrict@_to@_path\ is not set, the only permitted command is
+\(/usr/bin/vacation)\. The \allow@_commands\ option may not be set if
+\use@_shell\ is set.
+
+.conf batch@_id string$**$ unset
+See the description of local delivery batching in chapter ~~CHAPbatching.
+
+.conf batch@_max integer 1
+This limits the number of addresses that can be handled in a single delivery.
+See the description of local delivery batching in chapter ~~CHAPbatching.
+
+.conf check@_string string unset
+As \%pipe%\ writes the message, the start of each line is tested for matching
+\check@_string\, and if it does, the initial matching characters are replaced
+by the contents of \escape@_string\, provided both are set. The value of
+\check@_string\ is a literal string, not a regular expression, and the case of
+any letters it contains is significant. When \use@_bsmtp\ is set, the contents
+of \check@_string\ and \escape@_string\ are forced to values that implement the
+SMTP escaping protocol. Any settings made in the configuration file are
+ignored.
+
+.conf command string$**$ unset
+This option need not be set when \%pipe%\ is being used to deliver to pipes
+obtained directly from address redirections. In other cases, the option must be
+set, to provide a command to be run. It need not yield an absolute path (see
+the \path\ option below). The command is split up into separate arguments by
+Exim, and each argument is separately expanded, as described in section
+~~SECThowcommandrun above.
+
+.conf environment string$**$ unset
+.index \%pipe%\ transport||environment for command
+.index environment for \%pipe%\ transport
+This option is used to add additional variables to the environment in which the
+command runs (see section ~~SECTpipeenv for the default list). Its value is a
+string which is expanded, and then interpreted as a colon-separated list of
+environment settings of the form `<<name>>=<<value>>'.
+
+.conf escape@_string string unset
+See \check@_string\ above.
+
+.conf freeze@_exec@_fail boolean false
+.index exec failure
+.index failure of exec
+.index \%pipe%\ transport||failure of exec
+Failure to exec the command in a pipe transport is by default treated like
+any other failure while running the command. However, if \freeze@_exec@_fail\
+is set, failure to exec is treated specially, and causes the message to be
+frozen, whatever the setting of \ignore@_status\.
+
+.conf ignore@_status boolean false
+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.
+
+.conf log@_defer@_output boolean false
+.index \%pipe%\ transport||logging output
+If this option is set, and the status returned by the command is
+one of the codes listed in \temp@_errors\ (that is, delivery was deferred),
+and any output was produced, the first line of it is written to the main log.
+
+.conf log@_fail@_output boolean false
+If this option is set, and the command returns any output, and also ends with a
+return code that is neither zero nor one of the return codes listed in
+\temp@_errors\ (that is, the delivery failed), the first line of output is
+written to the main log.
+
+.conf log@_output boolean false
+If this option is set and the command returns any output, the first line of
+output is written to the main log, whatever the return code.
+
+.conf max@_output integer 20K
+This specifies the maximum amount of output that the command may produce on its
+standard output and standard error file combined. If the limit is exceeded, the
+process running the command is killed. This is intended as a safety measure to
+catch runaway processes. The limit is applied independently of the settings of
+the options that control what is done with such output (for example,
+\return@_output\). Because of buffering effects, the amount of output may
+exceed the limit by a small amount before Exim notices.
+
+.conf message@_prefix string$**$ "see below"
+The string specified here is expanded and output at the start of every message.
+The default is unset if \use@_bsmtp\ is set. Otherwise it is
+.display asis
+message_prefix = \
+ From ${if def:return_path{$return_path}{MAILER-DAEMON}}\
+ ${tod_bsdinbox}\n
+.endd
+.index Cyrus
+.index \tmail\
+.index `From' line
+This is required by the commonly used \(/usr/bin/vacation)\ program.
+However, it must $it{not} be present if delivery is to the Cyrus IMAP server,
+or to the \tmail\ local delivery agent. The prefix can be suppressed by setting
+.display asis
+message_prefix =
+.endd
+
+.conf message@_suffix string$**$ "see below"
+The string specified here is expanded and output at the end of every message.
+The default is unset if \use@_bsmtp\ is set. Otherwise it is a single newline.
+The suffix can be suppressed by setting
+.display asis
+message_suffix =
+.endd
+
+.conf path string $tt{/usr/bin}
+This option specifies the string that is set up in the \\PATH\\ environment
+variable of the subprocess. If the \command\ option does not yield an absolute
+path name, the command is sought in the \\PATH\\ directories, in the usual way.
+\**Warning**\: This does not apply to a command specified as a transport
+filter.
+
+.conf pipe@_as@_creator boolean false
+.index uid (user id)||local delivery
+If the generic \user\ option is not set and this option is true, the delivery
+process is run under the uid that was in force when Exim was originally called
+to accept the message. If the group id is not otherwise set (via the generic
+\group\ option), the gid that was in force when Exim was originally called to
+accept the message is used.
+
+.conf restrict@_to@_path boolean false
+When this option is set, any command name not listed in \allow@_commands\ must
+contain no slashes. The command is searched for only in the directories listed
+in the \path\ option. This option is intended for use in the case when a pipe
+command has been generated from a user's \(.forward)\ file. This is usually
+handled by a \%pipe%\ transport called \address@_pipe\.
+
+.conf return@_fail@_output boolean false
+If this option is true, and the command produced any output and ended with a
+return code other than zero or one of the codes listed in \temp@_errors\ (that
+is, the delivery failed), the output is returned in the bounce message.
+However, if the message has a null sender (that is, it is itself a bounce
+message), output from the command is discarded.
+
+.conf return@_output boolean false
+If this option is true, and the command produced any output, the delivery is
+deemed to have failed whatever the return code from the command, and the output
+is returned in the bounce message. Otherwise, the output is just discarded.
+However, if the message has a null sender (that is, it is a bounce message),
+output from the command is always discarded, whatever the setting of this
+option.
+
+.conf temp@_errors "string list" "see below"
+.index \%pipe%\ transport||temporary failure
+This option contains either a colon-separated list of numbers, or a single
+asterisk. If \ignore@_status\ is false
+.em
+and \return@_output\ is not set,
+.nem
+and the command exits with a non-zero return code, the failure is treated as
+temporary and the delivery is deferred if the return code matches one of the
+numbers, or if the setting is a single asterisk. Otherwise, non-zero return
+codes are treated as permanent errors. The default setting contains the codes
+defined by \\EX@_TEMPFAIL\\ and \\EX@_CANTCREAT\\ in \(sysexits.h)\. If Exim is
+compiled on a system that does not define these macros, it assumes values of 75
+and 73, respectively.
+
+.conf timeout time 1h
+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.
+
+.conf umask "octal integer" 022
+This specifies the umask setting for the subprocess that runs the command.
+
+.conf use@_bsmtp boolean false
+.index envelope sender
+If this option is set true, the \%pipe%\ transport writes messages in `batch
+SMTP' format, with the envelope sender and recipient(s) included as SMTP
+commands. If you want to include a leading \\HELO\\ command with such messages,
+you can do so by setting the \message@_prefix\ option. See section
+~~SECTbatchSMTP for details of batch SMTP.
+
+.conf use@_crlf boolean false
+.index carriage return
+.index linefeed
+This option causes lines to be terminated with the two-character CRLF sequence
+(carriage return, linefeed) instead of just a linefeed character. In the case
+of batched SMTP, the byte sequence written to the pipe is then an exact image
+of what would be sent down a real SMTP connection.
+
+The contents of the \message@_prefix\ and \message@_suffix\ options are written
+verbatim, so must contain their own carriage return characters if these are
+needed. Since the default values for both \message@_prefix\ and
+\message@_suffix\ end with a single linefeed, their values
+must
+be changed to end with \"@\r@\n"\ if \use@_crlf\ is set.
+
+.conf use@_shell boolean false
+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
+where the command is expected to be run under a shell and cannot easily be
+modified. The \allow@_commands\ and \restrict@_to@_path\ options, and the
+`$tt{@$pipe@_addresses}' facility are incompatible with \use@_shell\. The
+command is expanded as a single string, and handed to \(/bin/sh)\ as data for
+its \-c-\ option.
+
+.endconf
+
+.section Using an external local delivery agent
+.index local delivery||using an external agent
+.index \*procmail*\
+.index external local delivery
+.index delivery||\*procmail*\
+.index delivery||by external agent
+The \%pipe%\ transport can be used to pass all messages that require local
+delivery to a separate local delivery agent such as \procmail\. When doing
+this, care must be taken to ensure that the pipe is run under an appropriate
+uid and gid. In some configurations one wants this to be a uid that is trusted
+by the delivery agent to supply the correct sender of the message. It may be
+necessary to recompile or reconfigure the delivery agent so that it trusts an
+appropriate user. The following is an example transport and router
+configuration for \procmail\:
+.display asis
+# transport
+procmail_pipe:
+ driver = pipe
+ command = /usr/local/bin/procmail -d $local_part
+ return_path_add
+ delivery_date_add
+ envelope_to_add
+ check_string = "From "
+ escape_string = ">From "
+ user = $local_part
+ group = mail
+.endd
+.display asis
+# router
+procmail:
+ driver = accept
+ check_local_user
+ transport = procmail_pipe
+.endd
+
+In this example, the pipe is run as the local user, but with the group set to
+\*mail*\. An alternative is to run the pipe as a specific user such as \*mail*\
+or \*exim*\, but in this case you must arrange for \procmail\ to trust that
+user to supply a correct sender address. If you do not specify either a \group\
+or a \user\ option, the pipe command is run as the local user. The home
+directory is the user's home directory by default.
+
+Note that the command that the pipe transport runs does $it{not} begin with
+.display asis
+IFS=" "
+.endd
+as shown in the \procmail\ documentation, because Exim does not by default use
+a shell to run pipe commands.
+
+.index Cyrus
+The next example shows a transport and a router for a system where local
+deliveries are handled by the Cyrus IMAP server.
+.display asis
+# transport
+local_delivery_cyrus:
+ driver = pipe
+ command = /usr/cyrus/bin/deliver \
+ -m ${substr_1:$local_part_suffix} -- $local_part
+ user = cyrus
+ group = mail
+ return_output
+ log_output
+ message_prefix =
+ message_suffix =
+.endd
+.display asis
+# router
+local_user_cyrus:
+ driver = accept
+ check_local_user
+ local_part_suffix = .*
+ transport = local_delivery_cyrus
+.endd
+Note the unsetting of \message@_prefix\ and \message@_suffix\, and the use of
+\return@_output\ to cause any text written by Cyrus to be returned to the
+sender.
+
+
+.
+.
+.
+.
+. ============================================================================
+.chapter The smtp transport
+.rset CHAPsmtptrans "~~chapter"
+.set runningfoot "smtp transport"
+.index transports||\%smtp%\
+.index \%smtp%\ transport
+The \%smtp%\ transport delivers messages over TCP/IP connections using the SMTP
+or LMTP protocol. The list of hosts to try can either be taken from the address
+that is being processed (having been set up by the router), or specified
+explicitly for the transport. Timeout and retry processing (see chapter
+~~CHAPretry) is applied to each IP address independently.
+
+.section Multiple messages on a single connection
+The sending of multiple messages over a single TCP/IP connection can arise in
+two ways:
+.numberpars $.
+If a message contains more than \max@_rcpt\ (see below) addresses that are
+routed to the same host, more than one copy of the message has to be sent to
+that host. In this situation, multiple copies may be sent in a single run of
+the \%smtp%\ transport over a single TCP/IP connection. (What Exim actually does
+when it has too many addresses to send in one message also depends on the value
+of the global \remote@_max@_parallel\ option. Details are given in section
+~~SECToutSMTPTCP.)
+.nextp
+.index hints database||remembering routing
+When a message has been successfully delivered over a TCP/IP connection, Exim
+looks in its hints database to see if there are any other messages awaiting a
+connection to the same host. If there are, a new delivery process is started
+for one of them, and the current TCP/IP connection is passed on to it. The new
+process may in turn send multiple copies and possibly create yet another
+process.
+.endp
+
+For each copy sent over the same TCP/IP connection, a sequence counter is
+incremented, and if it ever gets to the value of \connection@_max@_messages\,
+no further messages are sent over that connection.
+
+
+.section Use of the @$host variable
+.index \$host$\
+.index \$host@_address$\
+At the start of a run of the \%smtp%\ transport, the values of \$host$\ and
+\$host@_address$\ are the name and IP address of the first host on the host list
+passed by the router. However, when the transport is about to connect to a
+specific host, and while it is connected to that host, \$host$\ and
+\$host@_address$\ are set to the values for that host. These are the values
+that are in force when the \helo@_data\, \hosts@_try@_auth\, \interface\,
+\serialize@_hosts\, and the various TLS options are expanded.
+
+
+.section Private options for smtp
+The private options of the \%smtp%\ transport are as follows:
+
+.index options||\%smtp%\ transport
+.startconf
+.conf allow@_localhost boolean false
+.index local host||sending to
+.index fallback||hosts specified on transport
+When a host specified in \hosts\ or \fallback@_hosts\ (see below) turns out to
+be the local host, or is listed in \hosts@_treat@_as@_local\, delivery is
+deferred by default. However, if \allow@_localhost\ is set, Exim goes on to do
+the delivery anyway. This should be used only in special cases when the
+configuration ensures that no looping will result (for example, a differently
+configured Exim is listening on the port to which the message is sent).
+
+.conf authenticated@_sender string$**$ unset
+.index Cyrus
+When Exim has authenticated as a client, this option sets a value for the
+\\AUTH=\\ item on outgoing \\MAIL\\ commands, overriding any existing
+authenticated sender value. If the string expansion is forced to fail, the
+option is ignored. Other expansion failures cause delivery to be deferred. If
+the result of expansion is an empty string, that is also ignored.
+
+If the SMTP session is not authenticated, the expansion of
+\authenticated@_sender\ still happens (and can cause the delivery to be
+deferred if it fails), but no \\AUTH=\\ item is added to \\MAIL\\ commands.
+
+This option allows you to use the \%smtp%\ transport in LMTP mode to
+deliver mail to Cyrus IMAP and provide the proper local part as the
+`authenticated sender', via a setting such as:
+.display asis
+authenticated_sender = $local_part
+.endd
+This removes the need for IMAP subfolders to be assigned special ACLs to
+allow direct delivery to those subfolders.
+
+Because of expected uses such as that just described for Cyrus (when no
+domain is involved), there is no checking on the syntax of the provided
+value.
+
+.conf command@_timeout time 5m
+This sets a timeout for receiving a response to an SMTP command that has been
+sent out. It is also used when waiting for the initial banner line from the
+remote host. Its value must not be zero.
+
+.conf connect@_timeout time 5m
+This sets a timeout for the \*connect()*\ function, which sets up a TCP/IP call
+to a remote host. A setting of zero allows the system timeout (typically
+several minutes) to act. To have any effect, the value of this option must be
+less than the system timeout. However, it has been observed that on some
+systems there is no system timeout, which is why the default value for this
+option is 5 minutes, a value recommended by RFC 1123.
+
+.index SMTP||passed connection
+.index SMTP||multiple deliveries
+.index multiple SMTP deliveries
+.conf connection@_max@_messages integer 500
+This controls the maximum number of separate message deliveries that are sent
+over a single TCP/IP connection. If the value is zero, there is no limit.
+For testing purposes, this value can be overridden by the \-oB-\ command line
+option.
+
+.conf data@_timeout time 5m
+This sets a timeout for the transmission of each block in the data portion of
+the message. As a result, the overall timeout for a message depends on the size
+of the message. Its value must not be zero. See also \final@_timeout\.
+
+.conf delay@_after@_cutoff boolean true
+This option controls what happens when all remote IP addresses for a given
+domain have been inaccessible for so long that they have passed their retry
+cutoff times.
+
+In the default state, if the next retry time has not been reached for any of
+them, the address is bounced without trying any deliveries. In other words,
+Exim delays retrying an IP address after the final cutoff time until a new
+retry time is reached, and can therefore bounce an address without ever trying
+a delivery, when machines have been down for a long time. Some people are
+unhappy at this prospect, so...
+
+If \delay@_after@_cutoff\ is set false, Exim behaves differently. If all IP
+addresses are past their final cutoff time, Exim tries to deliver to those
+IP addresses that have not been tried since the message arrived. If there are
+none, of if they all fail, the address is bounced. In other words, it does not
+delay when a new message arrives, but immediately tries those expired IP
+addresses that haven't been tried since the message arrived. If there is a
+continuous stream of messages for the dead hosts, unsetting
+\delay@_after@_cutoff\ means that there will be many more attempts to deliver
+to them.
+
+.conf dns@_qualify@_single boolean true
+If the \hosts\ or \fallback@_hosts\ option is being used,
+and the \gethostbyname\ option is false,
+the \\RES@_DEFNAMES\\ resolver option is set. See the \qualify@_single\ option
+in chapter ~~CHAPdnslookup for more details.
+
+.conf dns@_search@_parents boolean false
+.index \search@_parents\
+If the \hosts\ or \fallback@_hosts\ option is being used, and the
+\gethostbyname\ option is false, the \\RES@_DNSRCH\\ resolver option is set.
+See the \search@_parents\ option in chapter ~~CHAPdnslookup for more details.
+
+
+.conf fallback@_hosts "string list" unset
+.index 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.
+
+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
+transport queue with its host list replaced by the fallback hosts, unless the
+address was routed via MX records and the current host was in the original MX
+list. In that situation, the fallback host list is not used.
+
+Once normal deliveries are complete, the fallback queue is delivered by
+re-running the same transports with the new host lists. If several failing
+addresses have the same fallback hosts (and \max@_rcpt\ permits it), a single
+copy of the message is sent.
+
+The resolution of the host names on the fallback list is controlled by the
+\gethostbyname\ option, as for the \hosts\ option. Fallback hosts apply
+both to cases when the host list comes with the address and when it is taken
+from \hosts\. This option provides a `use a smart host only if delivery fails'
+facility.
+
+.conf final@_timeout time 10m
+This is the timeout that applies while waiting for the response to the final
+line containing just `.' that terminates a message. Its value must not be zero.
+
+.conf gethostbyname boolean false
+If this option is true when the \hosts\ and/or \fallback@_hosts\ options are
+being used, names are looked up using \*gethostbyname()*\
+(or \*getipnodebyname()*\ when available)
+instead of using the DNS. Of course, that function may in fact use the DNS, but
+it may also consult other sources of information such as \(/etc/hosts)\.
+
+.index \\HELO\\||argument, setting
+.index \\EHLO\\||argument, setting
+.conf helo@_data string$**$ $tt{@$primary@_hostname}
+The value of this option is expanded, and used as the argument for the \\EHLO\\
+or \\HELO\\ command that starts the outgoing SMTP session.
+
+.conf hosts "string list$**$" unset
+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.
+
+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.
+
+During delivery, the hosts are tried in order, subject to their retry status,
+unless \hosts@_randomize\ is set.
+
+.conf hosts@_avoid@_esmtp "host list$**$" unset
+.index ESMTP, avoiding use of
+.index \\HELO\\||forcing use of
+.index \\EHLO\\||avoiding use of
+.index \\PIPELINING\\||avoiding the use of
+This option is for use with broken hosts that announce ESMTP facilities (for
+example, \\PIPELINING\\) and then fail to implement them properly. When a host
+matches \hosts@_avoid@_esmtp\, Exim sends \\HELO\\ rather than \\EHLO\\ at the
+start of the SMTP session. This means that it cannot use any of the ESMTP
+facilities such as \\AUTH\\, \\PIPELINING\\, \\SIZE\\, and \\STARTTLS\\.
+
+.conf hosts@_avoid@_tls "host list$**$" unset
+.index TLS||avoiding for certain hosts
+Exim will not try to start a TLS session when delivering to any host that
+matches this list. See chapter ~~CHAPTLS for details of TLS.
+
+.conf hosts@_max@_try integer 5
+.index host||maximum number to try
+.index limit||number of hosts tried
+.index limit||number of MX tried
+.index MX record||maximum tried
+This option limits the number of IP addresses that are tried for any one
+delivery
+.em
+in cases where there are temporary delivery errors.
+.nem
+Section ~~SECTvalhosmax describes in detail how the value of this option is
+used.
+
+.conf hosts@_nopass@_tls "host list$**$" unset
+.index TLS||passing connection
+.index multiple SMTP deliveries
+.index TLS||multiple message deliveries
+For any host that matches this list, a connection on which a TLS session has
+been started will not be passed to a new delivery process for sending another
+message on the same connection. See section ~~SECTmulmessam for an explanation
+of when this might be needed.
+
+.conf hosts@_override boolean false
+If this option is set and the \hosts\ option is also set, any hosts that are
+attached to the address are ignored, and instead the hosts specified by the
+\hosts\ option are always used. This option does not apply to
+\fallback@_hosts\.
+
+.conf hosts@_randomize boolean false
+.index randomized host list
+.index host||list of, randomized
+.index fallback||randomized hosts
+If this option is set, and either the list of hosts is taken from the
+\hosts\ or the \fallback@_hosts\ option, or the hosts supplied by the router
+were not obtained from MX records (this includes fallback hosts from the
+router), and were not randomizied by the router, the order of trying the hosts
+is randomized each time the transport runs. Randomizing the order of a host
+list can be used to do crude load sharing.
+
+When \hosts@_randomize\ is true, a host list may be split into groups whose
+order is separately randomized. This makes it possible to set up MX-like
+behaviour. The boundaries between groups are indicated by an item that is just
+\"+"\ in the host list. For example:
+.display asis
+hosts = host1:host2:host3:+:host4:host5
+.endd
+The order of the first three hosts and the order of the last two hosts is
+randomized for each use, but the first three always end up before the last two.
+If \hosts@_randomize\ is not set, a \"+"\ item in the list is ignored.
+
+.index authentication||required by client
+.conf hosts@_require@_auth "host list$**$" unset
+This option provides a list of servers for which authentication must succeed
+before Exim will try to transfer a message. If authentication fails for
+servers which are not in this list, Exim tries to send unauthenticated. If
+authentication fails for one of these servers, delivery is deferred. This
+temporary error is detectable in the retry rules, so it can be turned into a
+hard failure if required. See also \hosts@_try@_auth\, and chapter
+~~CHAPSMTPAUTH for details of authentication.
+
+.conf hosts@_require@_tls "host list$**$" unset
+.index TLS||requiring for certain servers
+Exim will insist on using a TLS session when delivering to any host that
+matches this list. See chapter ~~CHAPTLS for details of TLS.
+\**Note**\: This option affects outgoing mail only. To insist on TLS for
+incoming messages, use an appropriate ACL.
+
+.index authentication||optional in client
+.conf hosts@_try@_auth "host list$**$" unset
+This option provides a list of servers to which, provided they announce
+authentication support, Exim will attempt to authenticate as a client when it
+connects. If authentication fails, Exim will try to transfer the message
+unauthenticated. See also \hosts@_require@_auth\, and chapter ~~CHAPSMTPAUTH
+for details of authentication.
+
+.index bind IP address
+.index IP address||binding
+.conf interface "string list$**$" unset
+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
+expansion failure, or an empty string result causes the option to be ignored.
+Otherwise, after expansion,
+.em
+the string must be a list of IP addresses, colon-separated by default, but the
+separator can be changed in the usual way.
+.nem
+For example:
+.display asis
+interface = <; 192.168.123.123 ; 3ffe:ffff:836f::fe86:a061
+.endd
+The first interface of the correct type (IPv4 or IPv6) is used for the outgoing
+connection. If none of them are the correct type, the option is ignored. If
+\interface\ is not set, or is ignored, the system's IP functions choose which
+interface to use if the host has more than one.
+
+.conf keepalive boolean true
+.index keepalive||on outgoing connection
+This option controls the setting of \\SO@_KEEPALIVE\\ on outgoing TCP/IP socket
+connections. When set, it causes the kernel to probe idle connections
+periodically, by sending packets with `old' sequence numbers. The other end of
+the connection should send a acknowledgement if the connection is still okay or
+a reset if the connection has been aborted. The reason for doing this is that
+it has the beneficial effect of freeing up certain types of connection that can
+get stuck when the remote host is disconnected without tidying up the TCP/IP
+call properly. The keepalive mechanism takes several hours to detect
+unreachable hosts.
+
+.conf max@_rcpt integer 100
+.index \\RCPT\\||maximum number of outgoing
+This option limits the number of \\RCPT\\ commands that are sent in a single
+SMTP message transaction. Each set of addresses is treated independently, and
+so can cause parallel connections to the same host if \remote@_max@_parallel\
+permits this.
+
+.conf multi@_domain boolean true
+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
+one domain at a time. This is useful if you want to use \$domain$\ in an
+expansion for the transport, because it is set only when there is a single
+domain involved in a remote delivery.
+
+.conf port string$**$ "see below"
+.index port||sending TCP/IP
+.index TCP/IP||setting outgoing port
+This option specifies the TCP/IP port on the server to which Exim connects. If
+it begins with a digit it is taken as a port number; otherwise it is looked up
+using \*getservbyname()*\. The default value is normally `smtp', but if
+\protocol\ is set to `lmtp', the default is `lmtp'.
+If the expansion fails, or if a port number cannot be found, delivery is
+deferred.
+
+
+.conf protocol string "smtp"
+.index LMTP||over TCP/IP
+If this option is set to `lmtp' instead of `smtp', the default value for the
+\port\ option changes to `lmtp', and the transport operates the LMTP protocol
+(RFC 2033) instead of SMTP. This protocol is sometimes used for local
+deliveries into closed message stores. Exim also has support for running LMTP
+over a pipe to a local process -- see chapter ~~CHAPLMTP.
+
+.conf retry@_include@_ip@_address boolean true
+Exim normally includes both the host name and the IP address in the key it
+constructs for indexing retry data after a temporary delivery failure. This
+means that when one of several IP addresses for a host is failing, it gets
+tried periodically (controlled by the retry rules), but use of the other IP
+addresses is not affected.
+
+However, in some dialup environments hosts are assigned a different IP address
+each time they connect. In this situation the use of the IP address as part of
+the retry key leads to undesirable behaviour. Setting this option false causes
+Exim to use only the host name. This should normally be done on a separate
+instance of the \%smtp%\ transport, set up specially to handle the dialup hosts.
+
+.conf serialize@_hosts "host list$**$" unset
+.index serializing connections
+.index host||serializing connections
+Because Exim operates in a distributed manner, if several messages for the same
+host arrive at around the same time, more than one simultaneous connection to
+the remote host can occur. This is not usually a problem except when there is a
+slow link between the hosts. In that situation it may be helpful to restrict
+Exim to one connection at a time. This can be done by setting
+\serialize@_hosts\ to match the relevant hosts.
+
+.index hints database||serializing deliveries to a host
+Exim implements serialization by means of a hints database in which a record is
+written whenever a process connects to one of the restricted hosts. The record
+is deleted when the connection is completed. Obviously there is scope for
+records to get left lying around if there is a system or program crash. To
+guard against this, Exim ignores any records that are more than six hours old.
+
+If you set up this kind of serialization, you should also arrange to delete the
+relevant hints database whenever your system reboots. The names of the files
+start with \(misc)\ and they are kept in the \(spool/db)\ directory. There
+may be one or two files, depending on the type of DBM in use. The same files
+are used for ETRN serialization.
+
+.conf size@_addition integer 1024
+.index SMTP||\\SIZE\\
+.index message||size issue for transport filter
+.index size||of message
+.index transport||filter
+.index filter||transport filter
+If a remote SMTP server indicates that it supports the \\SIZE\\ option of the
+\\MAIL\\ command, Exim uses this to pass over the message size at the start of
+an SMTP transaction. It adds the value of \size@_addition\ to the value it
+sends, to allow for headers and other text that may be added during delivery by
+configuration options or in a transport filter. It may be necessary to increase
+this if a lot of text is added to messages.
+
+Alternatively, if the value of \size@_addition\ is set negative, it disables
+the use of the \\SIZE\\ option altogether.
+
+.conf tls@_certificate string$**$ unset
+.index TLS||client certificate, location of
+.index certificate||for client, location of
+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
+and address of the server during the expansion. See chapter ~~CHAPTLS for
+details of TLS.
+
+\**Note**\: This option must be set if you want Exim to use TLS when sending
+messages as a client. The global option of the same name specifies the
+certificate for Exim as a server; it is not automatically assumed that the same
+certificate should be used when Exim is operating as a client.
+
+.em
+.conf tls@_crl string$**$ unset
+.index TLS||client certificate revocation list
+.index certificate||revocation list for client
+This option specifies a certificate revocation list. The expanded value must
+be the name of a file that contains a CRL in PEM format.
+.nem
+
+.conf tls@_privatekey string$**$ unset
+.index TLS||client private key, location of
+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
+and address of the server during the expansion.
+If this option is unset, the private key is assumed to be in the same file as
+the certificate.
+See chapter ~~CHAPTLS for details of TLS.
+
+.conf tls@_require@_ciphers string$**$ unset
+.index TLS||requiring specific ciphers
+.index cipher||requiring specific
+The value of this option must be a list of permitted cipher suites, for use
+when setting up an
+.em
+outgoing encrypted connection. (There is a global option of the same name for
+controlling incoming connections.)
+.nem
+The values of \$host$\ and \$host@_address$\ are set to the name and address of
+the server during the expansion. See chapter ~~CHAPTLS for details of TLS; note
+that this option is used in different ways by OpenSSL and GnuTLS (see section
+~~SECTreqciphsslgnu).
+
+.conf tls@_tempfail@_tryclear boolean true
+When the server host is not in \hosts@_require@_tls\, and there is a problem in
+setting up a TLS session, this option determines whether or not Exim should try
+to deliver the message unencrypted. If it is set false, delivery to the
+current host is deferred; if there are other hosts, they are tried. If this
+option is set true, Exim attempts to deliver unencrypted after a 4\*xx*\
+response to \\STARTTLS\\. Also, if \\STARTTLS\\ is accepted, but the subsequent
+TLS negotiation fails, Exim closes the current connection (because it is in an
+unknown state), opens a new one to the same host, and then tries the delivery
+in clear.
+
+.conf tls@_verify@_certificates string$**$ unset
+.index TLS||server certificate verification
+.index certificate||verification of server
+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
+\tls@_verify@_certificates\ to the name of a directory containing certificate
+files. This does not work with GnuTLS; the option must be set to the name of a
+single file if you are using GnuTLS. The values of \$host$\ and
+\$host@_address$\ are set to the name and address of the server during the
+expansion of this option. See chapter ~~CHAPTLS for details of TLS.
+
+.endconf
+
+
+.section How the value of hosts@_max@_try is used
+.rset SECTvalhosmax "~~chapter.~~section"
+.index host||maximum number to try
+.index limit||hosts, maximum number tried
+The \hosts@_max@_try\ option limits the number of hosts that are tried
+for a single delivery. However, despite the term `host' in its name, the option
+actually applies to each IP address independently. In other words, a multihomed
+host is treated as several independent hosts, just as it is for retrying.
+
+Many of the larger ISPs have multiple MX records which often point to
+multihomed hosts. As a result, a list of a dozen or more IP addresses may be
+created as a result of routing one of these domains.
+
+Trying every single IP address on such a long list does not seem sensible; if
+several at the top of the list fail, it is reasonable to assume there is some
+problem that is likely to affect all of them. Roughly speaking, the value of
+\hosts@_max@_try\ is the maximum number that are tried before deferring the
+delivery. However, the logic cannot be quite that simple.
+
+Firstly, IP addresses that are skipped because their retry times have not
+arrived do not count, and in addition, addresses that are past their retry
+limits are also not counted, even when they are tried. This means that when
+some IP addresses are past their retry limits, more than the value of
+\hosts@_max@_retry\ may be tried. The reason for this behaviour is to ensure
+that all IP addresses are considered before timing out an email address.
+
+Secondly, when the \hosts@_max@_try\ limit is reached, Exim looks down the host
+list to see if there is a subsequent host with a different (higher valued) MX.
+If there is, that host is used next, and the current IP address is used but not
+counted. This behaviour helps in the case of a domain with a retry rule that
+hardly ever delays any hosts, as is now explained:
+
+Consider the case of a long list of hosts with one MX value, and a few with a
+higher MX value. If \hosts@_max@_try\ is small (the default is 5) only a few
+hosts at the top of the list are tried at first. With the default retry rule,
+which specifies increasing retry times, the higher MX hosts are eventually
+tried when those at the top of the list are skipped because they have not
+reached their retry times.
+
+However, it is common practice to put a fixed short retry time on domains for
+large ISPs, on the grounds that their servers are rarely down for very long.
+Unfortunately, these are exactly the domains that tend to resolve to long lists
+of hosts. The short retry time means that the lowest MX hosts are tried every
+time. The attempts may be in a different order because of random sorting, but
+without the special MX check mentioned about, the higher MX hosts would never
+be tried at all because the lower MX hosts are never all past their retry
+times.
+
+With the special check, Exim tries least one address from each MX value, even
+if the \hosts@_max@_try\ limit has already been reached.
+
+
+
+
+
+
+.
+.
+.
+.
+. ============================================================================
+.chapter Address rewriting
+.set runningfoot "address rewriting"
+.rset CHAPrewrite ~~chapter
+.index rewriting||addresses
+There are some circumstances in which Exim automatically rewrites domains in
+addresses. The two most common are when an address is given without a domain
+(referred to as an `unqualified address') or when an address contains an
+abbreviated domain that is expanded by DNS lookup.
+
+Unqualified envelope addresses are accepted only for locally submitted
+messages, or messages from hosts that match \sender@_unqualified@_hosts\ or
+\recipient@_unqualified@_hosts\, respectively. Unqualified addresses in header
+lines are qualified if they are in locally submitted messages, or messages from
+hosts that are permitted to send unqualified envelope addresses. Otherwise,
+unqualified addresses in header lines are neither qualified nor rewritten.
+
+One situation in which Exim does $it{not} automatically rewrite a domain is
+when it is the name of a CNAME record in the DNS. The older RFCs suggest that
+such a domain should be rewritten using the `canonical' name, and some MTAs do
+this. The new RFCs do not contain this suggestion.
+
+.section Explicitly configured address rewriting
+This chapter describes the rewriting rules that can be used in the
+main rewrite section of the configuration file, and also in the generic
+\headers@_rewrite\ option that can be set on any transport.
+
+Some people believe that configured address rewriting is a Mortal Sin.
+Others believe that life is not possible without it. Exim provides the
+facility; you do not have to use it.
+
+.em
+The main rewriting rules that appear in the `rewrite' section of the
+configuration file are applied to addresses in incoming messages, both envelope
+addresses and addresses in header lines. Each rule specifies the types of
+address to which it applies.
+.nem
+
+Rewriting of addresses in header lines applies only to those headers that
+were received with the message, and, in the case of transport rewriting, those
+that were added by a system filter. That is, it applies only to those headers
+that are common to all copies of the message. Header lines that are added by
+individual routers or transports (and which are therefore specific to
+individual recipient addresses) are not rewritten.
+
+In general, rewriting addresses from your own system or domain has some
+legitimacy. Rewriting other addresses should be done only with great care and
+in special circumstances. The author of Exim believes that rewriting should be
+used sparingly, and mainly for `regularizing' addresses in your own domains.
+Although it can sometimes be used as a routing tool, this is very strongly
+discouraged.
+
+There are two commonly encountered circumstances where rewriting is used, as
+illustrated by these examples:
+.numberpars $.
+The company whose domain is \*hitch.fict.example*\ has a number of hosts that
+exchange mail with each other behind a firewall, but there is only a single
+gateway to the outer world. The gateway rewrites \*@*.hitch.fict.example*\ as
+\*hitch.fict.example*\ when sending mail off-site.
+.nextp
+A host rewrites the local parts of its own users so that, for example,
+\*fp42@@hitch.fict.example*\ becomes \*Ford.Prefect@@hitch.fict.example*\.
+.endp
+
+.em
+.section When does rewriting happen?
+.index rewriting||timing of
+.index ~~ACL||rewriting addresses in
+Configured address rewriting can take place at several different stages of a
+message's processing.
+
+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
+is verified in the ACL, it is rewritten before verification, and remains
+rewritten thereafter. The subsequent value of \$sender@_address$\ is the
+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.
+
+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
+from the sender address when a recipient is verified. The address is rewritten
+for the verification, but the rewriting is not remembered at this stage. The
+value of \$local@_part$\ and \$domain$\ after verification are always the same
+as they were before (that is, they contain the unrewritten -- except for
+SMTP-time rewriting -- address).
+
+Once a message's header lines have been received, all the envelope recipient
+addresses are permanently rewritten, and rewriting is also applied to the
+addresses in the header lines (if configured).
+.index \*local@_scan()*\ function||address rewriting, timing of
+Thus, all the rewriting is completed before the \\DATA\\ ACL and
+\*local@_scan()*\ functions are run.
+
+When an address is being routed, either for delivery or for verification,
+rewriting is applied immediately to child addresses that are generated by
+redirection, unless \no@_rewrite\ is set on the router.
+.nem
+
+.index envelope sender, rewriting
+.index rewriting||at transport time
+At transport time, additional rewriting of addresses in header lines can be
+specified by setting the generic \headers@_rewrite\ option on a transport. This
+option contains rules that are identical in form to those in the rewrite
+section of the configuration file. In addition, the outgoing envelope sender
+can be rewritten by means of the \return@_path\ transport option. However, it
+is not possible to rewrite envelope recipients at transport time.
+
+
+
+.section Testing the rewriting rules that apply on input
+.index rewriting||testing
+.index testing||rewriting
+Exim's input rewriting configuration appears in a part of the run time
+configuration file headed by `begin rewrite'. It can be tested by the \-brw-\
+command line option. This takes an address (which can be a full RFC 2822
+address) as its argument. The output is a list of how the address would be
+transformed by the rewriting rules for each of the different places it might
+appear in an incoming message, that is, for each different header and for the
+envelope sender and recipient fields. For example,
+.display asis
+exim -brw ph10@exim.workshop.example
+.endd
+might produce the output
+.display asis
+ sender: Philip.Hazel@exim.workshop.example
+ from: Philip.Hazel@exim.workshop.example
+ to: ph10@exim.workshop.example
+ cc: ph10@exim.workshop.example
+ bcc: ph10@exim.workshop.example
+reply-to: Philip.Hazel@exim.workshop.example
+env-from: Philip.Hazel@exim.workshop.example
+ env-to: ph10@exim.workshop.example
+.endd
+which shows that rewriting has been set up for that address when used in any of
+the source fields, but not when it appears as a recipient address. At the
+present time, there is no equivalent way of testing rewriting rules that are
+set for a particular transport.
+
+.section Rewriting rules
+.index rewriting||rules
+The rewrite section of the configuration file consists of lines of rewriting
+rules in the form
+.display
+<<source pattern>> <<replacement>> <<flags>>
+.endd
+Rewriting rules that are specified for the \headers@_rewrite\ generic transport
+option are given as a colon-separated list. Each item in the list takes the
+same form as a line in the main rewriting configuration
+(except that any colons must be doubled, of course).
+
+The formats of source patterns and replacement strings are described below.
+Each is terminated by white space, unless enclosed in double quotes, in which
+case normal quoting conventions apply inside the quotes. The flags are single
+characters which may appear in any order. Spaces and tabs between them are
+ignored.
+
+For each address that could potentially be rewritten, the rules are scanned in
+order, and replacements for the address from earlier rules can themselves be
+replaced by later rules (but see the `q' and `R' flags).
+
+The order in which addresses are rewritten is undefined, may change between
+releases, and must not be relied on, with one exception: when a message is
+received, the envelope sender is always rewritten first, before any header
+lines are rewritten. For example, the replacement string for a rewrite of an
+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.
+
+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
+.display asis
+*@* ${lookup ...
+.endd
+where the lookup key uses \$1$\ and \$2$\ or \$local@_part$\ and \$domain$\ to
+refer to the address that is being rewritten.
+
+.section Rewriting patterns
+.index rewriting||patterns
+.index 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.
+
+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
+can use a regular expression that starts with \"^(?i)"\.
+
+.index numerical variables (\$1$\, \$2$\, etc)||in rewriting rules
+After matching, the numerical variables \$1$\, \$2$\, etc. may be set,
+depending on the type of match which occurred. These can be used in the
+replacement string to insert portions of the incoming address. \$0$\ always
+refers to the complete incoming address. When a regular expression is used, the
+numerical variables are set from its capturing subexpressions. For other types
+of pattern they are set as follows:
+
+.numberpars $.
+If a local part or domain starts with an asterisk, the numerical variables
+refer to the character strings matched by asterisks, with \$1$\ associated with
+the first asterisk, and \$2$\ with the second, if present. For example, if the
+pattern
+.display
+*queen@@*.fict.example
+.endd
+is matched against the address \*hearts-queen@@wonderland.fict.example*\ then
+.display asis
+$0 = hearts-queen@wonderland.fict.example
+$1 = hearts-
+$2 = wonderland
+.endd
+Note that if the local part does not start with an asterisk, but the domain
+does, it is \$1$\ that contains the wild part of the domain.
+.nextp
+If the domain part of the pattern is a partial lookup, the wild and fixed parts
+of the domain are placed in the next available numerical variables. Suppose,
+for example, that the address \*foo@@bar.baz.example*\ is processed by a
+rewriting rule of the form
+.display
+*@@partial-dbm;/some/dbm/file <<replacement string>>
+.endd
+and the key in the file that matches the domain is \"*.baz.example"\. Then
+.display asis
+$1 = foo
+$2 = bar
+$3 = baz.example
+.endd
+If the address \*foo@@baz.example*\ is looked up, this matches the same
+wildcard file entry, and in this case \$2$\ is set to the empty string, but
+\$3$\ is still set to \*baz.example*\. If a non-wild key is matched in a
+partial lookup, \$2$\ is again set to the empty string and \$3$\ is set to the
+whole domain. For non-partial domain lookups, no numerical variables are set.
+.endp
+
+.section Rewriting replacements
+.index rewriting||replacements
+If the replacement string for a rule is a single asterisk, addresses that
+match the pattern and the flags are $it{not} rewritten, and no subsequent
+rewriting rules are scanned. For example,
+.display asis
+hatta@lookingglass.fict.example * f
+.endd
+specifies that \*hatta@@lookingglass.fict.example*\ is never to be rewritten in
+::From:: headers.
+
+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.
+Any letters they contain retain their original case -- they are not lower
+cased. The numerical variables are set up according to the type of pattern that
+matched the address, as described above. If the expansion is forced to fail by
+the presence of `fail' in a conditional or lookup item, rewriting by the
+current rule is abandoned, but subsequent rules may take effect. Any other
+expansion failure causes the entire rewriting operation to be abandoned, and an
+entry written to the panic log.
+
+
+.section Rewriting flags
+There are three different kinds of flag that may appear on rewriting rules:
+.numberpars $.
+Flags that specify which headers and envelope addresses to rewrite: E, F, T, b,
+c, f, h, r, s, t.
+.nextp
+A flag that specifies rewriting at SMTP time: S.
+.nextp
+Flags that control the rewriting process: Q, q, R, w.
+.endp
+For rules that are part of the \headers@_rewrite\ generic transport option,
+E, F, T, and S are not permitted.
+
+
+.section Flags specifying which headers and envelope addresses to rewrite
+.index rewriting||flags
+If none of the following flag letters, nor the `S' flag (see section
+~~SECTrewriteS) are present, a main rewriting rule applies to all headers and
+to both the sender and recipient fields of the envelope, whereas a
+transport-time rewriting rule just applies to all headers. Otherwise, the
+rewriting rule is skipped unless the relevant addresses are being processed.
+.display
+E $rm{rewrite all envelope fields}
+F $rm{rewrite the envelope From field}
+T $rm{rewrite the envelope To field}
+b $rm{rewrite the ::Bcc:: header}
+c $rm{rewrite the ::Cc:: header}
+f $rm{rewrite the ::From:: header}
+h $rm{rewrite all headers}
+r $rm{rewrite the ::Reply-To:: header}
+s $rm{rewrite the ::Sender:: header}
+t $rm{rewrite the ::To:: header}
+.endd
+You should be particularly careful about rewriting ::Sender:: headers, and
+restrict this to special known cases in your own domains.
+
+.section The SMTP-time rewriting flag
+.rset SECTrewriteS "~~chapter.~~section"
+.index SMTP||rewriting malformed addresses
+.index \\RCPT\\||rewriting argument of
+.index \\MAIL\\||rewriting argument of
+The rewrite flag `S' specifies a rewrite of incoming envelope addresses at SMTP
+time, as soon as an address is received in a \\MAIL\\ or \\RCPT\\ command, and
+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.
+
+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,
+the variables \$local@_part$\ and \$domain$\ are not available during the
+expansion of the replacement string. The result of rewriting replaces the
+original address in the \\MAIL\\ or \\RCPT\\ command.
+
+.section Flags controlling the rewriting process
+There are four flags which control the way the rewriting process works. These
+take effect only when a rule is invoked, that is, when the address is of the
+correct type (matches the flags) and matches the pattern:
+.numberpars $.
+If the `Q' flag is set on a rule, the rewritten address is permitted to be an
+unqualified local part. It is qualified with \qualify@_recipient\. In the
+absence of `Q' the rewritten address must always include a domain.
+.nextp
+If the `q' flag is set on a rule, no further rewriting rules are considered,
+even if no rewriting actually takes place because of a `fail' in the expansion.
+The `q' flag is not effective if the address is of the wrong type (does not
+match the flags) or does not match the pattern.
+.nextp
+The `R' flag causes a successful rewriting rule to be re-applied to the new
+address, up to ten times. It can be combined with the `q' flag, to stop
+rewriting once it fails to match (after at least one successful rewrite).
+.nextp
+.index rewriting||whole addresses
+When an address in a header is rewritten, the rewriting normally applies only
+to the working part of the address, with any comments and RFC 2822 `phrase'
+left unchanged. For example, rewriting might change
+.display asis
+From: Ford Prefect <fp42@restaurant.hitch.fict.example>
+.endd
+into
+.display asis
+From: Ford Prefect <prefectf@hitch.fict.example>
+.endd
+Sometimes there is a need to replace the whole address item, and this can be
+done by adding the flag letter `w' to a rule. If this is set on a rule that
+causes an address in a header line to be rewritten, the entire address is
+replaced, not just the working part. The replacement must be a complete RFC
+2822 address, including the angle brackets if necessary. If text outside angle
+brackets contains a character whose value is greater than 126 or less than 32
+(except for tab), the text is encoded according to RFC 2047.
+The character set is taken from \headers@_charset\, which defaults to
+ISO-8859-1.
+
+When the `w' flag is set on a rule that causes an envelope address to be
+rewritten, all but the working part of the replacement address is discarded.
+.endp
+
+.section Rewriting examples
+Here is an example of the two common rewriting paradigms:
+.display asis
+*@*.hitch.fict.example $1@hitch.fict.example
+*@hitch.fict.example ${lookup{$1}dbm{/etc/realnames}\
+ {$value}fail}@hitch.fict.example bctfrF
+.endd
+Note the use of `fail' in the lookup expansion in the second rule, forcing
+the string expansion to fail if the lookup does not succeed. In this context it
+has the effect of leaving the original address unchanged, but Exim goes on to
+consider subsequent rewriting rules, if any, because the `q' flag is not
+present in that rule. An alternative to `fail' would be to supply \$1$\
+explicitly, which would cause the rewritten address to be the same as before,
+at the cost of a small bit of processing. Not supplying either of these is an
+error, since the rewritten address would then contain no local part.
+
+The first example above replaces the domain with a superior, more general
+domain. This may not be desirable for certain local parts. If the rule
+.display asis
+root@*.hitch.fict.example *
+.endd
+were inserted before the first rule, rewriting would be suppressed for the
+local part \*root*\ at any domain ending in \*hitch.fict.example*\.
+
+Rewriting can be made conditional on a number of tests, by making use of
+\${if$\ in the expansion item. For example, to apply a rewriting rule only to
+messages that originate outside the local host:
+.display asis
+*@*.hitch.fict.example "${if !eq {$sender_host_address}{}\
+ {$1@hitch.fict.example}fail}"
+.endd
+The replacement string is quoted in this example because it contains white
+space.
+
+.index rewriting||bang paths
+.index bang paths||rewriting
+Exim does not handle addresses in the form of `bang paths'. If it sees such an
+address it treats it as an unqualified local part which it qualifies with the
+local qualification domain (if the source of the message is local or if the
+remote host is permitted to send unqualified addresses). Rewriting can
+sometimes be used to handle simple bang paths with a fixed number of
+components. For example, the rule
+.display asis
+\N^([^!]+)!(.*)@your.domain.example$\N $2@$1
+.endd
+rewrites a two-component bang path \*host.name!user*\ as the domain address
+\*user@@host.name*\. However, there is a security implication in using this as
+a global rewriting rule for envelope addresses. It can provide a backdoor
+method for using your system as a relay, because the incoming addresses appear
+to be local. If the bang path addresses are received via SMTP, it is safer to
+use the `S' flag to rewrite them as they are received, so that relay checking
+can be done on the rewritten addresses.
+
+
+
+
+
+.
+.
+.
+.
+. ============================================================================
+.chapter Retry configuration
+.set runningfoot "retry configuration"
+.rset CHAPretry ~~chapter
+.index retry||configuration, description of
+.index configuration file||retry section
+The `retry' section of the run time configuration file contains a list of retry
+rules which control how often Exim tries to deliver messages that cannot be
+delivered at the first attempt. If there are no retry rules, temporary errors
+are treated as permanent. The \-brt-\ command line option can be used to test
+which retry rule will be used for a given address or domain.
+
+The most common cause of retries is temporary failure to deliver to a remote
+host because the host is down, or inaccessible because of a network problem.
+Exim's retry processing in this case is applied on a per-host (strictly, per IP
+address) basis, not on a per-message basis. Thus, if one message has recently
+been delayed, delivery of a new message to the same host is not immediately
+tried, but waits for the host's retry time to arrive. If the \retry@_defer\ log
+selector is set, the message
+.index retry||time not reached
+`retry time not reached' is written to the main log whenever a delivery is
+skipped for this reason. Section ~~SECToutSMTPerr contains more details of the
+handling of errors during remote deliveries.
+
+Retry processing applies to routing as well as to delivering, except as covered
+in the next paragraph. The retry rules do not distinguish between these
+actions. It is not possible, for example, to specify different behaviour for
+failures to route the domain \*snark.fict.example*\ and failures to deliver to
+the host \*snark.fict.example*\. I didn't think anyone would ever need this
+added complication, so did not implement it. However, although they share the
+same retry rule, the actual retry times for routing and transporting a given
+domain are maintained independently.
+
+When a delivery is not part of a queue run (typically an immediate delivery on
+receipt of a message), the routers are always run, and local deliveries are
+always attempted, even if retry times are set for them. This makes for better
+behaviour if one particular message is causing problems (for example, causing
+quota overflow, or provoking an error in a filter file). If such a delivery
+suffers a temporary failure, the retry data is updated as normal, and
+subsequent delivery attempts from queue runs occur only when the retry time for
+the local address is reached.
+
+
+.section Retry rules
+.index retry||rules
+Each retry rule occupies one line and consists of three parts, separated by
+white space: a pattern, an error name, and a list of retry parameters. The
+pattern must be enclosed in double quotes if it contains white space. The rules
+are searched in order until one is found whose pattern matches the failing host
+or address.
+
+The pattern is any single item that may appear in an address list (see section
+~~SECTaddresslist). It is in fact processed as a one-item address list, which
+means that it is expanded before being tested against the address that has
+been delayed. Address list processing treats a plain domain name as if it were
+preceded by `*@@', which makes it possible for many retry rules to start with
+just a domain. For example,
+.display asis
+lookingglass.fict.example * F,24h,30m;
+.endd
+provides a rule for any address in the \*lookingglass.fict.example*\ domain,
+whereas
+.display asis
+alice@lookingglass.fict.example * F,24h,30m;
+.endd
+applies only to temporary failures involving the local part \alice\.
+In practice, almost all rules start with a domain name pattern without a local
+part.
+
+.index regular expressions||in retry rules
+\**Warning**\: If you use a regular expression in a routing rule, it must match
+a complete address, not just a domain, because that is how regular expressions
+work in address lists.
+.display
+^@\Nxyz@\d+@\.abc@\.example@$@\N * G,1h,10m,2 \Wrong\
+^@\N[^@@]+@@xyz@\d+@\.abc@\.example@$@\N * G,1h,10m,2 \Right\
+.endd
+
+
+.section Choosing which retry rule to use
+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
+router. Otherwise, only the domain is used, except when matching against a
+regular expression, when the local part of the address is replaced with `*'. A
+domain on its own can match a domain pattern, or a pattern that starts with
+`*@@'. By default, \retry@_use@_local@_part\ is true for routers where
+\check@_local@_user\ is true, and false for other routers.
+
+Similarly, when Exim is looking for a retry rule after a local delivery has
+failed (for example, after a mailbox full error), each line in the retry
+configuration is tested against the complete address only if
+\retry@_use@_local@_part\ is set for the transport (it defaults true for all
+local transports).
+
+.em
+When Exim is looking for a retry rule after a remote delivery attempt has
+failed, what happens depends on the type of failure. After a 4\*xx*\ SMTP
+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,
+.nem
+(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
+.display asis
+a.b.c.example MX 5 x.y.z.example
+ MX 6 p.q.r.example
+ MX 7 m.n.o.example
+.endd
+and the retry rules are
+.display asis
+p.q.r.example * F,24h,30m;
+a.b.c.example * F,4d,45m;
+.endd
+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.
+
+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
+\*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.
+
+.section Retry rules for specific errors
+.index retry||specific errors, specifying
+The second field in a retry rule is the name of a particular error, or an
+asterisk, which matches any error. The errors that can be tested for are:
+.numberpars " "
+\*auth@_failed*\: authentication failed when trying to send to a host in the
+\hosts@_require@_auth\ list in an \%smtp%\ transport
+.nextp
+\*refused@_MX*\: connection refused from a host obtained from an MX record
+.nextp
+\*refused@_A*\: connection refused from a host not obtained from an MX record
+.nextp
+\*refused*\: any connection refusal
+.nextp
+\*timeout@_connect@_MX*\: connection timeout from a host obtained from an MX
+record
+.nextp
+\*timeout@_connect@_A*\: connection timeout from a host not obtained from an MX
+record
+.nextp
+\*timeout@_connect*\: any connection timeout
+.nextp
+\*timeout@_MX*\: any timeout from a host obtained from an MX
+record
+.nextp
+\*timeout@_A*\: any timeout from a host not obtained from an MX
+record
+.nextp
+\*timeout*\: any timeout
+.nextp
+\*quota*\: quota exceeded in local delivery by \%appendfile%\
+.nextp
+.index quota||error testing in retry rule
+.index retry||quota error testing
+\*quota@_*\<<time>>: quota exceeded in local delivery, and the mailbox has not
+been read for <<time>>. For example, \*quota@_4d*\ applies to a quota error
+when the mailbox has not been read for four days.
+
+.em
+.index mailbox||time of last read
+\**Warning**\: It is not always possible to determine a `time of last read' for
+a mailbox:
+.numberpars $.
+If the mailbox is a single file, the time of last access is used.
+.nextp
+.index maildir format||time of last read
+For a maildir delivery, the time of last modification of the \(new)\
+subdirectory is used. As the mailbox is over quota, no new files will be
+created in the \(new)\ subdirectory, so any change is assumed to be the result
+of an MUA moving a new message to the \(cur)\ directory when it is first read.
+.nextp
+For other kinds of multi-file delivery, the time of last read cannot be
+obtained, and so a retry rule that uses this type of error field is never
+matched.
+.endp
+.nem
+.endp
+The quota errors apply both to system-enforced quotas and to Exim's own quota
+mechanism in the \%appendfile%\ transport. The \*quota*\ error also applies
+when a local delivery is deferred because a partition is full (the \\ENOSPC\\
+error).
+
+
+.section Retry rule parameters
+.index retry||parameters in rules
+The third field in a retry rule is a sequence of retry parameter sets,
+separated by semicolons. Each set consists of
+.display
+<<letter>>,<<cutoff time>>,<<arguments>>
+.endd
+The letter identifies the algorithm for computing a new retry time; the cutoff
+time is the time beyond which this algorithm no longer applies, and the
+arguments vary the algorithm's action. The cutoff time is measured from the
+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.
+.index retry||algorithms
+The available algorithms are:
+.numberpars $.
+\*F*\: retry at fixed intervals. There is a single time parameter specifying the
+interval.
+.nextp
+\*G*\: retry at geometrically increasing intervals. The first argument 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.
+.endp
+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
+case of fixed interval retries, this simply means adding the interval to the
+current time. For geometrically increasing intervals, retry intervals are
+computed from the rule's parameters until one that is greater than the previous
+interval is found. The main configuration variable
+.index limit||retry interval
+.index retry||interval, maximum
+.index \retry@_interval@_max\
+\retry@_interval@_max\ limits the maximum interval between retries.
+
+A single remote domain may have a number of hosts associated with it, and each
+host may have more than one IP address. Retry algorithms are selected on the
+basis of the domain name, but are applied to each IP address independently. If,
+for example, a host has two IP addresses and one is unusable, Exim will
+generate retry times for it and will not try to use it until its next retry
+time comes. Thus the good IP address is likely to be tried first most of the
+time.
+
+.index hints database||use for retrying
+Retry times are hints rather than promises. Exim does not make any attempt to
+run deliveries exactly at the computed times. Instead, a queue runner process
+starts delivery processes for delayed messages periodically, and these attempt
+new deliveries only for those addresses that have passed their next retry time.
+If a new message arrives for a deferred address, an immediate delivery attempt
+occurs only if the address has passed its retry time. In the absence of new
+messages, the minimum time between retries is the interval between queue runner
+processes. There is not much point in setting retry times of five minutes if
+your queue runners happen only once an hour, unless there are a significant
+number of incoming messages (which might be the case on a system that is
+sending everything to a smart host, for example).
+
+The data in the retry hints database can be inspected by using the
+\*exim@_dumpdb*\ or \*exim@_fixdb*\ utility programs (see chapter ~~CHAPutils). The
+latter utility can also be used to change the data. The \*exinext*\ utility
+script can be used to find out what the next retry times are for the hosts
+associated with a particular mail domain, and also for local deliveries that
+have been deferred.
+
+.section Retry rule examples
+Here are some example retry rules:
+.display asis
+alice@wonderland.fict.example quota_5d F,7d,3h
+wonderland.fict.example quota_5d
+wonderland.fict.example * F,1h,15m; G,2d,1h,2;
+lookingglass.fict.example * F,24h,30m;
+* refused_A F,2h,20m;
+* * F,2h,15m; G,16h,1h,1.5; F,5d,8h
+.endd
+The first rule sets up special handling for mail to
+\*alice@@wonderland.fict.example*\ when there is an over-quota error and the
+mailbox has not been read for at least 5 days. Retries continue every three
+hours for 7 days. The second rule handles over-quota errors for all other local
+parts at \*wonderland.fict.example*\; the absence of a local part has the same
+effect as supplying `$*$@@'. As no retry algorithms are supplied, messages that
+fail are bounced immediately if the mailbox has not been read for at least 5
+days.
+
+The third rule handles all other errors at \*wonderland.fict.example*\; retries
+happen every 15 minutes for an hour, then with geometrically increasing
+intervals until two days have passed since a delivery first failed. After the
+first hour there is a delay of one hour, then two hours, then four hours, and
+so on (this is a rather extreme example).
+
+The fourth rule controls retries for the domain \*lookingglass.fict.example*\.
+They happen every 30 minutes for 24 hours only. The remaining two rules handle
+all other domains, with special action for connection refusal from hosts that
+were not obtained from an MX record.
+
+The final rule in a retry configuration should always have asterisks in the
+first two fields so as to provide a general catch-all for any addresses that do
+not have their own special handling. This example tries every 15 minutes for 2
+hours, then with intervals starting at one hour and increasing by a factor of
+1.5 up to 16 hours, then every 8 hours up to 5 days.
+
+
+.section Timeout of retry data
+.index timeout||of retry data
+.index \retry@_data@_expire\
+.index hints database||data expiry
+.index retry||timeout of data
+Exim timestamps the data that it writes to its retry hints database. When it
+consults the data during a delivery it ignores any that is older than the value
+set in \retry@_data@_expire\ (default 7 days). If, for example, a host hasn't
+been tried for 7 days, Exim will try to deliver to it immediately a message
+arrives, and if that fails, it will calculate a retry time as if it were
+failing for the first time.
+
+This improves the behaviour for messages routed to rarely-used hosts such as MX
+backups. If such a host was down at one time, and happens to be down again when
+Exim tries a month later, using the old retry data would imply that it had been
+down all the time, which is not a justified assumption.
+
+If a host really is permanently dead, this behaviour causes a burst of retries
+every now and again, but only if messages routed to it are rare. It there is a
+message at least once every 7 days the retry data never expires.
+
+
+
+.section Long-term failures
+.index delivery||failure, long-term
+.index retry||after long-term failure
+Special processing happens when an email address has been failing for so long
+that the cutoff time for the last algorithm is reached. For example, using the
+default retry rule:
+.display asis
+* * F,2h,15m; G,16h,1h,1.5; F,4d,6h
+.endd
+the cutoff time is four days. Reaching the retry cutoff is independent of how
+long any specific message has been failing; it is the length of continuous
+failure for the recipient address that counts.
+
+When the cutoff time is reached for a local delivery, or for all the IP
+addresses associated with a remote delivery, a subsequent delivery failure
+causes Exim to give up on the address, and a bounce message is generated.
+In order to cater for new messages that use the failing address, a next retry
+time is still computed from the final algorithm, and is used as follows:
+
+For local deliveries, one delivery attempt is always made for any subsequent
+messages. If this delivery fails, the address fails immediately. The
+post-cutoff retry time is not used.
+
+If the delivery is remote, there are two possibilities, controlled by the
+.index \delay@_after@_cutoff\
+\delay@_after@_cutoff\ option of the \%smtp%\ transport. The option is true by
+default and in that case:
+.numberpars " "
+Until the post-cutoff retry time for one of the IP addresses is reached,
+the failing email address is bounced immediately, without a delivery attempt
+taking place. After that time, one new delivery attempt is made to those IP
+addresses that are past their retry times, and if that still fails, the address
+is bounced and new retry times are computed.
+.endp
+
+In other words, when all the hosts for a given email address have been failing
+for a long time, Exim bounces rather then defers until one of the hosts' retry
+times is reached. Then it tries once, and bounces if that attempt fails. This
+behaviour ensures that few resources are wasted in repeatedly trying to deliver
+to a broken destination, but if the host does recover, Exim will eventually
+notice.
+
+If \delay@_after@_cutoff\ is set false, Exim behaves differently. If all IP
+addresses are past their final cutoff time, Exim tries to deliver to those IP
+addresses that have not been tried since the message arrived. If there are
+no suitable IP addresses, or if they all fail, the address is bounced. In other
+words, it does not delay when a new message arrives, but tries the expired
+addresses immediately, unless they have been tried since the message arrived.
+If there is a continuous stream of messages for the failing domains, setting
+\delay@_after@_cutoff\ false means that there will be many more attempts to
+deliver to permanently failing IP addresses than when \delay@_after@_cutoff\ is
+true.
+
+.section Ultimate address timeout
+.index retry||ultimate address timeout
+An additional rule is needed to cope with cases where a host is intermittently
+available, or when a message has some attribute that prevents its delivery when
+others to the same address get through. In this situation, because some
+messages are successfully delivered, the `retry clock' for the address keeps
+getting restarted, and so a message could remain on the queue for ever. To
+prevent this, if a message has been on the queue for longer than the cutoff
+time of any applicable retry rule for a given address, a delivery is attempted
+for that address, even if it is not yet time, and if this delivery fails, the
+address is timed out. A new retry time is not computed in this case, so that
+other messages for the same address are considered immediately.
+
+
+
+
+
+.
+.
+.
+.
+. ============================================================================
+.chapter SMTP authentication
+.set runningfoot "SMTP authentication"
+.rset CHAPSMTPAUTH "~~chapter"
+.index SMTP||authentication configuration
+.index authentication
+The `authenticators' section of Exim's run time configuration is concerned with
+SMTP authentication. This facility is an extension to the SMTP protocol,
+described in RFC 2554, which allows a client SMTP host to authenticate itself
+to a server. This is a common way for a server to recognize clients that
+are permitted to use it as a relay. SMTP authentication is not of relevance to
+the transfer of mail between servers that have no managerial connection with
+each other.
+
+.index \\AUTH\\||description of
+Very briefly, the way SMTP authentication works is as follows:
+.numberpars $.
+The server advertises a number of authentication \*mechanisms*\ in response to
+the client's \\EHLO\\ command.
+.nextp
+The client issues an \\AUTH\\ command, naming a specific mechanism. The command
+may, optionally, contain some authentication data.
+.nextp
+The server may issue one or more \*challenges*\, to which the client must send
+appropriate responses. In simple authentication mechanisms, the challenges are
+just prompts for user names and passwords. The server does not have to issue
+any challenges -- in some mechanisms the relevant data may all be transmitted
+with the \\AUTH\\ command.
+.nextp
+The server either accepts or denies authentication.
+.nextp
+If authentication succeeds, the client may optionally make use of the \\AUTH\\
+option on the \\MAIL\\ command to pass an authenticated sender in subsequent
+mail transactions. Authentication lasts for the remainder of the SMTP
+connection.
+.nextp
+If authentication fails, the client may give up, or it may try a different
+authentication mechanism, or it may try transferring mail over the
+unauthenticated connection.
+.endp
+If you are setting up a client, and want to know which authentication
+mechanisms the server supports, you can use Telnet to connect to port 25 (the
+SMTP port) on the server, and issue an \\EHLO\\ command. The response to this
+includes the list of supported mechanisms. For example:
+.display
+@$ $cb{telnet server.example 25}
+Trying 192.168.34.25...
+Connected to server.example.
+Escape character is '@^]'.
+220 server.example ESMTP Exim 4.20 ...
+$cb{ehlo client.example}
+250-server.example Hello client.example [10.8.4.5]
+250-SIZE 52428800
+250-PIPELINING
+250-AUTH PLAIN
+250 HELP
+.endd
+The second-last line of this example output shows that the server supports
+authentication using the PLAIN mechanism. In Exim, the different authentication
+mechanisms are configured by specifying \*authenticator*\ drivers. Like the
+routers and transports, which authenticators are included in the binary is
+controlled by build-time definitions. The following are currently available,
+included by setting
+.display asis
+AUTH_CRAM_MD5=yes
+AUTH_PLAINTEXT=yes
+AUTH_SPA=yes
+.endd
+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.
+
+The authenticators are configured using the same syntax as other drivers (see
+section ~~SECTfordricon). If no authenticators are required, no authentication
+section need be present in the configuration file. Each authenticator can in
+principle have both server and client functions. When Exim is receiving SMTP
+mail, it is acting as a server; when it is sending out messages over SMTP, it
+is acting as a client. Authenticator configuration options are provided for use
+in both these circumstances.
+
+To make it clear which options apply to which situation, the prefixes
+\server@_\ and \client@_\ are used on option names that are specific to either
+the server or the client function, respectively. Server and client functions
+are disabled if none of their options are set. If an authenticator is to be
+used for both server and client functions, a single definition, using both sets
+of options, is required. For example:
+.display asis
+cram:
+ driver = cram_md5
+ public_name = CRAM-MD5
+ server_secret = ${if eq{$1}{ph10}{secret1}fail}
+ client_name = ph10
+ client_secret = secret2
+.endd
+The \server@_\ option is used when Exim is acting as a server, and the
+\client@_\ options when it is acting as a client.
+
+Descriptions of the individual authenticators are given in subsequent chapters.
+The remainder of this chapter covers the generic options for the
+authenticators, followed by general discussion of the way authentication works
+in Exim.
+
+
+.section Generic options for authenticators
+.index authentication||generic options
+
+.startconf
+.index options||generic, for authenticators
+
+.conf driver string unset
+This option must always be set. It specifies which of the available
+authenticators is to be used.
+
+.conf public@_name string unset
+This option specifies the name of the authentication mechanism that the driver
+implements, and by which it is known to the outside world. These names should
+contain only upper case letters, digits, underscores, and hyphens (RFC 2222),
+but Exim in fact matches them caselessly. If \public@_name\ is not set, it
+defaults to the driver's instance name.
+
+.conf server@_advertise@_condition string$**$ unset
+When a server is about to advertise an authentication mechanism, the condition
+is expanded. If it yields the empty string, `0', `no', or `false', the
+mechanism is not advertised.
+If the expansion fails, the mechanism is not advertised. If the failure was not
+forced, and was not caused by a lookup defer, the incident is logged.
+See section ~~SECTauthexiser below for further discussion.
+
+.conf server@_debug@_print string$**$ unset
+If this option is set and authentication debugging is enabled (see the \-d-\
+command line option), the string is expanded and included in the debugging
+output when the authenticator is run as a server. This can help with checking
+out the values of variables.
+If expansion of the string fails, the error message is written to the debugging
+output, and Exim carries on processing.
+
+.conf server@_set@_id string$**$ unset
+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
+lines for incoming messages. For example, a user/password authenticator
+configuration might preserve the user name that was used to authenticate, and
+refer to it subsequently during delivery of the message.
+If expansion fails, the option is ignored.
+
+.conf server@_mail@_auth@_condition string$**$ unset
+This option allows a server to discard authenticated sender addresses supplied
+as part of \\MAIL\\ commands in SMTP connections that are authenticated by the
+driver on which \server__mail__auth@_condition\ is set. The option is not used
+as part of the authentication process; instead its (unexpanded) value is
+remembered for later use.
+How it is used is described in the following section.
+.endconf
+
+
+
+.section The AUTH parameter on MAIL commands
+.rset SECTauthparamail "~~chapter.~~section"
+.index authentication||sender, authenticated
+.index \\AUTH\\||on \\MAIL\\ command
+When a client supplied an \\AUTH=\\ item on a \\MAIL\\ command, Exim applies
+the following checks before accepting it as the authenticated sender of the
+message:
+.numberpars $.
+If the connection is not using extended SMTP (that is, \\HELO\\ was used rather
+than \\EHLO\\), the use of \\AUTH=\\ is a syntax error.
+.nextp
+If the value of the \\AUTH=\\ parameter is `@<@>', it is ignored.
+.nextp
+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.
+.nextp
+If \acl@_smtp@_mailauth\ is not defined, the value of the \\AUTH=\\ parameter
+is accepted and placed in \$authenticated@_sender$\ only if the client has
+authenticated.
+.nextp
+If the \\AUTH=\\ value was accepted by either of the two previous rules, and
+the client has authenticated, and the authenticator has a setting for the
+\server@_mail@_auth@_condition\, the condition is checked at this point. The
+valued that was saved from the authenticator is expanded. If the expansion
+fails, or yields an empty string, `0', `no', or `false', the value of
+\$authenticated__sender$\ is deleted. If the expansion yields any other value,
+the value of \$authenticated@_sender$\ is retained and passed on with the
+message.
+.endp
+
+When \$authenticated@_sender$\ is set for a message, it is passed on to other
+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.
+
+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
+value of \$sender@_address$\ is not yet set up when the \acl@_smtp@_mailauth\
+ACL is run.
+
+
+.section Authentication on an Exim server
+.rset SECTauthexiser "~~chapter.~~section"
+.index authentication||on an Exim server
+When Exim receives an \\EHLO\\ command, it advertises the public names of those
+authenticators that are configured as servers, subject to the following
+conditions:
+.numberpars $.
+The client host must match \auth@_advertise@_hosts\ (default $*$).
+.nextp
+It the \server@_advertise@_condition\ option is set, its expansion must not
+yield the empty string, `0', `no', or `false'.
+.endp
+The order in which the authenticators are defined controls the order in which
+the mechanisms are advertised.
+
+Some mail clients (for example, some versions of Netscape) require the user to
+provide a name and password for authentication whenever \\AUTH\\ is advertised,
+even though authentication may not in fact be needed (for example, Exim may be
+set up to allow unconditional relaying from the client by an IP address check).
+You can make such clients more friendly by not advertising \\AUTH\\ to them.
+For example, if clients on the 10.9.8.0/24 network are permitted (by the ACL
+that runs for \\RCPT\\) to relay without authentication, you should set
+.display asis
+auth_advertise_hosts = ! 10.9.8.0/24
+.endd
+so that no authentication mechanisms are advertised to them.
+
+The \server@_advertise@_condition\ controls the advertisement of individual
+authentication mechanisms. For example, it can be used to restrict the
+advertisement of a patricular mechanism to encrypted connections, by a setting
+such as:
+.display asis
+server_advertise_condition = ${if eq{$tls_cipher}{}{no}{yes}}
+.endd
+If the session is encrypted, \$tls@_cipher$\ is not empty, and so the expansion
+yields `yes', which allows the advertisement to happen.
+
+When an Exim server receives an \\AUTH\\ command from a client, it rejects it
+immediately if \\AUTH\\ was not advertised in response to an earlier \\EHLO\\
+command. This is the case if
+.numberpars $.
+The client host does not match \auth@_advertise@_hosts\; or
+.nextp
+No authenticators are configured with server options; or
+.nextp
+Expansion of \server@_advertise@_condition\ blocked the advertising of all the
+server authenticators.
+.endp
+
+Otherwise, Exim runs the ACL specified by \acl@_smtp@_auth\ in order
+to decide whether to accept the command. If \acl@_smtp@_auth\ is not set,
+\\AUTH\\ is accepted from any client host.
+
+If \\AUTH\\ is not rejected by the ACL, Exim searches its configuration for a
+server authentication mechanism that was advertised in response to \\EHLO\\ and
+that matches the one named in the \\AUTH\\ command. If it finds one, it runs
+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.
+
+When a message is received from an authenticated host, the value of
+\$received@_protocol$\ is set to `asmtp' 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.
+
+
+
+.section Testing server authentication
+.index authentication||testing a server
+.index \\AUTH\\||testing a server
+.index base64 encoding||creating authentication test data
+Exim's \-bh-\ option can be useful for testing server authentication
+configurations. The data for the \\AUTH\\ command has to be sent using base64
+encoding. A quick way to produce such data for testing is the following Perl
+script:
+.display asis
+use MIME::Base64;
+printf ("%s", encode_base64(eval "\"$ARGV[0]\""));
+.endd
+.index binary zero||in authentication data
+This interprets its argument as a Perl string, and then encodes it. The
+interpretation as a Perl string allows binary zeros, which are required for
+some kinds of authentication, to be included in the data. For example, a
+command line to run this script on such data might be
+.display asis
+encode '\0user\0password'
+.endd
+Note the use of single quotes to prevent the shell interpreting the
+backslashes, so that they can be interpreted by Perl to specify characters
+whose code value is zero.
+
+\**Warning 1**\: If either of the user or password strings starts with an octal
+digit, you must use three zeros instead of one after the leading backslash. If
+you do not, the octal digit that starts your string will be incorrectly
+interpreted as part of the code for the first character.
+
+\**Warning 2**\: If there are characters in the strings that Perl interprets
+specially, you must use a Perl escape to prevent them being misinterpreted. For
+example, a command such as
+.display asis
+encode '\0user@domain.com\0pas$$word'
+.endd
+gives an incorrect answer because of the unescaped `@@' and `@$' characters.
+
+If you have the \mimencode\ command installed, another way to do produce
+base64-encoded strings is to run the command
+.display asis
+echo -e -n `\0user\0password' | mimencode
+.endd
+The \-e-\ option of \echo\ enables the interpretation of backslash escapes in
+the argument, and the \-n-\ option specifies no newline at the end of its
+output. However, not all versions of \echo\ recognize these options, so you
+should check your version before relying on this suggestion.
+
+
+.section Authentication by an Exim client
+.index authentication||on an Exim client
+The \%smtp%\ transport has two options called \hosts@_require@_auth\ and
+\hosts@_try@_auth\. When the \%smtp%\ transport connects to a server that
+announces support for authentication, and the host matches an entry in either
+of these options, Exim (as a client) tries to authenticate as follows:
+.numberpars $.
+For each authenticator that is configured as a client, it searches the
+authentication mechanisms announced by the server for one whose name
+matches the public name of the authenticator.
+.nextp
+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
+is abandoned,
+and Exim moves on to the next authenticator.
+Otherwise an expansion failure causes delivery to be
+deferred.
+.nextp
+If the result of the authentication attempt is a temporary error or a timeout,
+Exim abandons trying to send the message to the host for the moment. It will
+try again later. If there are any backup hosts available, they are tried in the
+usual way.
+.nextp
+If the response to authentication is a permanent error (5xx code), Exim carries
+on searching the list of authenticators and tries another one if possible. If
+all authentication attempts give permanent errors, or if there are no attempts
+because no mechanisms match
+(or option expansions force failure),
+what happens depends on whether the host matches \hosts@_require@_auth\ or
+\hosts@_try@_auth\. In the first case, a temporary error is generated, and
+delivery is deferred. The error can be detected in the retry rules, and thereby
+turned into a permanent error if you wish. In the second case, Exim tries to
+deliver the message unauthenticated.
+.endp
+.index \\AUTH\\||on \\MAIL\\ command
+When Exim has authenticated itself to a remote server, it adds the \\AUTH\\
+parameter to the \\MAIL\\ commands it sends, if it has an authenticated sender
+for the message.
+If the message came from a remote host, the authenticated sender is the one
+that was receiving on an incoming \\MAIL\\ command, provided that the incoming
+connection was authenticated and the \server@_mail@_auth\ condition allowed the
+authenticated sender to be retained. If a local process calls Exim to send a
+message, the sender address that is built from the login name and
+\qualify@_domain\ is treated as authenticated. However, if the
+\authenticated@_sender\ option is set on the \%smtp%\ transport, it overrides
+the authenticated sender that was received with the message.
+
+
+
+
+
+
+.
+.
+.
+.
+. ============================================================================
+.chapter The plaintext authenticator
+.rset CHAPplaintext "~~chapter"
+.set runningfoot "plaintext authenticator"
+.index \%plaintext%\ authenticator
+.index authenticators||\%plaintext%\
+The \%plaintext%\ authenticator can be configured to support the PLAIN and
+LOGIN authentication mechanisms, both of which transfer authentication data as
+plain (unencrypted) text (though base64 encoded). The use of plain text is a
+security risk. If you use one of these mechanisms without also making use of
+SMTP encryption (see chapter ~~CHAPTLS) you should not use the same passwords
+for SMTP connections as you do for login accounts.
+
+.section Using plaintext in a server
+When running as a server, \%plaintext%\ performs the authentication test by
+expanding a string. It has the following options:
+
+.startconf
+.index options||\%plaintext%\ authenticator (server)
+
+.conf server@_prompts string$**$ unset
+The contents of this option, after expansion, must be a colon-separated list of
+prompt strings. If expansion fails, a temporary authentication rejection is
+given.
+
+.conf server@_condition string$**$ unset
+This option must be set in order to configure the driver as a server. Its use
+is described below.
+
+.endconf
+
+.index \\AUTH\\||in \%plaintext%\ authenticator
+.index binary zero||in \%plaintext%\ authenticator
+.index numerical variables (\$1$\, \$2$\, etc)||in \%plaintext%\ authenticator
+.index base64 encoding||in \%plaintext%\ authenticator
+The data sent by the client with the \\AUTH\\ command, or in response to
+subsequent prompts, is base64 encoded, and so may contain any byte values
+when decoded. If any data is supplied with the command, it is treated as a
+list of strings, separated by NULs (binary zeros), which are placed in the
+expansion variables \$1$\, \$2$\, etc. If there are more strings in
+\server@_prompts\ than the number of strings supplied with the \\AUTH\\
+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.
+
+\**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.
+There are good and bad examples at the end of the next section.
+
+
+.section The PLAIN authentication mechanism
+.index PLAIN authentication mechanism
+.index authentication||PLAIN mechanism
+.index binary zero||in \%plaintext%\ authenticator
+The PLAIN authentication mechanism (RFC 2595) specifies that three strings be
+sent as one item of data (that is, one combined string containing two NUL
+separators). The data is sent either as part of the \\AUTH\\ command, or
+subsequently in response to an empty prompt from the server.
+
+The second and third strings are a user name and a corresponding password.
+Using a single fixed user name and password as an example, this could be
+configured as follows:
+.display asis
+fixed_plain:
+ driver = plaintext
+ public_name = PLAIN
+ server_prompts = :
+ server_condition = \
+ ${if and {{eq{$2}{username}}{eq{$3}{mysecret}}}{yes}{no}}
+ server_set_id = $2
+.endd
+The \server@_prompts\ setting specifies a single, empty prompt (empty items at
+the end of a string list are ignored). If all the data comes as part of the
+\\AUTH\\ command, as is commonly the case, the prompt is not used. This
+authenticator is advertised in the response to \\EHLO\\ as
+.display asis
+250-AUTH PLAIN
+.endd
+and a client host can authenticate itself by sending the command
+.display asis
+AUTH PLAIN AHVzZXJuYW1lAG15c2VjcmV0
+.endd
+As this contains three strings (more than the number of prompts), no further
+data is required from the client. Alternatively, the client may just send
+.display asis
+AUTH PLAIN
+.endd
+to initiate authentication, in which case the server replies with an empty
+prompt. The client must respond with the combined data string.
+
+.em
+The data string is base64 encoded, as required by the RFC. This example,
+when decoded, is \"<<NUL>>username<<NUL>>mysecret"\, where <<NUL>> represents a
+zero byte. This is split up into three strings, the first of which is empty.
+The \server@_condition\ option in the authenticator checks that the second two
+are \"username"\ and \"mysecret"\ respectively.
+
+Having just one fixed user name and password, as in this example, is not very
+realistic, though for a small organization with only a handful of
+authenticating clients it could make sense.
+.nem
+
+A more sophisticated instance of this authenticator could use the user name in
+\$2$\ to look up a password in a file or database, and maybe do an encrypted
+comparison (see \crypteq\ in chapter ~~CHAPexpand). Here is a example of this
+approach, where the passwords are looked up in a DBM file. \**Warning**\: This
+is an incorrect example:
+.display asis
+server_condition = \
+ ${if eq{$3}{${lookup{$2}dbm{/etc/authpwd}}}{yes}{no}}
+.endd
+The expansion uses the user name (\$2$\) as the key to look up a password,
+which it then compares to the supplied password (\$3$\). Why is this example
+incorrect? It works fine for existing users, but consider what happens if a
+non-existent user name is given. The lookup fails, but as no success/failure
+strings are given for the lookup, it yields an empty string. Thus, to defeat
+the authentication, all a client has to do is to supply a non-existent user
+name and an empty password. The correct way of writing this test is:
+.display asis
+server_condition = ${lookup{$2}dbm{/etc/authpwd}\
+ {${if eq{$value}{$3}{yes}{no}}}{no}}
+.endd
+In this case, if the lookup succeeds, the result is checked; if the lookup
+fails, authentication fails. If \crypteq\ is being used instead of \eq\, the
+first example is in fact safe, because \crypteq\ always fails if its second
+argument is empty. However, the second way of writing the test makes the logic
+clearer.
+
+
+.section The LOGIN authentication mechanism
+.index LOGIN authentication mechanism
+.index authentication||LOGIN mechanism
+The LOGIN authentication mechanism is not documented in any RFC, but is in use
+in a number of programs. No data is sent with the \\AUTH\\ command. Instead, a
+user name and password are supplied separately, in response to prompts. The
+plaintext authenticator can be configured to support this as in this example:
+.display asis
+fixed_login:
+ driver = plaintext
+ public_name = LOGIN
+ server_prompts = User Name : Password
+ server_condition = \
+ ${if and {{eq{$1}{username}}{eq{$2}{mysecret}}}{yes}{no}}
+ server_set_id = $1
+.endd
+Because of the way plaintext operates, this authenticator accepts data supplied
+with the \\AUTH\\ command (in contravention of the specification of LOGIN), but
+if the client does not supply it (as is the case for LOGIN clients), the prompt
+strings are used to obtain two data items.
+
+Some clients are very particular about the precise text of the prompts. For
+example, Outlook Express is reported to recognize only `Username:' and
+`Password:'. Here is an example of a LOGIN authenticator which uses those
+strings, and which uses the \ldapauth\ expansion condition to check the user
+name and password by binding to an LDAP server:
+.display asis
+login:
+ driver = plaintext
+ public_name = LOGIN
+ server_prompts = Username:: : Password::
+ server_condition = ${if ldapauth \
+.newline
+ {user="cn=${quote_ldap_dn:$1},ou=people,o=example.org" \
+ pass=${quote:$2} \
+.newline
+ ldap://ldap.example.org/}{yes}{no}}
+ server_set_id = uid=$1,ou=people,o=example.org
+.endd
+Note the use of the \quote@_ldap@_dn\ operator to correctly quote the DN for
+authentication. However, the basic \quote\ operator, rather than any of the
+LDAP quoting operators, is the correct one to use for the password, because
+quoting is needed only to make the password conform to the Exim syntax. At the
+LDAP level, the password is an uninterpreted string.
+
+
+.section Support for different kinds of authentication
+A number of string expansion features are provided for the purpose of
+interfacing to different ways of user authentication. These include checking
+traditionally encrypted passwords from \(/etc/passwd)\ (or equivalent), PAM,
+Radius, \ldapauth\, and \*pwcheck*\. For details see section ~~SECTexpcond.
+
+
+
+.section Using plaintext in a client
+The \%plaintext%\ authenticator has just one client option:
+
+.startconf
+.index options||\%plaintext%\ authenticator (client)
+
+.conf client@_send string$**$ unset
+The string is a colon-separated list of authentication data strings. Each
+string is independently expanded before being sent to the server. The first
+string is sent with the \\AUTH\\ command; any more strings are sent in response
+to prompts from the server.
+
+\**Note**\: you cannot use expansion to create multiple strings, because
+splitting takes priority and happens first.
+
+Because the PLAIN authentication mechanism requires NUL (binary zero) bytes in
+the data, further processing is applied to each string before it is sent. If
+there are any single circumflex characters in the string, they are converted to
+NULs. Should an actual circumflex be required as data, it must be doubled in
+the string.
+
+.endconf
+
+This is an example of a client configuration that implements the PLAIN
+authentication mechanism with a fixed user name and password:
+.display asis
+fixed_plain:
+ driver = plaintext
+ public_name = PLAIN
+ client_send = ^username^mysecret
+.endd
+The lack of colons means that the entire text is sent with the \\AUTH\\
+command, with the circumflex characters converted to NULs. A similar example
+that uses the LOGIN mechanism is:
+.display asis
+fixed_login:
+ driver = plaintext
+ public_name = LOGIN
+ client_send = : username : mysecret
+.endd
+The initial colon means that the first string is empty, so no data is sent with
+the \\AUTH\\ command itself. The remaining strings are sent in response to
+prompts.
+
+
+
+
+.
+.
+.
+.
+. ============================================================================
+.chapter The cram@_md5 authenticator
+.set runningfoot "cram@_md5 authenticator"
+.index \%cram@_md5%\ authenticator
+.index authenticators||\%cram@_md5%\
+.index CRAM-MD5 authentication mechanism
+.index authentication||CRAM-MD5 mechanism
+The CRAM-MD5 authentication mechanism is described in RFC 2195. The server
+sends a challenge string to the client, and the response consists of a user
+name and the CRAM-MD5 digest of the challenge string combined with a secret
+string (password) which is known to both server and client. Thus, the secret
+is not sent over the network as plain text, which makes this authenticator more
+secure than \%plaintext%\. However, the downside is that the secret has to be
+available in plain text at either end.
+
+.section Using cram@_md5 as a server
+This authenticator has one server option, which must be set to configure the
+authenticator as a server:
+
+.startconf
+.index options||\%cram@_md5%\ authenticator (server)
+
+.conf server@_secret string$**$ unset
+.index numerical variables (\$1$\, \$2$\, etc)||in \%cram@_md5%\ authenticator
+When the server receives the client's response, the user name is placed in
+the expansion variable \$1$\, and \server@_secret\ is expanded to obtain the
+password for that user. The server then computes the CRAM-MD5 digest that the
+client should have sent, and checks that it received the correct string. If the
+expansion of \server@_secret\ is forced to fail, authentication fails. If the
+expansion fails for some other reason, a temporary error code is returned to
+the client.
+
+.endconf
+
+For example, the following authenticator checks that the user name given by the
+client is `ph10', and if so, uses `secret' as the password. For any other user
+name, authentication fails.
+.display asis
+fixed_cram:
+ driver = cram_md5
+ public_name = CRAM-MD5
+ server_secret = ${if eq{$1}{ph10}{secret}fail}
+ server_set_id = $1
+.endd
+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:
+.display asis
+lookup_cram:
+ driver = cram_md5
+ public_name = CRAM-MD5
+ server_secret = ${lookup{$1}lsearch{/etc/authpwd}{$value}fail}
+ server_set_id = $1
+.endd
+Note that this expansion explicitly forces failure if the lookup fails
+because \$1$\ contains an unknown user name.
+
+.section Using cram@_md5 as a client
+When used as a client, the \%cram@_md5%\ authenticator has two options:
+
+.startconf
+.index options||\%cram@_md5%\ authenticator (client)
+
+.conf client@_name string$**$ "the primary host name"
+This string is expanded, and the result used as the user name data when
+computing the response to the server's challenge.
+
+.conf client@_secret string$**$ unset
+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.
+
+.endconf
+
+Different user names and secrets can be used for different servers by referring
+to \$host$\ or \$host@_address$\ in the options.
+
+Forced failure of either expansion string is treated as an indication that this
+authenticator is not prepared to handle this case. Exim moves on to the next
+configured client authenticator. Any other expansion failure causes Exim to
+give up trying to send the message to the current server.
+
+A simple example configuration of a \%cram@_md5%\ authenticator, using fixed
+strings, is:
+.display asis
+fixed_cram:
+ driver = cram_md5
+ public_name = CRAM-MD5
+ client_name = ph10
+ client_secret = secret
+.endd
+
+
+
+
+
+.
+.
+.
+.
+. ============================================================================
+.chapter The spa authenticator
+.set runningfoot "spa authenticator"
+.index \%spa%\ authenticator
+.index authenticators||\%spa%\
+.index authentication||Microsoft Secure Password
+.index authentication||NTLM
+.index Microsoft Secure Password Authentication
+.index NTLM authentication
+The \%spa%\ authenticator provides client support for Microsoft's \*Secure
+Password Authentication*\ mechanism,
+which is also sometimes known as NTLM (NT LanMan). The code for client side of
+this authenticator was contributed by Marc Prud'hommeaux, and much of it is
+taken from the Samba project (\?http://www.samba.org?\). The code for the
+server side was subsequently contributed by Tom Kistner.
+
+The mechanism works as follows:
+.numberpars $.
+After the \\AUTH\\ command has been accepted, the client sends an SPA
+authentication request based on the user name and optional domain.
+.nextp
+The server sends back a challenge.
+.nextp
+The client builds a challenge response which makes use of the user's password
+and sends it to the server, which then accepts or rejects it.
+.endp
+Encryption is used to protect the password in transit.
+
+
+.section Using spa as a server
+The \%spa%\ authenticator has just one server option:
+
+.startconf
+.index options||\%spa%\ authenticator (server)
+
+.conf server@_password string$**$ unset
+.index 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:
+.display asis
+spa:
+ driver = spa
+ public_name = NTLM
+ server_password = ${lookup{$1}lsearch{/etc/exim/spa_clearpass}}
+.endd
+If the expansion is forced to fail, authentication fails. Any other expansion
+failure causes a temporary error code to be returned.
+
+.endconf
+
+
+
+.section Using spa as a client
+The \%spa%\ authenticator has the following client options:
+
+.startconf
+.index options||\%spa%\ authenticator (client)
+
+.conf client@_domain string$**$ unset
+This option specifies an optional domain for the authentication.
+
+.conf client@_password string$**$ unset
+This option specifies the user's password, and must be set.
+
+.conf client@_username string$**$ unset
+This option specifies the user name, and must be set.
+
+.endconf
+
+Here is an example of a configuration of this authenticator for use with the
+mail servers at \*msn.com*\:
+.display asis
+msn:
+ driver = spa
+ public_name = MSN
+ client_username = msn/msn_username
+ client_password = msn_plaintext_password
+ client_domain = DOMAIN_OR_UNSET
+.endd
+
+
+
+
+
+
+.
+.
+.
+.
+. ============================================================================
+.chapter Encrypted SMTP connections using TLS/SSL
+.set runningfoot "TLS encryption"
+.rset CHAPTLS "~~chapter"
+.index encryption||on SMTP connection
+.index SMTP||encryption
+.index TLS||on SMTP connection
+.index OpenSSL
+.index GnuTLS
+.em
+Support for TLS (Transport Layer Security), formerly known as SSL (Secure
+Sockets Layer), is implemented by making use of the OpenSSL library or the
+GnuTLS library (Exim requires GnuTLS release 1.0 or later).
+.nem
+There is no cryptographic code in the Exim distribution itself for implementing
+TLS. In order to use this feature you must install OpenSSL or GnuTLS, and then
+build a version of Exim that includes TLS support (see section
+~~SECTinctlsssl). You 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
+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
+between them is encrypted.
+
+Exim also has support for legacy clients that do not use the \\STARTTLS\\
+mechanism. Instead, they connect to a different port on the server (usually
+called the `ssmtp' port), and expect to negotiate a TLS session as soon as the
+connection to the server is established. The \-tls-on-connect-\ command line
+option can be used to run an Exim server in this way from \*inetd*\, and it can
+also be used to run a special daemon that operates in this manner (use \-oX-\
+to specify the port).
+
+Exim's ACLs can detect whether the current SMTP session is encrypted or not,
+and if so, what cipher suite is in use, whether the client supplied a
+certificate, and whether or not that certificate was verified. This makes it
+possible for an Exim server to deny or accept certain commands based on the
+encryption state.
+
+\**Warning**\: certain types of firewall and certain anti-virus products can
+disrupt TLS connections. You need to turn off SMTP scanning for these products
+in order to get TLS to work.
+
+
+.section OpenSSL vs GnuTLS
+.index TLS||OpenSSL \*vs*\ GnuTLS
+.rset SECTopenvsgnu "~~chapter.~~section"
+The first TLS support in Exim was implemented using OpenSSL. Support for GnuTLS
+followed later, when the first versions of GnuTLS were released. To build Exim
+to use GnuTLS, you need to set
+.display asis
+USE_GNUTLS=yes
+.endd
+in Local/Makefile, in addition to
+.display asis
+SUPPORT_TLS=yes
+.endd
+You must also set \\TLS@_LIBS\\ and \\TLS@_INCLUDE\\ appropriately, so that the
+include files and libraries for GnuTLS can be found.
+
+There are some differences in usage when using GnuTLS instead of OpenSSL:
+.numberpars $.
+.em
+The \tls@_verify@_certificates\ option must contain the name of a file, not the
+name of a directory (for OpenSSL it can be either).
+.nem
+.nextp
+The \tls@_dhparam\ option is ignored, because early versions of GnuTLS had no
+facility for varying its Diffie-Hellman parameters. I understand that this has
+changed, but Exim has not been updated to provide this facility.
+.nextp
+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.
+.nextp
+.em
+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.
+.nem
+.nextp
+OpenSSL identifies cipher suites using hyphens as separators, for example:
+DES-CBC3-SHA. GnuTLS uses underscores, for example: RSA@_ARCFOUR@_SHA. What is
+more, OpenSSL complains if underscores are present in a cipher list. To make
+life simpler, Exim changes underscores to hyhens for OpenSSL and hyphens to
+underscores for GnuTLS when processing lists of cipher suites in the
+.em
+\tls@_require@_ciphers\ options (the global option and the \%smtp%\ transport
+option).
+.nem
+.nextp
+.em
+The \tls@_require@_ciphers\ options operate differently, as described in the
+following section.
+.nem
+.endp
+
+.em
+.section Requiring specific ciphers in OpenSSL and GnuTLS
+.rset SECTreqciphsslgnu "~~chapter.~~section"
+.index TLS||requiring specific ciphers
+.index \tls@_require@_ciphers\||OpenSSL \*vs*\ GnuTLS
+This section documents the different ways the \tls@_require@_ciphers\ options
+(the global option and the \%smtp%\ transport option) operate in OpenSSL and
+GnuTLS.
+
+There is a function in the OpenSSL library that can be passed a list of
+cipher suites before the cipher negotiation takes place. This specifies which
+ciphers are acceptable. The list is colon separated and may contain names like
+DES-CBC3-SHA. Exim passes the expanded value of \tls@_require@_ciphers\
+directly to this function call. The following quotation from
+the OpenSSL documentation specifies what forms of item are allowed in the
+cipher string:
+.numberpars $.
+It can consist of a single cipher suite such as RC4-SHA.
+.nextp
+It can represent a list of cipher suites containing a certain algorithm,
+or cipher suites of a certain type. For example SHA1 represents all
+ciphers suites using the digest algorithm SHA1 and SSLv3 represents all
+SSL v3 algorithms.
+.nextp
+Lists of cipher suites can be combined in a single cipher string using
+the + character. This is used as a logical and operation. For example
+SHA1+DES represents all cipher suites containing the SHA1 and the DES
+algorithms.
+.nextp
+Each cipher string can be optionally preceded by the characters \"!"\, \"-"\ or
+\"+"\.
+.numberpars " "
+If \"!"\ is used then the ciphers are permanently deleted from the list. The
+ciphers deleted can never reappear in the list even if they are explicitly
+stated.
+.nextp
+If \"-"\ is used then the ciphers are deleted from the list, but some or all
+of the ciphers can be added again by later options.
+.nextp
+If \"+"\ is used then the ciphers are moved to the end of the list. This
+option doesn't add any new ciphers it just moves matching existing ones.
+.nextp
+If none of these characters is present then the string is just interpreted as a
+list of ciphers to be appended to the current preference list. If the list
+includes any ciphers already present they will be ignored: that is, they will
+not moved to the end of the list.
+.endp
+.endp
+
+The GnuTLS library does not have a combined function like OpenSSL. Instead,
+it allows the caller to specify separate lists of key-exchange methods,
+main cipher algorithms, and MAC algorithms. Unfortunately, these lists are
+numerical, and the library does not have a function for turning names into
+numbers. Consequently, the list of recognized names has to be built into
+the application.
+
+At present, Exim permits only the list of main cipher algorithms to be
+changed. The \tls@_require@_ciphers\ option is in the same format as for
+OpenSSL. Exim searches each item for the name of available algorithm. For
+example, if the list contains RSA@_ARCFOUR@_SHA then ARCFOUR is recognized.
+
+The cipher algorithms list starts out with a default set of algorithms. If
+the first item in \tls@_require@_ciphers\ does \*not*\ start with an
+exclamation mark, all the default items are deleted. Thus, only those specified
+can be used. If the first item in \tls@_require@_ciphers\ \*does*\ start with
+an exclamation mark, the defaults are left on the list.
+
+Then, any item that starts with an exclamation mark causes the relevent
+algorithms to be removed from the list, and any item that does not start
+with an exclamation mark causes the relevant algorithms to be added to the
+list. Thus,
+.display asis
+tls_require_ciphers = !RSA_ARCFOUR_SHA
+.endd
+allows all the defaults except those that use ARCFOUR, whereas
+.display asis
+tls_require_ciphers = AES : 3DES
+.endd
+allows only cipher suites that use AES and 3DES. The currently recognized
+algorithms are: ARCFOUR@_128, ARCFOUR@_40, ARCFOUR (both of the preceding),
+AES@_256, AES@_128, AES (both of the preceding), and 3DES.
+
+Unrecognized algorithms are ignored. In a client, the order of the list
+specifies a preference order for the algorithms.
+.nem
+
+
+.section Configuring an Exim server to use TLS
+.index TLS||configuring an Exim server
+When Exim has been built with TLS support, it advertises the availability of
+the \\STARTTLS\\ command to client hosts that match \tls@_advertise@_hosts\,
+but not to any others. The default value of this option is unset, which means
+that \\STARTTLS\\ is not advertised at all. This default is chosen because you
+need to set some other options in order to make TLS avaliable, and also it is
+sensible for systems that want to use TLS only as a client.
+
+If a client issues a \\STARTTLS\\ command and there is some configuration
+problem in the server, the command is rejected with a 454 error. If the client
+persists in trying to issue SMTP commands, all except \\QUIT\\ are rejected
+with the error
+.display asis
+554 Security failure
+.endd
+If a \\STARTTLS\\ command is issued within an existing TLS session, it is
+rejected with a 554 error code.
+
+To enable TLS operations on a server, you must set \tls@_advertise@_hosts\ to
+match some hosts. You can, of course, set it to $*$ to match all hosts.
+However, this is not all you need to do. TLS sessions to a server won't work
+without some further configuration at the server end.
+
+It is rumoured that all existing clients that support TLS/SSL use RSA
+encryption. To make this work you need to set, in the server,
+.display asis
+tls_certificate = /some/file/name
+tls_privatekey = /some/file/name
+.endd
+The first file contains the server's X509 certificate, and the second contains
+the private key that goes with it. These files need to be readable by the Exim
+user, and must always be given as full path names. They can be the same file if
+both the certificate and the key are contained within it. If \tls@_privatekey\
+is not set, this is assumed to be the case. The certificate file may also
+contain intermediate certificates that need to be sent to the client to enable
+it to authenticate the server's certificate.
+
+If you do not understand about certificates and keys, please try to find a
+source of this background information, which is not Exim-specific. (There are a
+few comments below in section ~~SECTcerandall.)
+
+\**Note**\: These options do not apply when Exim is operating as a client --
+they apply only in the case of a server. For a client, you must set the options
+of the same name in an \%smtp%\ transport.
+
+With just these options, Exim will work as a server with clients such as
+Netscape. It does not require the client to have a certificate (but see below
+for how to insist on this). There is one other option that may be needed in
+other situations. If
+.display asis
+tls_dhparam = /some/file/name
+.endd
+is set, the SSL library is initialized for the use of Diffie-Hellman ciphers
+with the parameters contained in the file. This increases the set of cipher
+suites that the server supports. See the command
+.display asis
+openssl dhparam
+.endd
+for a way of generating this data.
+At present, \tls@_dhparam\ is used only when Exim is linked with OpenSSL. It is
+ignored if GnuTLS is being used.
+
+The strings supplied for these three options are expanded every time a client
+host connects. It is therefore possible to use different certificates and keys
+for different hosts, if you so wish, by making use of the client's IP address
+in \$sender@_host@_address$\ to control the expansion. If a string expansion is
+forced to fail, Exim behaves as if the option is not set.
+
+.index cipher||logging
+.index log||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
+also included in the log line that records a message's arrival, keyed by `X=',
+unless the \tls@_cipher\ log selector is turned off.
+The \encrypted\ condition can be used to test for specific cipher suites in
+ACLs.
+
+The ACLs that run for subsequent SMTP commands can check the name of the cipher
+suite and vary their actions accordingly. The cipher suite names are those used
+by OpenSSL. These may differ from the names used elsewhere. For example,
+OpenSSL uses the name DES-CBC3-SHA for the cipher suite which in other contexts
+is known as TLS@_RSA@_WITH@_3DES@_EDE@_CBC@_SHA. Check the OpenSSL
+documentation for more details.
+
+
+.section Requesting and verifying client certificates
+.index certificate||verification of client
+.index TLS||client certificate verification
+If you want an Exim server to request a certificate when negotiating a TLS
+session with a client, you must set either \tls@_verify@_hosts\ or
+\tls@_try@_verify@_hosts\. You can, of course, set either of them to $*$ to
+apply to all TLS connections. For any host that matches one of these options,
+Exim requests a certificate as part of the setup of the TLS session. The
+contents of the certificate are verified by comparing it with a list of
+expected certificates. These must be available in a file or,
+.em
+for OpenSSL only (not GnuTLS), a directory, identified by
+\tls@_verify@_certificates\.
+.nem
+
+A file can contain multiple certificates, concatenated end to end. If a
+directory is used
+.em
+(OpenSSL only),
+.nem
+each certificate must be in a separate file, with a name (or a symbolic link)
+of the form <<hash>>.0, where <<hash>> is a hash value constructed from the
+certificate. You can compute the relevant hash by running the command
+.display asis
+openssl x509 -hash -noout -in /cert/file
+.endd
+where \(/cert/file)\ contains a single certificate.
+
+The difference between \tls@_verify@_hosts\ and \tls@_try@_verify@_hosts\ is
+what happens if the client does not supply a certificate, or if the certificate
+does not match any of the certificates in the collection named by
+\tls@_verify@_certificates\. If the client matches \tls@_verify@_hosts\, the
+attempt to set up a TLS session is aborted, and the incoming connection is
+dropped. If the client matches \tls@_try@_verify@_hosts\, the (encrypted) SMTP
+session continues. ACLs that run for subsequent SMTP commands can detect the
+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.
+
+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.
+.index log||distinguished name
+Because it is often a long text string, it is not included in the log line or
+::Received:: header by default. You can arrange for it to be logged, keyed by
+`DN=', by setting the \tls@_peerdn\ log selector, and you can use
+\received@_header@_text\ to change the ::Received:: header. When no certificate
+is supplied, \$tls@_peerdn$\ is empty.
+
+.em
+.section Revoked certificates
+.index TLS||revoked certificates
+.index revocation list
+.index certificate||revocation list
+Certificate issuing authorities issue Certificate Revocation Lists (CRLs) when
+certificates are revoked. If you have such a list, you can pass it to an Exim
+server using the global option called \tls@_crl\ and to an Exim client using an
+identically named option for the \%smtp%\ transport. In each case, the value of
+the option is expanded and must then be the name of a file that contains a CRL
+in PEM format.
+.nem
+
+.section Configuring an Exim client to use TLS
+.index cipher||logging
+.index log||TLS cipher
+.index log||distinguished name
+.index TLS||configuring an Exim client
+The \tls@_cipher\ and \tls@_peerdn\ log selectors apply to outgoing SMTP
+deliveries as well as to incoming, the latter one causing logging of the
+server certificate's DN. The remaining client configuration for TLS is all
+within the \%smtp%\ transport.
+
+It is not necessary to set any options to have TLS work in the \%smtp%\
+transport. If Exim is built with TLS support, and TLS is advertised by a
+server, the \%smtp%\ transport always tries to start a TLS session. However,
+this can be prevented by setting \hosts@_avoid@_tls\ (an option of the
+transport) to a list of server hosts for which TLS should not be used.
+
+If you do not want Exim to attempt to send messages unencrypted when an attempt
+to set up an encrypted connection fails in any way, you can set
+\hosts@_require@_tls\ to a list of hosts for which encryption is mandatory. For
+those hosts, delivery is always deferred if an encrypted connection cannot be
+set up. If there are any other hosts for the address, they are tried in the
+usual way.
+
+When the server host is not in \hosts@_require@_tls\, Exim may try to deliver
+the message unencrypted. It always does this if the response to \\STARTTLS\\ is
+a 5\*xx*\ code. For a temporary error code, or for a failure to negotiate a TLS
+session after a success response code, what happens is controlled by the
+\tls@_tempfail@_tryclear\ option of the \%smtp%\ transport. If it is false,
+delivery to this host is deferred, and other hosts (if available) are tried. If
+it is true, Exim attempts to deliver unencrypted after a 4\*xx*\ response to
+\\STARTTLS\\, and if \\STARTTLS\\ is accepted, but the subsequent TLS
+negotiation fails, Exim closes the current connection (because it is in an
+unknown state), opens a new one to the same host, and then tries the delivery
+unencrypted.
+
+
+The \tls@_certificate\ and \tls@_privatekey\ options of the \%smtp%\ transport
+provide the client with a certificate, which is passed to the server if it
+requests it. If the server is Exim, it will request a certificate only if
+\tls@_verify@_hosts\ or \tls@_try@_verify@_hosts\ matches the client.
+\**Note**\: these options must be set in the \%smtp%\ transport for Exim to use
+TLS when it is operating as a client. Exim does not assume that a server
+certificate (set by the global options of the same name) should also be used
+when operating as a client.
+
+If \tls@_verify@_certificates\ is set, it must name a file or,
+.em
+for OpenSSL only (not GnuTLS), a directory, that contains a collection of
+expected server certificates. The client verifies the server's certificate
+against this collection, taking into account any revoked certificates that are
+in the list defined by \tls@_crl\.
+.nem
+
+If
+\tls@_require@_ciphers\ is set on the \%smtp%\ transport, it must contain a
+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.
+
+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
+behave as if the relevant option were unset.
+
+
+.section Multiple messages on the same encrypted TCP/IP connection
+.rset SECTmulmessam "~~chapter.~~section"
+.index multiple SMTP deliveries with TLS
+.index TLS||multiple message deliveries
+Exim sends multiple messages down the same TCP/IP connection by starting up
+an entirely new delivery process for each message, passing the socket from
+one process to the next. This implementation does not fit well with the use
+of TLS, because there is quite a lot of state information associated with a TLS
+connection, not just a socket identification. Passing all the state information
+to a new process is not feasible. Consequently, Exim shuts down an existing TLS
+session before passing the socket to a new process. The new process may then
+try to start a new TLS session, and if successful, may try to re-authenticate
+if \\AUTH\\ is in use, before sending the next message.
+
+The RFC is not clear as to whether or not an SMTP session continues in clear
+after TLS has been shut down, or whether TLS may be restarted again later, as
+just described. However, if the server is Exim, this shutdown and
+reinitialization works. It is not known which (if any) other servers operate
+successfully if the client closes a TLS session and continues with unencrypted
+SMTP, but there are certainly some that do not work. For such servers, Exim
+should not pass the socket to another process, because the failure of the
+subsequent attempt to use it would cause Exim to record a temporary host error,
+and delay other deliveries to that host.
+
+To test for this case, Exim sends an \\EHLO\\ command to the server after
+closing down the TLS session. If this fails in any way, the connection is
+closed instead of being passed to a new delivery process, but no retry
+information is recorded.
+
+There is also a manual override; you can set \hosts@_nopass@_tls\ on the
+\%smtp%\ transport to match those hosts for which Exim should not pass
+connections to new processes if TLS has been used.
+
+
+
+.section Certificates and all that
+.rset SECTcerandall "~~chapter.~~section"
+.index certificate||references to discussion
+In order to understand fully how TLS works, you need to know about
+certificates, certificate signing, and certificate authorities. This is not the
+place to give a tutorial, especially as I do not know very much about it
+myself. Some helpful introduction can be found in the FAQ for the SSL addition
+to Apache, currently at
+.display rm
+\?http://www.modssl.org/docs/2.7/ssl@_faq.html@#ToC24?\
+.endd
+Other parts of the \*modssl*\ documentation are also helpful, and have
+links to further files.
+Eric Rescorla's book, \*SSL and TLS*\, published by Addison-Wesley (ISBN
+0-201-61598-3), contains both introductory and more in-depth descriptions.
+Some sample programs taken from the book are available from
+.display rm
+\?http://www.rtfm.com/openssl-examples/?\
+.endd
+
+.section Certificate chains
+The file named by \tls@_certificate\ may contain more than one
+certificate. This is useful in the case where the certificate that is being
+sent is validated by an intermediate certificate which the other end does
+not have. Multiple certificates must be in the correct order in the file.
+First the host's certificate itself, then the first intermediate
+certificate to validate the issuer of the host certificate, then the next
+intermediate certificate to validate the issuer of the first intermediate
+certificate, and so on, until finally (optionally) the root certificate.
+The root certificate must already be trusted by the recipient for
+validation to succeed, of course, but if it's not preinstalled, sending the
+root certificate along with the rest makes it available for the user to
+install if the receiving end is a client MUA that can interact with a user.
+
+.section Self-signed certificates
+.index certificate||self-signed
+You can create a self-signed certificate using the \*req*\ command provided
+with OpenSSL, like this:
+.display asis
+openssl req -x509 -newkey rsa:1024 -keyout file1 -out file2 \
+ -days 9999 -nodes
+.endd
+\(file1)\ and \(file2)\ can be the same file; the key and the certificate are
+delimited and so can be identified independently. The \-days-\ option
+specifies a period for which the certificate is valid. The \-nodes-\ option is
+important: if you do not set it, the key is encrypted with a passphrase
+that you are prompted for, and any use that is made of the key causes more
+prompting for the passphrase. This is not helpful if you are going to use
+this certificate and key in an MTA, where prompting is not possible.
+
+A self-signed certificate made in this way is sufficient for testing, and
+may be adequate for all your requirements if you are mainly interested in
+encrypting transfers, and not in secure identification.
+
+However, many clients require that the certificate presented by the server be a
+user (also called `leaf' or `site') certificate, and not a self-signed
+certificate. In this situation, the self-signed certificate described above
+must be installed on the client host as a trusted root \*certification
+authority*\ (CA), and the certificate used by Exim must be a user certificate
+signed with that self-signed certificate.
+
+For information on creating self-signed CA certificates and using them to sign
+user certificates, see the \*General implementation overview*\ chapter of the
+Open-source PKI book, available online at \?http://ospkibook.sourceforge.net/?\.
+
+
+
+.
+.
+.
+.
+. ============================================================================
+.chapter Access control lists
+.set runningfoot "ACL"
+.rset CHAPACL "~~chapter"
+.index ~~ACL||description
+.index control of incoming mail
+.index message||controlling incoming
+.index policy control||access control lists
+Access Control Lists (ACLs) are defined in a separate section of the run time
+configuration file, headed by `begin acl'. Each ACL definition starts with a
+name, terminated by a colon. Here is a complete ACL section which contains just
+one very small ACL:
+.display asis
+begin acl
+
+small_acl:
+ accept hosts = one.host.only
+.endd
+You can have as many lists as you like in the ACL section, and the order in
+which they appear does not matter. The lists are self-terminating.
+
+The majority of ACLs are used to control Exim's behaviour when it receives
+certain SMTP commands. This applies both to incoming TCP/IP connections, and
+when a local process submits a message over a pipe (using the \-bs-\ option).
+The most common use is for controlling which recipients are accepted in
+incoming messages. In addition, you can also define an ACL that is used to
+check local non-SMTP messages. The default configuration file contains an
+example of a realistic ACL for checking \\RCPT\\ commands. This is discussed in
+chapter ~~CHAPdefconfil.
+
+.section Testing ACLs
+The \-bh-\ command line option provides a way of testing your ACL configuration
+locally by running a fake SMTP session with which you interact. The host
+\*relay-test.mail-abuse.org*\ provides a service for checking your relaying
+configuration (see section ~~SECTcheralcon for more details).
+
+
+.section Specifying when ACLs are used
+.index ~~ACL||options for specifying
+In order to cause an ACL to be used, you have to name it in one of the relevant
+options in the main part of the configuration. These options are:
+.index \\AUTH\\||ACL for
+.index \\DATA\\, ACL for
+.index \\ETRN\\||ACL for
+.index \\EXPN\\||ACL for
+.index \\HELO\\||ACL for
+.index \\EHLO\\||ACL for
+.index \\MAIL\\||ACL for
+.index \\RCPT\\||ACL for
+.index \\STARTTLS\\, ACL for
+.index \\VRFY\\||ACL for
+.display
+.tabs 20
+.if !~~sys.fancy
+.tabs 24
+.fi
+\acl@_not@_smtp\ $t $rm{ACL for non-SMTP messages}
+\acl@_smtp@_auth\ $t $rm{ACL for \\AUTH\\}
+\acl@_smtp@_connect\ $t $rm{ACL for start of SMTP connection}
+\acl@_smtp@_data\ $t $rm{ACL after \\DATA\\}
+\acl@_smtp@_etrn\ $t $rm{ACL for \\ETRN\\}
+\acl@_smtp@_expn\ $t $rm{ACL for \\EXPN\\}
+\acl@_smtp@_helo\ $t $rm{ACL for \\HELO\\ or \\EHLO\\}
+\acl@_smtp@_mail\ $t $rm{ACL for \\MAIL\\}
+.newline
+\acl@_smtp@_mailauth\ $t $rm{ACL for the \\AUTH\\ parameter of \\MAIL\\}
+.newline
+\acl@_smtp@_rcpt\ $t $rm{ACL for \\RCPT\\}
+\acl@_smtp@_starttls\ $t $rm{ACL for \\STARTTLS\\}
+\acl@_smtp@_vrfy\ $t $rm{ACL for \\VRFY\\}
+.endd
+For example, if you set
+.display asis
+acl_smtp_rcpt = small_acl
+.endd
+the little ACL defined above is used whenever Exim receives a \\RCPT\\ command
+in an SMTP dialogue. The majority of policy tests on incoming messages can be
+done when \\RCPT\\ commands arrive. A rejection of \\RCPT\\ should cause the
+sending MTA to give up on the recipient address contained in the \\RCPT\\
+command, whereas rejection at other times may cause the client MTA to keep on
+trying to deliver the message. It is therefore recommended that you do as much
+testing as possible at \\RCPT\\ time.
+
+However, you cannot test the contents of the message, for example, to verify
+addresses in the headers, at \\RCPT\\ time. Such tests have to appear in the
+ACL that is run after the message has been received, before the final response
+to the \\DATA\\ command is sent. This is the ACL specified by
+\acl@_smtp@_data\. At this time, it is no longer possible to reject individual
+recipients. An error response should reject the entire message. Unfortunately,
+it is known that some MTAs do not treat hard (5$it{xx}) errors correctly at
+this point -- they keep the message on their queues and try again later, but
+that is their problem, though it does waste some of your resources.
+
+The ACL test specified by \acl@_smtp@_connect\ happens after the test specified
+by \host__reject__connection\ (which is now an anomaly) and any TCP Wrappers
+testing (if configured).
+
+The non-SMTP ACL applies to all non-interactive incoming messages, that is, it
+applies to batch SMTP as well as to non-SMTP messages. (Batch SMTP is not
+really SMTP.) This ACL is run just before the \*local@_scan()*\ function. Any
+kind of rejection is treated as permanent, because there is no way of sending a
+temporary error for these kinds of message. Many of the ACL conditions (for
+example, host tests, and tests on the state of the SMTP connection such as
+encryption and authentication) are not relevant and are forbidden in this ACL.
+
+
+.section ACL return codes
+.index ~~ACL||return codes
+The result of running an ACL is either `accept' or `deny', or, if some test
+cannot be completed (for example, if a database is down), `defer'. These
+results cause 2$it{xx}, 5$it{xx}, and 4$it{xx} return codes, respectively, to
+be used in the SMTP dialogue. A fourth return, `error', occurs when there is an
+error such as invalid syntax in the ACL. This also causes a 4$it{xx} return
+code.
+
+The ACLs that are relevant to message reception may also return `discard'. This
+has the effect of `accept', but causes either the entire message or an
+individual recipient address to be discarded. In other words, it is a
+blackholing facility. Use it with great care.
+
+If the ACL for \\MAIL\\ returns `discard', all recipients are discarded, and no
+ACL is run for subsequent \\RCPT\\ commands. The effect of `discard' in a
+\\RCPT\\ ACL is to discard just the one address. If there are no recipients
+left when the message's data is received, the \\DATA\\ ACL is not run. A
+`discard' return from the \\DATA\\ or the non-SMTP ACL discards all the
+remaining recipients.
+
+The \*local@_scan()*\ function is always run, even if there are no remaining
+recipients; it may create new recipients.
+
+
+.section Unset ACL options
+.index ~~ACL||unset options
+.em
+The default actions when any of the \acl@_$it{xxx}\ options are unset are not
+all the same. \**Note**\: These defaults apply only when the relevant ACL is
+not defined at all. For any defined ACL, the default action if control reaches
+the end of the ACL statements is `deny'.
+.nem
+
+For \acl@_not@_smtp\, \acl@_smtp@_auth\, \acl@_smtp@_connect\,
+\acl@_smtp@_data\, \acl@_smtp@_helo\, \acl__smtp__mail\, \acl@_smtp@_mailauth\,
+and \acl@_smtp@_starttls\, the
+.em
+action when the ACL is not defined is `accept'.
+
+For the others (\acl@_smtp@_etrn\, \acl@_smtp@_expn\, \acl@_smtp@_rcpt\, and
+\acl@_smtp@_vrfy\), the action when the ACL is not defined is `deny'.
+.nem
+This means that \acl@_smtp@_rcpt\ must be defined in order to receive any
+messages over an SMTP connection. For an example, see the ACL in the default
+configuration file.
+
+
+
+.section Data for message ACLs
+.index ~~ACL||data for message ACL
+When an ACL for \\MAIL\\, \\RCPT\\, or \\DATA\\ is being run, 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 being run, the variables
+that contain information about the host are set, but \$sender@_address$\ is not
+yet set.
+
+The \$message@_size$\ variable is set to the value of the \\SIZE\\ parameter on
+the \\MAIL\\ command at \\MAIL\\ and \\RCPT\\ time, or -1 if that parameter was
+not given.
+Its value is updated to the true message size by the time the ACL after
+\\DATA\\ is run.
+
+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,
+\$rcpt@_count$\ contains the total number of \\RCPT\\ commands, and
+\$recipients@_count$\ contains the total number of accepted recipients.
+
+
+
+.section Data for non-message ACLs
+.rset SECTdatfornon "~~chapter.~~section"
+.index ~~ACL||data for non-message ACL
+When an ACL for \\AUTH\\, \\ETRN\\, \\EXPN\\,
+\\STARTTLS\\,
+or \\VRFY\\ is being run, 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 for use with \\AUTH\\, which insists that either
+the session is encrypted, or the CRAM-MD5 authentication method is used. In
+other words, it does not permit authentication methods that use cleartext
+passwords on unencrypted connections.
+.display asis
+acl_check_auth:
+ accept encrypted = *
+ accept condition = ${if eq{${uc:$smtp_command_argument}}\
+ {CRAM-MD5}{yes}{no}}
+ deny message = TLS encryption or CRAM-MD5 required
+.endd
+(Another way of applying this restriction is to arrange for the authenticators
+that use cleartext passwords not to be advertised when the connection is not
+encrypted. You can use the generic \server@_advertise@_condition\ authenticator
+option to do this.)
+
+
+.section Use of the ACL selection options
+.index ~~ACL||specifying which to use
+The value of an \acl@_smtp@_$it{xxx}\ option is expanded before use, so you can
+use different ACLs in different circumstances, and in fact the resulting string
+does not have to be the name of a configured list. Having expanded the string,
+Exim searches for an ACL as follows:
+.numberpars $.
+If the string begins with a slash, Exim attempts to open the file and read
+its contents as an ACL.
+The lines are processed in the same way as lines in the Exim configuration
+file. In particular, continuation lines are supported, blank lines are ignored,
+as are lines whose first non-whitespace character is `@#'.
+If the file does not exist or cannot be read, an error occurs (typically
+causing a temporary failure of whatever caused the ACL to be run). For example:
+.display asis
+acl_smtp_data = /etc/acls/\
+ ${lookup{$sender_host_address}lsearch\
+ {/etc/acllist}{$value}{default}}
+.endd
+This looks up an ACL file to use on the basis of the host's IP address, falling
+back to a default if the lookup fails. If an ACL is successfully read from a
+file, it is retained in memory for the duration of the Exim process, so that it
+can be re-used without having to re-read the file.
+.nextp
+If the string does not start with a slash, and does not contain any spaces,
+Exim searches the ACL section of the configuration for a list whose name
+matches the string.
+.nextp
+If no named ACL is found, or if the string contains spaces, Exim parses
+the string as an inline ACL. This can save typing in cases where you just
+want to have something like
+.display asis
+acl_smtp_vrfy = accept
+.endd
+in order to allow free use of the \\VRFY\\ command.
+Such a string may contain newlines; it is processed in the same way as an ACL
+that is read from a file.
+.endp
+
+
+.section Format of an ACL
+.index ~~ACL||format of
+.index ~~ACL||verbs, definition of
+An individual ACL consists of a number of statements. Each statement starts
+with a verb, optionally followed by a number of conditions and other modifiers.
+If all the conditions are met, the verb is obeyed.
+The same condition may be used (with different arguments) more than once in the
+same statement. This provides a means of specifying an `and' conjunction
+between conditions. For example:
+.display asis
+deny dnslists = list1.example
+ dnslists = list2.example
+.endd
+
+If there are no conditions, the verb is always obeyed. What happens if any of
+the conditions are not met depends on the verb (and in one case, on a special
+modifier). Not all the conditions make sense at every testing point. For
+example, you cannot test a sender address in the ACL that is run for a \\VRFY\\
+command.
+
+The verbs are as follows:
+.numberpars $.
+\accept\: If all the conditions are met, the ACL returns `accept'. If any of
+the conditions are not met, what happens depends on whether \endpass\ appears
+among the conditions (for syntax see below). If the failing condition precedes
+\endpass\, control is passed to the next ACL statement; if it follows
+\endpass\, the ACL returns `deny'. Consider this statement, used to check a
+\\RCPT\\ command:
+.display asis
+accept domains = +local_domains
+ endpass
+ verify = recipient
+.endd
+If the recipient domain does not match the \domains\ condition, control passes
+to the next statement. If it does match, the recipient is verified, and the
+command is accepted if verification succeeds. However, if verification fails,
+the ACL yields `deny', because the failing condition is after \endpass\.
+.nextp
+\defer\: If all the conditions are met, the ACL returns `defer' which, in an
+SMTP session, causes a 4\*xx*\ response to be given. For a non-SMTP ACL,
+\defer\ is the same as \deny\, because there is no way of sending a temporary
+error. For a \\RCPT\\ command, \defer\ is much the same as using a
+\%redirect%\ router and \":defer:"\ while verifying, but the \defer\ verb can
+be used in any ACL, and even for a recipient it might be a simpler approach.
+.nextp
+\deny\: If all the conditions are met, the ACL returns `deny'. If any of the
+conditions are not met, control is passed to the next ACL statement. For
+example,
+.display asis
+deny dnslists = blackholes.mail-abuse.org
+.endd
+rejects commands from hosts that are on a DNS black list.
+.nextp
+\discard\: This verb behaves like \accept\, except that it returns `discard'
+from the ACL instead of `accept'. It is permitted only on ACLs that are
+concerned with receiving messages, and it causes recipients to be discarded.
+If the \log@_message\ modifier is set when \discard\ operates, its contents are
+added to the line that is automatically written to the log.
+
+If \discard\ is used in an ACL for \\RCPT\\, just the one recipient is
+discarded; if used for \\MAIL\\, \\DATA\\ or in the non-SMTP ACL, all the
+message's recipients are discarded. Recipients that are discarded before
+\\DATA\\ do not appear in the log line when the \log@_recipients\ log selector
+is set.
+.nextp
+\drop\: This verb behaves like \deny\, except that an SMTP connection is
+forcibly closed after the 5\*xx*\ error message has been sent. For example:
+.display asis
+drop message = I don't take more than 20 RCPTs
+ condition = ${if > {$rcpt_count}{20}{yes}{no}}
+.endd
+There is no difference between \deny\ and \drop\ for the connect-time ACL. The
+connection is always dropped after sending a 550 response.
+.nextp
+\require\: If all the conditions are met, control is passed to the next ACL
+statement. If any of the conditions are not met, the ACL returns `deny'. For
+example, when checking a \\RCPT\\ command,
+.display asis
+require verify = sender
+.endd
+passes control to subsequent statements only if the message's sender can be
+verified. Otherwise, it rejects the command.
+.nextp
+.em
+\warn\: If all the conditions are met, a header line is added to an incoming
+message and/or a line is written to Exim's main log. In all cases, control
+passes to the next ACL statement. The text of the added header line and the log
+line are specified by modifiers; if they are not present, a \warn\ verb just
+checks its conditions and obeys any `immediate' modifiers such as \set\ and
+\logwrite\.
+
+If any condition on a \warn\ statement cannot be completed (that is, there is
+some sort of defer), no header is added and the configured log line is not
+written. No further conditions or modifiers in the \warn\ statement are
+processed. The incident is logged, but the ACL continues to be processed, from
+the next statement onwards.
+
+When testing an incoming message, the \message\ modifier can be used on a
+\warn\ statement to add an extra header line,
+.nem
+as in this example:
+.display asis
+warn message = X-blacklisted-at: $dnslist_domain
+ dnslists = blackholes.mail-abuse.org : \
+ dialup.mail-abuse.org
+.endd
+If an identical header line is requested several times (provoked, for example,
+by multiple \\RCPT\\ commands), only one copy is actually added to the message.
+.em
+If the text of the \message\ modifier is not a valid header line,
+\"X-ACL-Warn:"\ is added to the front of it.
+.nem
+
+Header lines that are added by an ACL at \\MAIL\\ or \\RCPT\\ time are not
+visible in string expansions in the ACL for subsequent \\RCPT\\ commands.
+However they are visible in string expansions in the ACL that is run after
+\\DATA\\. If you want to preserve data between \\MAIL\\ and \\RCPT\\ ACLs, you
+can use ACL variables, as described in the next section. If a message is
+rejected after \\DATA\\, all added header lines are included in the entry that
+is written to the reject log.
+
+If a \message\ modifier is present on a \warn\ verb in an ACL that is not
+testing an incoming message, it is ignored, and the incident is logged.
+
+A \warn\ statement may use the \log@_message\ modifier to cause a line to be
+written to the main log when the statement's conditions are true.
+.em
+Just as for \message\, 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.
+.nem
+
+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:
+.display asis
+warn !verify = sender
+ log_message = sender verify failed: $acl_verify_message
+.endd
+.endp
+
+At the end of each ACL there is an implicit unconditional \deny\.
+
+As you can see from the examples above, the conditions and modifiers are
+written one to a line, with the first one on the same line as the verb, and
+subsequent ones on following lines. If you have a very long condition, you can
+continue it onto several physical lines by the usual @\ continuation mechanism.
+It is conventional to align the conditions vertically.
+
+
+.section ACL variables
+.rset SECTaclvariables "~~chapter.~~section"
+.index ~~ACL||variables
+There are some special variables that can be set during ACL processing. They
+can be used to pass information between different ACLs, different
+invocations of the same ACL in the same SMTP connection, and between ACLs and
+the routers, transports, and filters that are used to deliver a message.
+There are two sets of these variables:
+.numberpars $.
+The values of \$acl@_c0$\ to \$acl@_c9$\ persist throughout an SMTP connection.
+They are never reset. Thus, a value that is set while receiving one message is
+still available when receiving the next message on the same SMTP connection.
+.nextp
+The values of \$acl@_m0$\ to \$acl@_m9$\ persist only while a message is being
+received. They are reset afterwards. They are also reset by \\MAIL\\, \\RSET\\,
+\\EHLO\\, \\HELO\\, and after starting up a TLS session.
+.endp
+When a message is accepted, the current values of all the ACL variables are
+preserved with the message and are subsequently made available at delivery
+time.
+
+The ACL variables are set by modifier called \set\. For example:
+.display asis
+accept hosts = whatever
+ set acl_m4 = some value
+.endd
+Note that the leading dollar sign is not used when naming a variable that is to
+be set. If you want to set a variable without taking any action, you can use a
+\warn\ verb without any other modifiers.
+
+
+.section Condition and modifier processing
+.index ~~ACL||conditions, processing
+.index ~~ACL||modifiers, processing
+An exclamation mark preceding a condition negates its result. For example,
+.display asis
+deny domains = *.dom.example
+ !verify = recipient
+.endd
+causes the ACL to return `deny' if the recipient domain ends in
+\*dom.example*\, but the recipient address cannot be verified.
+
+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
+condition is true. Consider these two statements:
+.display asis
+accept senders = ${lookup{$host_name}lsearch\
+ {/some/file}{$value}fail}
+accept senders = ${lookup{$host_name}lsearch\
+ {/some/file}{$value}{}}
+.endd
+Each attempts to look up a list of acceptable senders. If the lookup succeeds,
+the returned list is searched, but if the lookup fails the behaviour is
+different in the two cases. The \fail\ in the first statement causes the
+condition to be ignored, leaving no further conditions. The \accept\ verb
+therefore succeeds. The second statement, however, generates an empty list when
+the lookup fails. No sender can match an empty list, so the condition fails,
+and therefore the \accept\ also fails.
+
+ACL modifiers appear mixed in with conditions in ACL statements. Some of them
+specify actions that are taken as the conditions for a statement are checked;
+others specify text for messages that are used when access is denied or a
+warning is generated.
+
+The positioning of the modifiers in an ACL statement important, because the
+processing of a verb ceases as soon as its outcome is known. Only those
+modifiers that have already been encountered will take effect. For the \accept\
+and \require\ statements, this means that processing stops as soon as a false
+condition is met. For example, consider this use of the \message\ modifier:
+.display asis
+require message = Can't verify sender
+ verify = sender
+ message = Can't verify recipient
+ verify = recipient
+ message = This message cannot be used
+.endd
+If sender verification fails, Exim knows that the result of the statement is
+`deny', so it goes no further. The first \message\ modifier has been seen, so
+its text is used as the error message. If sender verification succeeds, but
+recipient verification fails, the second message is used. If recipient
+verification succeeds, the third message becomes `current', but is never used
+because there are no more conditions to cause failure.
+
+For the \deny\ verb, on the other hand, it is always the last \message\
+modifier that is used, because all the conditions must be true for rejection to
+happen. Specifying more than one \message\ modifier does not make sense, and
+the message can even be specified after all the conditions. For example:
+.display asis
+deny hosts = ...
+ !senders = *@my.domain.example
+ message = Invalid sender from client host
+.endd
+The `deny' result does not happen until the end of the statement is reached, by
+which time Exim has set up the message.
+
+
+.section ACL modifiers
+.rset SECTACLmodi "~~chapter.~~section"
+.index ~~ACL||modifiers, list of
+The ACL modifiers are as follows:
+
+.startitems
+
+.item "control = <<text>>"
+.index message||submission
+This modifier may appear only in ACLs for commands relating to incoming
+messages. It affects the subsequent processing of the message, provided that
+the message is eventually accepted.
+.em
+The text must be one of the words `freeze', `queue@_only', or `submission' (in
+the latter case, optionally followed by slash-delimited options). The first two
+cause the message to be frozen or just queued (without immediate delivery),
+respectively. The third tells Exim that this message is a submission from a
+local MUA. In this case, Exim applies certain fixups to the message if
+necessary. For example, it add a ::Date:: header line if one is not present.
+Details are given in chapter ~~CHAPmsgproc.
+.nem
+
+Once one of these controls is set, it remains set for the message. For example,
+if \control\ is used in a \\RCPT\\ ACL, it applies to the whole message, not
+just the individual recipient. The \control\ modifier can be used in several
+different ways. For example:
+.numberpars $.
+It can be at the end of an \accept\ statement:
+.display asis
+accept ...some conditions...
+ control = queue_only
+.endd
+In this case, the control is applied when this statement yields `accept'.
+.nextp
+It can be in the middle of an \accept\ statement:
+.display asis
+accept ...some conditions...
+ control = queue_only
+ ...some more conditions...
+.endd
+If the first set of conditions are true, the control is applied, even if the
+statement does not accept because one of the second set of conditions is false.
+In this case, some subsequent statement must yield `accept' for the control to
+be relevant.
+.nextp
+It can be used with \warn\ to apply the control, leaving the
+decision about accepting or denying to a subsequent verb. For
+example:
+.display asis
+warn ...some conditions...
+ control = freeze
+accept ...
+.endd
+.em
+This example of \warn\ does not contain \message\, \log@_message\, or
+\logwrite\, so it does not add anything to the message and does not write a log
+entry.
+.nem
+.endp
+
+.item "delay = <<time>>"
+.index \-bh-\ option
+This modifier causes Exim to wait for the time interval before proceeding. The
+time is given in the usual Exim notation. This modifier may appear in any ACL.
+The delay happens as soon as the modifier is processed.
+.em
+However, when testing Exim using the \-bh-\ option, the delay is not actually
+imposed (an appropriate message is output).
+.nem
+
+Like \control\, \delay\ can be used with \accept\ or
+\deny\, for example:
+.display asis
+deny ...some conditions...
+ delay = 30s
+.endd
+The delay happens if all the conditions are true, before the statement returns
+`deny'. Compare this with:
+.display asis
+deny delay = 30s
+ ...some conditions...
+.endd
+which waits for 30s before processing the conditions. The \delay\ modifier can
+also be used with \warn\ and together with \control\:
+.display
+warn ...some conditions...
+ delay = 2m
+ control = freeze
+accept ...
+.endd
+
+.item endpass
+This modifier, which has no argument, is recognized only in \accept\
+statements. It marks the boundary between the conditions whose failure causes
+control to pass to the next statement, and the conditions whose failure causes
+the ACL to return `deny'. See the description of \accept\ above.
+
+.item "log@_message = <<text>>"
+This modifier sets up a message that is used as part of the log message if the
+ACL denies access
+.em
+or a \warn\ statement's conditions are true.
+.nem
+For example:
+.display asis
+require log_message = wrong cipher suite $tls_cipher
+ encrypted = DES-CBC3-SHA
+.endd
+\log@_message\ adds to any underlying error message that may exist because of
+the condition failure. For example, while verifying a recipient address, a
+:::fail:: redirection might have already set up a message. Although the message
+is usually defined before the conditions to which it applies, the expansion
+does not happen until Exim decides that access is to be denied. This means that
+any variables that are set by the condition are available for inclusion in the
+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.
+
+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.
+
+.em
+If \log@_message\ is used with a \warn\ statement, `Warning:' is added to the
+start of the logged message. If the same warning log message is requested more
+than once while receiving a single email message, only one copy is actually
+logged. If you want to log multiple copies, use \logwrite\ instead of
+\log@_message\. In the absence of \log@_message\ and \logwrite\, nothing is
+logged for a succesful \warn\ statement.
+.nem
+
+If \log@_message\ is not present and there is no underlying error message (for
+example, from the failure of address verification), but \message\ is present,
+the \message\ text is used for logging rejections. However, if any text for
+logging contains newlines, only the first line is logged. In the absence of
+both \log@_message\ and \message\, a default built-in message is used for
+logging rejections.
+
+.item "logwrite = <<text>>"
+.index log||in ACL, immediate
+This modifier writes a message to a log file as soon as it is encountered when
+processing an ACL. (Compare \log@_message\, which,
+.em
+except in the case of \warn\,
+.nem
+is used only if the ACL statement denies access.) The \logwrite\ modifier can
+be used to log special incidents in ACLs. For example:
+.display
+accept <<some special conditions>>
+ control = freeze
+ logwrite = froze message because ...
+.endd
+By default, the message is written to the main log. However, it may begin
+with a colon, followed by a comma-separated list of log names, and then
+another colon, to specify exactly which logs are to be written. For
+example:
+.display asis
+logwrite = :main,reject: text for main and reject logs
+logwrite = :panic: text for panic log only
+.endd
+
+.item "message = <<text>>"
+This modifier sets up a text string that is expanded and used as an error
+message if the current statement causes the ACL to deny access. The expansion
+happens at the time Exim decides that access is to be denied, not at the time
+it processes \message\. If the expansion fails, or generates an empty string,
+the modifier is ignored. For ACLs that are triggered by SMTP commands, the
+message is returned as part of the SMTP error response.
+
+The \message\ modifier is also used with the \warn\ verb to specify one or more
+header lines to be added to an incoming message when all the conditions are
+true.
+If \message\ is used with \warn\ in an ACL that is not concerned with receiving
+a message, it has no effect.
+
+The text is literal; any quotes are taken as literals, but because the string
+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.
+
+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$\.
+
+.item "set <<acl@_name>> = <<value>>"
+This modifier puts a value into one of the ACL variables (see section
+~~SECTaclvariables).
+
+.enditems
+
+
+
+
+.section ACL conditions
+.rset SECTaclconditions "~~chapter.~~section"
+.index ~~ACL||conditions, list of
+Not all conditions are relevant in all circumstances. For example, testing
+senders and recipients does not make sense in an ACL that is being run as the
+result of the arrival of an \\ETRN\\ command, and checks on message headers can
+be done only in the ACLs specified by \acl@_smtp@_data\
+and \acl__not__smtp\.
+You can use the same condition (obviously with different parameters) more than
+once in the same ACL statement. This provides a way of specifying an `and'
+conjunction.
+The conditions are as follows:
+
+.startitems
+
+.item "acl = <<name of acl or ACL string or file name >>"
+.index ~~ACL||nested
+.index ~~ACL||indirect
+The possible values of the argument are the same as for the
+\acl@_smtp@_$it{xxx}\ options. The named or inline ACL is run. If it returns
+`accept' the condition is true; if it returns `deny' the condition is false; if
+it returns `defer', the current ACL returns `defer'.
+If it returns `drop' and the outer condition denies access, the connection is
+dropped. If it returns `discard', the verb must be \accept\ or \discard\, and
+the action is taken immediately -- no further conditions are tested.
+
+ACLs may be nested up to 20 deep; the limit exists purely to catch runaway
+loops. This condition allows you to use different ACLs in different
+circumstances. For example, different ACLs can be used to handle \\RCPT\\
+commands for different local users or different local domains.
+
+.item "authenticated = <<string list>>"
+.index authentication||ACL checking
+.index ~~ACL||testing for authentication
+If the SMTP connection is not authenticated, the condition is false. Otherwise,
+the name of the authenticator is tested against the list. To test for
+authentication by any authenticator, you can set
+.display asis
+authenticated = *
+.endd
+
+.item "condition = <<string>>"
+.index customizing||ACL condition
+.index ~~ACL||customized test
+This feature allows you to make up custom conditions. If the result of
+expanding the string is an empty string, the number zero, or one of the strings
+`no' or `false', the condition is false. If the result is any non-zero number,
+or one of the strings `yes' or `true', the condition is true. For any other
+values, some error is assumed to have occured, and the ACL returns `defer'.
+
+.item "dnslists = <<list of domain names and other data>>"
+.index DNS list||in ACL
+.index black list (DNS)
+.index ~~ACL||testing a DNS list
+This condition checks for entries in DNS black lists. These are also known as
+`RBL lists', after the original Realtime Blackhole List, but note that the use
+of the lists at \*mail-abuse.org*\ now carries a charge.
+There are too many different variants of this condition to describe briefly
+here. See sections ~~SECTmorednslists--~~SECTmorednslistslast for details.
+
+.item "domains = <<domain list>>"
+.index domain||ACL checking
+.index ~~ACL||testing a recipient domain
+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 lookup, the result of the lookup is placed in \$domain@_data$\
+until the next \domains\ test.
+
+.item "encrypted = <<string list>>"
+.index encryption||checking in an ACL
+.index ~~ACL||testing for encryption
+If the SMTP connection is not encrypted, the condition is false. Otherwise, the
+name of the cipher suite in use is tested against the list. To test for
+encryption without testing for any specific cipher suite(s), set
+.display asis
+encrypted = *
+.endd
+
+.item "hosts = << host list>>"
+.index host||ACL checking
+.index ~~ACL||testing the client host
+This condition tests that the calling host matches the host list. If you have
+name lookups or wildcarded host names and IP addresses in the same host list,
+you should normally put the IP addresses first. For example, you could have:
+.display asis
+accept hosts = 10.9.8.7 : dbm;/etc/friendly/hosts
+.endd
+The reason for this lies in the left-to-right way that Exim processes lists.
+It can test IP addresses without doing any DNS lookups, but when it reaches an
+item that requires a host name, it fails if it cannot find a host name to
+compare with the pattern. If the above list is given in the opposite order, the
+\accept\ statement fails for a host whose name cannot be found, even if its
+IP address is 10.9.8.7.
+
+If you really do want to do the name check first, and still recognize the IP
+address even if the name lookup fails, you can rewrite the ACL like this:
+.display asis
+accept hosts = dbm;/etc/friendly/hosts
+accept hosts = 10.9.8.7
+.endd
+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.
+
+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:
+.display asis
+deny hosts = net-lsearch;/some/file
+ message = $host_data
+.endd
+which gives a custom error message for each denied host.
+
+.item "local@_parts = <<local part list>>"
+.index local part||ACL checking
+.index ~~ACL||testing a local part
+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.
+
+.item "recipients = <<address list>>"
+.index recipient||ACL checking
+.index ~~ACL||testing a recipient
+This condition is relevant only after a \\RCPT\\ command. It checks the entire
+recipient address against a list of recipients.
+
+.item "sender@_domains = <<domain list>>"
+.index sender||ACL checking
+.index ~~ACL||testing a sender 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 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.
+
+.item "senders = <<address list>>"
+.index sender||ACL checking
+.index ~~ACL||testing a sender
+This condition tests the sender of the message against the given list. To test
+for a bounce message, which has an empty sender, set
+.display asis
+senders = :
+.endd
+
+.item "verify = certificate"
+.index TLS||client certificate verification
+.index certificate||verification of client
+.index ~~ACL||certificate verification
+This condition is true in an SMTP session if the session is encrypted, and a
+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).
+
+.item "verify = header@_sender/<<options>>"
+.index ~~ACL||verifying sender in the header
+.index header lines||verifying the sender in
+.index sender||verifying in header
+.index verifying||sender in header
+This condition is relevant only in an ACL that is run after a message has been
+received, that is, in an ACL specified by \acl@_smtp@_data\. It checks that
+there is a verifiable sender address in at least one of the ::Sender::,
+::Reply-To::, or ::From:: header lines. Details of address verification and the
+options are given later, starting at section ~~SECTaddressverification. You can
+combine this condition with the \senders\ condition to restrict it to bounce
+messages only:
+.display asis
+deny senders = :
+ message = A valid sender header is required for bounces
+ !verify = header_sender
+.endd
+
+.item "verify = header@_syntax"
+.index ~~ACL||verifying header syntax
+.index header lines||verifying syntax
+.index verifying||header syntax
+This condition is relevant only in an ACL that is run after a message has been
+received, that is, in an ACL specified by \acl@_smtp@_data\
+or \acl@_not@_smtp\.
+It checks the syntax of all header lines that can contain lists of addresses
+(::Sender::, ::From::, ::Reply-To::, ::To::, ::Cc::, and ::Bcc::).
+Unqualified addresses (local parts without domains) are permitted only in
+locally generated messages and from hosts that match
+\sender@_unqualified@_hosts\ or \recipient@_unqualified@_hosts\, as
+appropriate.
+
+Note that this condition is a syntax check only. However, a common spamming
+ploy is to send syntactically invalid headers such as
+.display asis
+To: @
+.endd
+and this condition can be used to reject such messages.
+
+.item "verify = helo"
+.index ~~ACL||verifying HELO/EHLO
+.index \\HELO\\||verifying
+.index \\EHLO\\||verifying
+.index verifying||\\EHLO\\
+.index 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.
+
+.item "verify = recipient/<<options>>"
+.index ~~ACL||verifying recipient
+.index recipient||verifying
+.index verifying||recipient
+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 \$address@_data$\ is the last value that was set while routing the
+address. This applies even if the verification fails. When an address that is
+being verified is redirected to a single address, verification continues with
+the new address, and in that case, the subsequent value of \$address@_data$\ is
+the value for the child address.
+
+
+.item "verify = reverse@_host@_lookup"
+.index ~~ACL||verifying host reverse lookup
+.index host||verifying reverse lookup
+This condition ensures that a verified host name has been looked up from the IP
+address of the client host. (This may have happened already if the host name
+was needed for checking a host list, or if the host matched \host@_lookup\.)
+Verification ensures that the host name obtained from a reverse DNS lookup, or
+one of its aliases, does, when it is itself looked up in the DNS, yield the
+original IP address.
+
+If this condition is used for a locally generated message (that is, when there
+is no client host involved), it always succeeds.
+
+
+.item "verify = sender/<<options>>"
+.index ~~ACL||verifying sender
+.index sender||verifying
+.index verifying||sender
+This condition is relevant only after a
+\\MAIL\\ or \\RCPT\\ command, or after a 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. Details of
+verification are given later, starting at section ~~SECTaddressverification.
+Exim caches the result of sender verification, to avoid doing it more than once
+per message.
+
+.item "verify = sender=address/<<options>>"
+This is a variation of the previous option, in which a modified address is
+verified as a sender.
+
+.enditems
+
+
+
+.section Using DNS lists
+.rset SECTmorednslists "~~chapter.~~section"
+.index DNS list||in ACL
+.index black list (DNS)
+.index ~~ACL||testing a DNS list
+In its simplest form, the \dnslists\ condition tests whether the calling host
+is on a DNS list by looking up the inverted IP address in one or more DNS
+domains. For example, if the calling host's IP address is 192.168.62.43, and
+the ACL statement is
+.display asis
+deny dnslists = blackholes.mail-abuse.org : \
+ dialups.mail-abuse.org
+.endd
+the following domains are looked up:
+.display asis
+43.62.168.192.blackholes.mail-abuse.org
+43.62.168.192.dialups.mail-abuse.org
+.endd
+If a DNS lookup times out or otherwise fails to give a decisive answer, Exim
+behaves as if the host is not on the relevant list. This is usually the
+required action when \dnslists\ is used with \deny\ (which is the most common
+usage), because it prevents a DNS failure from blocking mail. However, you can
+change this behaviour by putting one of the following special items in the
+list:
+.index \"+include@_unknown"\
+.index \"+exclude@_unknown"\
+.index \"+defer@_unknown"\
+.display
++include@_unknown $rm{behave as if the item is on the list}
++exclude@_unknown $rm{behave as if the item is not on the list (default)}
++defer@_unknown $rm{give a temporary error}
+.endd
+Each of these applies to any subsequent items on the list. For example:
+.display asis
+deny dnslists = +defer_unknown : foo.bar.example
+.endd
+
+Testing the list of domains stops as soon as a match is found. If you want to
+warn for one list and block for another, you can use two different statements:
+.display asis
+deny dnslists = blackholes.mail-abuse.org
+warn message = X-Warn: sending host is on dialups list
+ dnslists = dialups.mail-abuse.org
+.endd
+
+DNS list lookups are cached by Exim for the duration of the SMTP session,
+so a lookup based on the IP address is done at most once for any incoming
+connection. Exim does not share information between multiple incoming
+connections (but your local name server cache should be active).
+
+
+.section DNS lists keyed on domain names
+There are some lists that are keyed on domain names rather than inverted IP
+addresses (see for example the \*domain based zones*\ link at
+\?http://www.rfc-ignorant.org/?\).
+.em
+No reversing of components is used with these lists.
+.nem
+You can change the name that is looked up in a DNS list by adding additional
+data to a \dnslists\ item, introduced by a slash. For example,
+.display asis
+deny message = Sender's domain is listed at $dnslist_domain
+ dnslists = dsn.rfc-ignorant.org/$sender_address_domain
+.endd
+This particular example is useful only in ACLs that are obeyed after the
+\\RCPT\\ or \\DATA\\ commands, when a sender address is available. If (for
+example) the message's sender is \*user@@tld.example*\ the name that is looked
+up by this example is
+.display asis
+tld.example.dsn.rfc-ignorant.org
+.endd
+You can mix entries with and without additional data in the same \dnslists\
+condition.
+
+.section Data returned by DNS lists
+DNS lists are constructed using address records in the DNS. The original RBL
+just used the address 127.0.0.1 on the right hand side of each record, but the
+RBL+ list and some other lists use a number of values with different meanings.
+The values used on the RBL+ list are:
+.display rm
+.tabs 12
+127.1.0.1 $t RBL
+127.1.0.2 $t DUL
+127.1.0.3 $t DUL and RBL
+127.1.0.4 $t RSS
+127.1.0.5 $t RSS and RBL
+127.1.0.6 $t RSS and DUL
+127.1.0.7 $t RSS and DUL and RBL
+.endd
+Some DNS lists may return more than one address record.
+
+.section Variables set from DNS lists
+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
+associated TXT record. If more than one address record is returned by the DNS
+lookup, all the IP addresses are included in \$dnslist@_value$\, separated by
+commas and spaces.
+
+You can use these variables in \message\ or \log@_message\ modifiers --
+although these appear before the condition in the ACL, they are not expanded
+until after it has failed. For example:
+.display asis
+deny hosts = !+local_networks
+ message = $sender_host_address is listed \
+ at $dnslist_domain
+ dnslists = rbl-plus.mail-abuse.example
+.endd
+
+
+.section Additional matching conditions for DNS lists
+If you add an equals sign and an IP address after a \dnslists\ domain name, you
+can restrict its action to DNS records with a matching right hand side. For
+example,
+.display asis
+deny dnslists = rblplus.mail-abuse.org=127.0.0.2
+.endd
+rejects only those hosts that yield 127.0.0.2. Without this additional data,
+any address record is considered to be a match. If more than one address record
+is found on the list, they are all checked for a matching right-hand side.
+
+If you want to specify a constraining address and also change the name that is
+looked up, the address list must be specified first. For example:
+.display asis
+deny dnslists = dsn.rfc-ignorant.org\
+ =127.0.0.2/$sender_address_domain
+.endd
+
+More than one IP address may be given for checking, using a comma as a
+separator. These are alternatives -- if any one of them matches, the \dnslists\
+condition is true. For example:
+.display asis
+deny dnslists = a.b.c=127.0.0.2,127.0.0.3
+.endd
+
+If the character `&' is used instead of `=', the comparison for each listed
+IP address is done by a bitwise `and' instead of by an equality test. In
+other words, the listed addresses are used as bit masks. The comparison is
+true if all the bits in the mask are present in the address that is being
+tested. For example:
+.display asis
+dnslists = a.b.c&0.0.0.3
+.endd
+matches if the address is \*x.x.x.*\3, \*x.x.x.*\7, \*x.x.x.*\11, etc. If you
+want to test whether one bit or another bit is present (as opposed to both
+being present), you must use multiple values. For example:
+.display asis
+dnslists = a.b.c&0.0.0.1,0.0.0.2
+.endd
+matches if the final component of the address is an odd number or two times
+an odd number.
+
+
+.section Negated DNS matching conditions
+You can supply a negative list of IP addresses as part of a \dnslists\
+condition. Whereas
+.display asis
+deny dnslists = a.b.c=127.0.0.2,127.0.0.3
+.endd
+means `deny if the host is in the black list at the domain \*a.b.c*\ and the IP
+address yielded by the list is either 127.0.0.2 or 127.0.0.3',
+.display asis
+deny dnslists = a.b.c!=127.0.0.2,127.0.0.3
+.endd
+means `deny if the host is in the black list at the domain \*a.b.c*\ and the IP
+address yielded by the list is not 127.0.0.2 and not 127.0.0.3'. In other
+words, the result of the test is inverted if an exclamation mark appears before
+the `=' (or the `&') sign.
+
+\**Note**\: this kind of negation is not the same as negation in a domain,
+host, or address list (which is why the syntax is different).
+
+If you are using just one list, the negation syntax does not gain you much. The
+previous example is precisely equivalent to
+.display asis
+deny dnslists = a.b.c
+ !dnslists = a.b.c=127.0.0.2,127.0.0.3
+.endd
+However, if you are using multiple lists, the negation syntax is clearer.
+Consider this example:
+.display asis
+deny dnslists = sbl.spamhaus.org : \
+ list.dsbl.org : \
+ dnsbl.njabl.org!=127.0.0.3 : \
+ relays.ordb.org
+.endd
+Using only positive lists, this would have to be:
+.display asis
+deny dnslists = sbl.spamhaus.org : \
+ list.dsbl.org
+deny dnslists = dnsbl.njabl.org
+ !dnslists = dnsbl.njabl.org=127.0.0.3
+deny dnslists = relays.ordb.org
+.endd
+which is less clear, and harder to maintain.
+
+
+
+.section DNS lists and IPv6
+.rset SECTmorednslistslast "~~chapter.~~section"
+If Exim is asked to do a dnslist lookup for an IPv6 address, it inverts it
+nibble by nibble. For example, if the calling host's IP address is
+3ffe:ffff:836f:0a00:000a:0800:200a:c031, Exim might look up
+.display asis
+1.3.0.c.a.0.0.2.0.0.8.0.a.0.0.0.0.0.a.0.f.6.3.8.
+ f.f.f.f.e.f.f.3.blackholes.mail-abuse.org
+.endd
+(split over two lines here to fit on the page). Unfortunately, some of the DNS
+lists contain wildcard records, intended for IPv4, that interact badly with
+IPv6. For example, the DNS entry
+.display asis
+*.3.some.list.example. A 127.0.0.1
+.endd
+is probably intended to put the entire 3.0.0.0/8 IPv4 network on the list.
+Unfortunately, it also matches the entire 3@:@:/124 IPv6 network.
+
+You can exclude IPv6 addresses from DNS lookups by making use of a suitable
+\condition\ condition, as in this example:
+.display asis
+deny condition = ${if isip4{$sender_host_address}{yes}{no}}
+ dnslists = some.list.example
+.endd
+
+
+.section Address verification
+.rset SECTaddressverification "~~chapter.~~section"
+.index verifying||address, options for
+.index policy control||address verification
+Several of the \verify\ conditions described in section ~~SECTaclconditions
+cause addresses to be verified. These conditions can be followed by options
+that modify the verification process. The options are separated from the
+keyword and from each other by slashes, and some of them contain parameters.
+For example:
+.display asis
+verify = sender/callout
+verify = recipient/defer_ok/callout=10s,defer_ok
+.endd
+The first stage of verification is to run the address through the routers, in
+`verify mode'. Routers can detect the difference between verification and
+routing for delivery, and their actions can be varied by a number of generic
+options such as \verify\ and \verify@_only\ (see chapter ~~CHAProutergeneric).
+
+If there is a defer error while doing this verification routing, the ACL
+normally returns `defer'. However, if you include \defer@_ok\ in the options,
+the condition is forced to be true instead.
+
+.section Callout verification
+.rset SECTcallver "~~chapter.~~section"
+.index verifying||address, by callout
+.index callout||verification
+.index 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.
+
+.em
+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.
+.nem
+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
+one or more remote hosts. The usual case is routing by a \%dnslookup%\ or a
+\%manualroute%\ router, where the router specifies the hosts. However, if a
+router that does not set up hosts routes to an \%smtp%\ transport with a
+\hosts\ setting, the transport's hosts are used. If an \%smtp%\ transport has
+\hosts@_override\ set, its hosts are always used, whether or not the router
+supplies a host list.
+
+The port that is used is taken from the transport, if it is specified and is a
+remote transport. (For routers that do verification only, no transport need be
+specified.) Otherwise, the default SMTP port is used. If a remote transport
+specifies an outgoing interface, this is used; otherwise the interface is not
+specified.
+
+For a sender callout check, Exim makes SMTP connections to the remote hosts, to
+test whether a bounce message could be delivered to the sender address. The
+following SMTP commands are sent:
+.display
+HELO <<primary host name>>
+MAIL FROM:@<@>
+RCPT TO:<<the address to be tested>>
+QUIT
+.endd
+\\LHLO\\ is used instead of \\HELO\\ if the transport's \protocol\ option is
+set to `lmtp'.
+
+.em
+A recipient callout check is similar. By default, it also uses an empty address
+for the sender. This default is chosen because most hosts do not make use of
+the sender address when verifying a recipient. Using the same address means
+that a single cache entry can be used for each recipient. Some sites, however,
+do make use of the sender address when verifying. These are catered for by the
+\use@_sender\ and \use@_postmaster\ options, described in the next section.
+.nem
+
+If the response to the \\RCPT\\ command is a 2$it{xx} code, the verification
+succeeds. If it is 5$it{xx}, the verification fails. For any other condition,
+Exim tries the next host, if any. If there is a problem with all the remote
+hosts, the ACL yields `defer', unless the \defer@_ok\ parameter of the
+\callout\ option is given, in which case the condition is forced to succeed.
+
+
+.section Additional parameters for callouts
+.rset CALLaddparcall "~~chapter.~~section"
+.index callout||timeout, specifying
+The \callout\ option can be followed by an equals sign and a number of optional
+parameters, separated by commas. For example:
+.display asis
+verify = recipient/callout=10s,defer_ok
+.endd
+The old syntax, which had \callout@_defer@_ok\ and \check@_postmaster\ as
+separate verify options, is retained for backwards compatibility, but is now
+deprecated. The additional parameters for \callout\ are as follows:
+
+.numberpars $.
+<<a time>>: This specifies the timeout that applies for the callout attempt to
+each host. For example:
+.display asis
+verify = sender/callout=5s
+.endd
+The default is 30 seconds. The timeout is used for each response from the
+remote host.
+.nextp
+.index callout||defer, action on
+\defer@_ok\: 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.
+.nextp
+.index callout||cache, suppressing
+.index caching||callout, suppressing
+\no@_cache\: The callout cache is neither read nor updated.
+.nextp
+.index callout||postmaster, checking
+\postmaster\: A successful 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.
+.nextp
+.index callout||`random' check
+\random\: Before doing the normal callout check, Exim does a
+check for a `random' local part at the same domain. The local part is not
+really random -- it is defined by the expansion of the option
+\callout@_random@_local@_part\, which defaults to
+.display asis
+$primary_host_name-$tod_epoch-testing
+.endd
+The idea here is to try to determine whether the remote host accepts all local
+parts without checking. If it does, there is no point in doing callouts for
+specific local parts. If the `random' check succeeds, the result is saved in
+a cache record, and used to force the current and subsequent callout checks to
+succeed without a connection being made, until the cache record expires.
+.nextp
+.index callout||sender for recipient check
+.em
+\use@_postmaster\: This option applies to recipient callouts only. For example:
+.display asis
+deny !verify = recipient/callout=use_postmaster
+.endd
+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$\.
+.nextp
+\use@_sender\: This option applies to recipient callouts only. For example:
+.display asis
+require verify = recipient/callout=use_sender
+.endd
+It causes the message's actual sender address to be used in the \\MAIL\\
+command when performing the callout, instead of an empty address. The cache for
+such callouts is keyed by the sender/recipient combination; thus, for any given
+recipient, many more actual callouts are performed than when an empty sender or
+postmaster is used. This option should be set only when you know that the
+called hosts make use of the sender when checking recipients.
+.nem
+.endp
+
+
+.section Callout caching
+.rset SECTcallvercache "~~chapter.~~section"
+.index hints database||callout cache
+.index callout||caching
+.index caching||callout
+Exim caches the results of callouts in order to reduce the amount of resources
+used, unless you specify the \no@_cache\ parameter with the \callout\ option.
+A hints database called `callout' is used for the cache. Two different record
+types are used: one records the result of a callout check for a specific
+address, and the other records information that applies to the entire domain
+(for example, that it accepts the local part \*postmaster*\).
+
+When an original callout fails, a detailed SMTP error message is given about
+the failure. However, for subsequent failures use the cache data, this message
+is not available.
+
+The expiry times for negative and positive address cache records are
+independent, and can be set by the global options \callout@_negative@_expire\
+(default 2h) and \callout@_positive@_expire\ (default 24h), respectively.
+
+If a host gives a negative response to an SMTP connection, or rejects any
+commands up to and including
+.display asis
+MAIL FROM:<>
+.endd
+.em
+(but not including the \\MAIL\\ command with a non-empty address),
+.nem
+any callout attempt is bound to fail. Exim remembers such failures in a
+domain cache record, which it uses to fail callouts for the domain without
+making new connections, until the domain record times out. There are two
+separate expiry times for domain cache records:
+\callout@_domain@_negative@_expire\ (default 3h) and
+\callout__domain__positive@_expire\ (default 7d).
+
+Domain records expire when the negative expiry time is reached if callouts
+cannot be made for the domain, or if the postmaster check failed.
+Otherwise, they expire when the positive expiry time is reached. This
+ensures that, for example, a host that stops accepting `random' local parts
+will eventually be noticed.
+
+The callout caching mechanism is based entirely on the domain of the
+address that is being tested. If the domain routes to several hosts, it is
+assumed that their behaviour will be the same.
+
+
+.section Sender address verification reporting
+.index verifying||suppressing error details
+When sender verification fails in an ACL, the details of the failure are
+given as additional output lines before the 550 response to the relevant
+SMTP command (\\RCPT\\ or \\DATA\\). For example, if sender callout is in use,
+you might see:
+.display asis
+MAIL FROM:<xyz@abc.example>
+250 OK
+RCPT TO:<pqr@def.example>
+550-Verification failed for <xyz@abc.example>
+550-Called: 192.168.34.43
+550-Sent: RCPT TO:<xyz@abc.example>
+550-Response: 550 Unknown local part xyz in <xyz@abc.example>
+550 Sender verification failed
+.endd
+If more than one \\RCPT\\ command fails in the same way, the details are given
+only for the first of them. However, some administrators do not want to send
+out this much information. You can suppress the details by adding
+`/no@_details' to the ACL statement that requests sender verification. For
+example:
+.display asis
+verify = sender/no_details
+.endd
+
+
+.section Redirection while verifying
+.index verifying||redirection while
+.index 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:
+.numberpars $.
+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
+verification also fails.
+.nextp
+When an incoming address is redirected to more than one child address,
+verification does not continue. A success result is returned.
+.endp
+This seems the most reasonable behaviour for the common use of aliasing as a
+way of redirecting different local parts to the same mailbox. It means, for
+example, that a pair of alias entries of the form
+.display asis
+A.Wol: aw123
+aw123: :fail: Gone away, no forwarding address
+.endd
+work as expected, with both local parts causing verification failure. When a
+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.
+
+
+.section Using an ACL to control relaying
+.rset SECTrelaycontrol "~~chapter.~~section"
+.index ~~ACL||relay control
+.index relaying||control by ACL
+.index policy control||relay control
+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,
+.index `percent hack'
+but a redirection as a result of the `percent hack' is.
+
+Two kinds of relaying exist, which are termed `incoming' and `outgoing'. A host
+which is acting as a gateway or an MX backup is concerned with incoming
+relaying from arbitrary hosts to a specific set of domains. On the other hand,
+a host which is acting as a smart host for a number of clients is concerned
+with outgoing relaying from those clients to the Internet at large. Often the
+same host is fulfilling both functions, as illustrated in the diagram below,
+but in principle these two kinds of relaying are entirely independent. What is
+not wanted is the transmission of mail from arbitrary remote hosts through your
+system to arbitrary domains.
+.if ~~sys.fancy
+.figure "Controlled relaying" rm
+.indent 0
+.call aspic
+centre ~~sys.linelength;
+magnify 0.8;
+boundingbox 30;
+textdepth 16;
+ boxwidth 120;
+ boxdepth 44;
+A: box "Arbitrary" "remote hosts";
+C: ibox;
+D: box "Arbitrary" "domains";
+ iline down 50 from bottom of C;
+H: box width 180 "Local host";
+ iline down 50;
+E: ibox;
+SH: box "Specific" "hosts";
+SD: box join right to E "Specific" "domains";
+ arcarrow clockwise from top of SH to bottom of D plus (-10,-4)
+ via right of H plus (-20,0);
+ arcarrow clockwise from bottom of A to top of SD plus (10,4)
+ via left of H plus (20,0);
+
+ ibox join left to right of H "$it{Outgoing}";
+ goto H;
+ ibox join right to left of H "$it{Incoming}";
+
+L: line dashed from right of A to top of H plus (-15,0);
+ arc dashed to top of H plus (15,0);
+ arrow dashed to left of D plus (-2,0);
+
+ arrow dashed back up 72 right 32 from middle of L plus (8,0);
+ text at end plus (0, 4) "$it{Not wanted}";
+.endcall
+.endfigure
+.elif !~~html
+.display asis
+ -------------- -----------
+ | Arbitrary | |Arbitrary|
+ |remote hosts| | domains |
+ -------------- -----------
+ I v ^ O
+ n v ^ u
+ c ---v----------------^--- t
+ o | v Local ^ | g
+ m | v host ^ | o
+ i ---v----------------^--- i
+ n v ^ n
+ g v ^ g
+ Specific Specific
+ domains hosts
+.endd
+.else
+[(IMG SRC="relaying.gif" alt="Controlled relaying")][(br)]
+.fi
+
+You can implement relay control by means of suitable statements in the ACL that
+runs for each \\RCPT\\ command. For convenience, it is often easiest to use
+Exim's named list facility to define the domains and hosts involved. For
+example, suppose you want to do the following:
+.numberpars $.
+Deliver a number of domains to mailboxes on the local host (or process them
+locally in some other way). Let's say these are \*my.dom1.example*\ and
+\*my.dom2.example*\.
+.nextp
+Relay mail for a number of other domains for which you are the secondary MX.
+These might be \*friend1.example*\ and \*friend2.example*\.
+.nextp
+Relay mail from the hosts on your local LAN, to whatever domains are involved.
+Suppose your LAN is 192.168.45.0/24.
+.endp
+In the main part of the configuration, you put the following definitions:
+.display asis
+domainlist local_domains = my.dom1.example : my.dom2.example
+domainlist relay_domains = friend1.example : friend2.example
+hostlist relay_hosts = 192.168.45.0/24
+.endd
+Now you can use these definitions in the ACL that is run for every \\RCPT\\
+command:
+.display asis
+acl_check_rcpt:
+ accept domains = +local_domains : +relay_domains
+ accept hosts = +relay_hosts
+.endd
+The first statement accepts any \\RCPT\\ command that contains an address in
+the local or relay domains. For any other domain, control passes to the second
+statement, which accepts the command only if it comes from one of the relay
+hosts. In practice, you will probably want to make your ACL more sophisticated
+than this, for example, by including sender and recipient verification. The
+default configuration includes a more comprehensive example, which is described
+in chapter ~~CHAPdefconfil.
+
+
+.section Checking a relay configuration
+.rset SECTcheralcon "~~chapter.~~section"
+.index relaying||checking control of
+You can check the relay characteristics of your configuration in the same way
+that you can test any ACL behaviour for an incoming SMTP connection, by using
+the \-bh-\ option to run a fake SMTP session with which you interact.
+
+For specifically testing for unwanted relaying, the host
+\*relay-test.mail-abuse.org*\ provides a useful service. If you telnet to this
+host from the host on which Exim is running, using the normal telnet port, you
+will see a normal telnet connection message and then quite a long delay. Be
+patient. The remote host is making an SMTP connection back to your host, and
+trying a number of common probes to test for open relay vulnerability. The
+results of the tests will eventually appear on your terminal.
+
+
+
+
+.
+.
+.
+.
+. ============================================================================
+.chapter Adding a local scan function to Exim
+.set runningfoot "local scan function"
+.rset CHAPlocalscan "~~chapter"
+.index \*local@_scan()*\ function||description of
+.index customizing||input scan using C function
+.index policy control||by local scan function
+
+In these days of email worms, viruses, and ever-increasing spam, some sites
+want to apply a lot of checking to messages before accepting them. You can do a
+certain amount through string expansions and the \condition\ condition in the
+ACL that runs after the SMTP \\DATA\\ command or the ACL for non-SMTP messages
+(see chapter ~~CHAPACL), but this has its limitations.
+
+.index \exiscan\
+An increasingly popular way of doing additional checking is to make use of the
+Exiscan patch for Exim, which adds ACL conditions that perform body scans of
+various kinds. This is available from
+.if ~~html
+[(A HREF="http://duncanthrax.net/exiscan-acl/")]
+/?http://duncanthrax.net/exiscan-acl/?\.
+[(/A)]
+.else
+\?http:@/@/duncanthrax.net/exiscan-acl/?\.
+.fi
+
+To allow for even more general checking that can be customized to a site's own
+requirements, there is the possibility of linking Exim with a private message
+scanning function, written in C. If you want to run code that is written in
+something other than C, you can of course use a little C stub to call it.
+
+The local scan function is run once for every incoming message, at the point
+when Exim is just about to accept the message.
+It can therefore be used to control non-SMTP messages from local processes as
+well as messages arriving via SMTP.
+
+Exim applies a timeout to calls of the local scan function, and there is an
+option called \local@_scan@_timeout\ for setting it. The default is 5 minutes.
+Zero means `no timeout'.
+Exim also sets up signal handlers for SIGSEGV, SIGILL, SIGFPE, and SIGBUS
+before calling the local scan function, so that the most common types of crash
+are caught. If the timeout is exceeded or one of those signals is caught, the
+incoming message is rejected with a temporary error if it is an SMTP message.
+For a non-SMTP message, the message is dropped and Exim ends with a non-zero
+code. The incident is logged on the main and reject logs.
+
+
+.section Building Exim to use a local scan function
+.index \*local@_scan()*\ function||building Exim to use
+To make use of the local scan function feature, you must tell Exim where your
+function is before building Exim, by setting \\LOCAL@_SCAN@_SOURCE\\ in your
+\(Local/Makefile)\. A recommended place to put it is in the \(Local)\
+directory, so you might set
+.display asis
+LOCAL_SCAN_SOURCE=Local/local_scan.c
+.endd
+for example. The function must be called \*local@_scan()*\. It is called by
+Exim after it has received a message, when the success return code is about to
+be sent. This is after all the ACLs have been run. The return code from your
+function controls whether the message is actually accepted or not. There is a
+commented template function (that just accepts the message) in the file
+\(src/local@_scan.c)\.
+
+If you want to make use of Exim's run time configuration file to set options
+for your \*local@_scan()*\ function, you must also set
+.display asis
+LOCAL_SCAN_HAS_OPTIONS=yes
+.endd
+in \(Local/Makefile)\ (see section ~~SECTconoptloc below).
+
+
+
+.section API for local@_scan()
+.rset SECTapiforloc "~~chapter.~~section"
+.index \*local@_scan()*\ function||API description
+You must include this line near the start of your code:
+.display asis
+#include "local_scan.h"
+.endd
+This header file defines a number of variables and other values, and the
+prototype for the function itself. Exim is coded to use unsigned char values
+almost exclusively, and one of the things this header defines is a shorthand
+for \"unsigned char"\ called \"uschar"\.
+It also contains the following macro definitions, to simplify casting character
+strings and pointers to character strings:
+.display asis
+#define CS (char *)
+#define CCS (const char *)
+#define CSS (char **)
+#define US (unsigned char *)
+#define CUS (const unsigned char *)
+#define USS (unsigned char **)
+.endd
+
+The function prototype for \*local@_scan()*\ is:
+.display asis
+extern int local_scan(int fd, uschar **return_text);
+.endd
+The arguments are as follows:
+.numberpars $.
+\fd\ is a file descriptor for the file that contains the body of the message
+(the -D file).
+The file is open for reading and writing, but updating it is not recommended.
+\**Warning**\: You must \*not*\ close this file descriptor.
+
+The descriptor is positioned at character 19 of the file, which is the first
+character of the body itself, because the first 19 characters are the message
+id followed by \"-D"\ and a newline. If you rewind the file, you should use the
+macro \\SPOOL@_DATA@_START@_OFFSET\\ to reset to the start of the data, just in
+case this changes in some future version.
+
+.nextp
+\return@_text\ is an address which you can use to return a pointer to a text
+string at the end of the function. The value it points to on entry is NULL.
+.endp
+The function must return an \int\ value which is one of the following macros:
+.numberpars $.
+\"LOCAL@_SCAN@_ACCEPT"\
+
+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
+maximum length of text is 1000 characters.
+.nextp
+\"LOCAL@_SCAN@_ACCEPT@_FREEZE"\
+
+This behaves as \\LOCAL@_SCAN@_ACCEPT\\, except that the accepted message is
+queued without immediate delivery, and is frozen.
+.nextp
+\"LOCAL@_SCAN@_ACCEPT@_QUEUE"\
+
+This behaves as \\LOCAL@_SCAN@_ACCEPT\\, except that the accepted message is
+queued without immediate delivery.
+.nextp
+\"LOCAL@_SCAN@_REJECT"\
+
+The message is rejected; the returned text is used as an error message which is
+passed back to the sender and which is also logged. Newlines are permitted --
+they cause a multiline response for SMTP rejections, but are converted to
+\"@\n"\ in log lines.
+If no message is given, `Administrative prohibition' is used.
+.nextp
+\"LOCAL@_SCAN@_TEMPREJECT"\
+
+The message is temporarily rejected; the returned text is used as an error
+message as for \\LOCAL@_SCAN@_REJECT\\. If no message is given, `Temporary
+local problem' is used.
+.nextp
+\"LOCAL@_SCAN@_REJECT@_NOLOGHDR"\
+
+This behaves as \\LOCAL@_SCAN@_REJECT\\, except that the header of the rejected
+message is not written to the reject log. It has the effect of unsetting the
+\rejected@_header\ log selector for just this rejection. If \rejected@_header\
+is already unset (see the discussion of the \log@_selection\ option in section
+~~SECTlogselector), this code is the same as \\LOCAL@_SCAN@_REJECT\\.
+
+.nextp
+\"LOCAL@_SCAN@_TEMPREJECT@_NOLOGHDR"\
+
+This code is a variation of \\LOCAL@_SCAN@_TEMPREJECT\\ in the same way that
+\\LOCAL__SCAN__REJECT__NOLOGHDR\\ is a variation of \\LOCAL@_SCAN@_REJECT\\.
+.endp
+
+If the message is not being received by interactive SMTP, rejections are
+reported by writing to \stderr\ or by sending an email, as configured by the
+\-oe-\ command line options.
+
+
+.section Configuration options for local@_scan()
+.rset SECTconoptloc "~~chapter.~~section"
+.index \*local@_scan()*\ function||configuration options
+It is possible to have option settings in the main configuration file
+that set values in static variables in the \*local@_scan()*\ module. If you
+want to do this, you must have the line
+.display asis
+LOCAL_SCAN_HAS_OPTIONS=yes
+.endd
+in your \(Local/Makefile)\ when you build Exim. (This line is in
+\(OS/Makefile-Default)\, commented out). Then, in the \*local@_scan()*\ source
+file, you must define static variables to hold the option values, and a table to
+define them.
+
+The table must be a vector called \local@_scan@_options\, of type
+\"optionlist"\. Each entry is a triplet, consisting of a name, an option type,
+and a pointer to the variable that holds the value. The entries must appear in
+alphabetical order. Following \local@_scan@_options\ you must also define a
+variable called \local@_scan@_options@_count\ that contains the number of
+entries in the table. Here is a short example, showing two kinds of option:
+.display asis
+static int my_integer_option = 42;
+static uschar *my_string_option = US"a default string";
+
+optionlist local_scan_options[] = {
+ { "my_integer", opt_int, &my_integer_option },
+ { "my_string", opt_stringptr, &my_string_option }
+};
+int local_scan_options_count =
+ sizeof(local_scan_options)/sizeof(optionlist);
+.endd
+The values of the variables can now be changed from Exim's runtime
+configuration file by including a local scan section as in this example:
+.display asis
+begin local_scan
+my_integer = 99
+my_string = some string of text...
+.endd
+The available types of option data are as follows:
+
+.startitems
+
+.item opt@_bool
+This specifies a boolean (true/false) option. The address should point to
+a variable of type \"BOOL"\, which will be set to \\TRUE\\ or \\FALSE\\, which
+are macros that are defined as `1' and `0', respectively. If you want to detect
+whether such a variable has been set at all, you can initialize it to
+\\TRUE@_UNSET\\. (BOOL variables are integers underneath, so can hold more than
+two values.)
+
+.item "opt@_fixed"
+This specifies a fixed point number, such as is used for load averages.
+The address should point to a variable of type \"int"\. The value is stored
+multiplied by 1000, so, for example, 1.4142 is truncated and stored as 1414.
+
+.item "opt@_int"
+This specifies an integer; the address should point to a variable of type
+\"int"\. The value may be specified in any of the integer formats accepted by
+Exim.
+
+.item "opt@_mkint"
+This is the same as \opt@_int\, except that when such a value is output in a
+\-bP-\ listing, if it is an exact number of kilobytes or megabytes, it is
+printed with the suffix K or M.
+
+.item "opt@_octint"
+This also specifies an integer, but the value is always interpeted as an
+octal integer, whether or not it starts with the digit zero, and it is
+always output in octal.
+
+.item "opt@_stringptr"
+This specifies a string value; the address must be a pointer to a
+variable that points to a string (for example, of type \"uschar $*$"\).
+
+.item "opt@_time"
+This specifies a time interval value. The address must point to a variable of
+type \"int"\. The value that is placed there is a number of seconds.
+
+.enditems
+
+If the \-bP-\ command line option is followed by \"local@_scan"\, Exim prints
+out the values of all the \*local@_scan()*\ options.
+
+
+.section Available Exim variables
+.index \*local@_scan()*\ function||available Exim variables
+The header \(local@_scan.h)\ gives you access to a number of C variables.
+These are the only ones that are guaranteed to be maintained from release to
+release. Note, however, that you can obtain the value of any Exim variable by
+calling \*expand@_string()*\. The exported variables are as follows:
+
+.startitems
+
+.item "unsigned int debug@_selector"
+This variable is set to zero when no debugging is taking place. Otherwise, it
+is a bitmap of debugging selectors. Two bits are identified for use in
+\*local@_scan()*\; they are defined as macros:
+.numberpars $.
+The \"D@_v"\ bit is set when \-v-\ was present on the command line. This is a
+testing option that is not privileged -- any caller may set it. All the
+other selector bits can be set only by admin users.
+.nextp
+The \"D@_local@_scan"\ bit is provided for use by \*local@_scan()*\; it is set
+by the \"+local@_scan"\ debug selector. It is not included in the default set
+of debugging bits.
+.endp
+Thus, to write to the debugging output only when \"+local@_scan"\ has been
+selected, you should use code like this:
+.display asis
+if ((debug_selector & D_local_scan) != 0)
+ debug_printf("xxx", ...);
+.endd
+
+.item "uschar *expand@_string@_message"
+After a failing call to \*expand@_string()*\ (returned value NULL), the
+variable \expand__string__message\ contains the error message, zero-terminated.
+
+.item "header@_line *header@_list"
+A pointer to a chain of header lines. The \header@_line\ structure is discussed
+below.
+
+.item "header@_line *header@_last"
+A pointer to the last of the header lines.
+
+.item "uschar *headers@_charset"
+The value of the \headers@_charset\ configuration option.
+
+.item "BOOL host@_checking"
+This variable is TRUE during a host checking session that is initiated by the
+\-bh-\ command line option.
+
+.item "uschar *interface@_address"
+The IP address of the interface that received the message, as a string. This
+is NULL for locally submitted messages.
+
+.item "int interface@_port"
+The port on which this message was received.
+
+.item "uschar *message@_id"
+This variable contains the message id for the incoming message as a
+zero-terminated string.
+
+
+.item "uschar *received@_protocol"
+The name of the protocol by which the message was received.
+
+.item "int recipients@_count"
+The number of accepted recipients.
+
+.item "recipient@_item *recipients@_list"
+.index recipient||adding in local scan
+.index recipient||removing in local scan
+The list of accepted recipients, held in a vector of length
+\recipients@_count\. The \recipient@_item\ structure is discussed below. You
+can add additional recipients by calling \*receive@_add@_recipient()*\ (see
+below). You can delete recipients by removing them from the vector and adusting
+the value in \recipients@_count\. In particular, by setting \recipients@_count\
+to zero you remove all recipients. If you then return the value
+\"LOCAL@_SCAN@_ACCEPT"\, the message is accepted, but immediately blackholed.
+To replace the recipients, set \recipients@_count\ to zero and then call
+\*receive@_add@_recipient()*\ as often as needed.
+
+.item "uschar *sender@_address"
+The envelope sender address. For bounce messages this is the empty string.
+
+.item "uschar *sender@_host@_address"
+The IP address of the sending host, as a string. This is NULL for
+locally-submitted messages.
+
+.item "uschar *sender@_host@_authenticated"
+The name of the authentication mechanism that was used, or NULL if the message
+was not received over an authenticated SMTP connection.
+
+.item "uschar *sender@_host@_name"
+The name of the sending host, if known.
+
+.item "int sender@_host@_port"
+The port on the sending host.
+
+.item "BOOL smtp@_input"
+This variable is TRUE for all SMTP input, including BSMTP.
+
+.item "BOOL smtp@_batched@_input"
+This variable is TRUE for BSMTP input.
+
+.item "int store@_pool"
+The contents of this variable control which pool of memory is used for new
+requests. See section ~~SECTmemhanloc for details.
+
+.enditems
+
+
+.section Structure of header lines
+The \header@_line\ structure contains the members listed below.
+You can add additional header lines by calling the \*header@_add()*\ function
+(see below). You can cause header lines to be ignored (deleted) by setting
+their type to $*$.
+
+.startitems
+
+.item "struct header@_line *next"
+A pointer to the next header line, or NULL for the last line.
+
+.item "int type"
+A code identifying certain headers that Exim recognizes. The codes are printing
+characters, and are documented in chapter ~~CHAPspool of this manual. Notice in
+particular that any header line whose type is $*$ is not transmitted with the
+message. This flagging is used for header lines that have been rewritten, or
+are to be removed (for example, ::Envelope-sender:: header lines.) Effectively,
+$*$ means `deleted'.
+
+.item "int slen"
+The number of characters in the header line, including the terminating and any
+internal newlines.
+
+.item "uschar *text"
+A pointer to the text of the header. It always ends with a newline, followed by
+a zero byte. Internal newlines are preserved.
+
+.enditems
+
+
+
+.section Structure of recipient items
+The \recipient@_item\ structure contains these members:
+
+.startitems
+
+.item "uschar *address"
+This is a pointer to the recipient address as it was received.
+
+.item "int pno"
+This is used in later Exim processing when top level addresses are created
+by the \one@_time\ option. It is not relevant at the time \*local@_scan()*\ is
+run and
+must always contain -1 at this stage.
+
+.item "uschar *errors@_to"
+If this value is not NULL, bounce messages caused by failing to deliver to the
+recipient are sent to the address it contains. In other words, it overrides the
+envelope sender for this one recipient. (Compare the \errors@_to\ generic
+router option.)
+If a \*local@_scan()*\ function sets an \errors@_to\ field to an unqualified
+address, Exim qualifies it using the domain from \qualify@_recipient\.
+When \*local@_scan()*\ is called, the \errors@_to\ field is NULL for all
+recipients.
+.enditems
+
+
+.section Available Exim functions
+.index \*local@_scan()*\ function||available Exim functions
+The header \(local@_scan.h)\ gives you access to a number of Exim functions.
+These are the only ones that are guaranteed to be maintained from release to
+release:
+
+.startitems
+
+.item "pid@_t child@_open(uschar **argv, uschar **envp, int newumask, int *infdptr, int *outfdptr, BOOL make@_leader)"
+This function creates a child process that runs the command specified by
+\argv\. The environment for the process is specified by \envp\, which can be
+NULL if no environment variables are to be passed. A new umask is supplied for
+the process in \newumask\.
+
+Pipes to the standard input and output of the new process are set up
+and returned to the caller via the \infdptr\ and \outfdptr\ arguments. The
+standard error is cloned to the standard output. If there are any file
+descriptors `in the way' in the new process, they are closed. If the final
+argument is TRUE, the new process is made into a process group leader.
+
+The function returns the pid of the new process, or -1 if things go wrong.
+
+
+.item "int child@_close(pid@_t pid, int timeout)"
+This function waits for a child process to terminate, or for a timeout (in
+seconds) to expire. A timeout value of zero means wait as long as it takes. The
+return value is as follows:
+.numberpars $.
+>= 0
+
+The process terminated by a normal exit and the value is the process ending
+status.
+.nextp
+< 0 and > --256
+
+The process was terminated by a signal and the value is the negation of the
+signal number.
+.nextp
+--256
+
+The process timed out.
+.nextp
+--257
+
+The was some other error in wait(); \errno\ is still set.
+.endp
+
+
+.item "pid@_t child@_open@_exim(int *fd)"
+This function provide you with a means of submitting a new message to
+Exim. (Of course, you can also call \(/usr/sbin/sendmail)\ yourself if you
+want, but this packages it all up for you.) The function creates a pipe,
+forks a subprocess that is running
+.display asis
+exim -t -oem -oi -f <>
+.endd
+and returns to you (via the \"int *"\ argument) a file descriptor for the pipe
+that is connected to the standard input. The yield of the function is the PID
+of the subprocess. You can then write a message to the file descriptor, with
+recipients in ::To::, ::Cc::, and/or ::Bcc:: header lines.
+
+When you have finished, call \*child@_close()*\ to wait for the process to
+finish and to collect its ending status. A timeout value of zero is usually
+fine in this circumstance. Unless you have made a mistake with the recipient
+addresses, you should get a return code of zero.
+
+.item "void debug@_printf(char *, ...)"
+This is Exim's debugging function, with arguments as for \*(printf()*\. The
+output is written to the standard error stream. If no debugging is selected,
+calls to \*debug@_printf()*\ have no effect. Normally, you should make calls
+conditional on the \"local@_scan"\ debug selector by coding like this:
+.display asis
+if ((debug_selector & D_local_scan) != 0)
+ debug_printf("xxx", ...);
+.endd
+
+.item "uschar *expand@_string(uschar *string)"
+This is an interface to Exim's string expansion code. The return value is the
+expanded string, or NULL if there was an expansion failure.
+The C variable \expand@_string@_message\ contains an error message after an
+expansion failure. If expansion does not change the string, the return value is
+the pointer to the input string. Otherwise, the return value points to a new
+block of memory that was obtained by a call to \*store@_get()*\. See section
+~~SECTmemhanloc below for a discussion of memory handling.
+
+.item "void header@_add(int type, char *format, ...)"
+This function allows you to add additional header lines. The first argument is
+the type, and should normally be a space character. The second argument is a
+format string and any number of substitution arguments as for \*sprintf()*\.
+You may include internal newlines if you want, and you must ensure that the
+string ends with a newline.
+
+.item "uschar *lss@_b64encode(uschar *cleartext, int length)"
+.index base64 encoding||functions for \*local@_scan()*\ use
+This function base64-encodes a string, which is passed by address and length.
+The text may contain bytes of any value, including zero. The result is passed
+back in dynamic memory that is obtained by calling \*store@_get()*\. It is
+zero-terminated.
+
+.item "int lss@_b64decode(uschar *codetext, uschar **cleartext)"
+This function decodes a base64-encoded string. Its arguments are a
+zero-terminated base64-encoded string and the address of a variable that is set
+to point to the result, which is in dynamic memory. The length of the
+decoded string is the yield of the function. If the input is invalid base64
+data, the yield is -1. A zero byte is added to the end of the output string to
+make it easy to interpret as a C string (assuming it contains no zeros of its
+own). The added zero byte is not included in the returned count.
+
+.item "int lss@_match@_domain(uschar *domain, uschar *list)"
+This function checks for a match in a domain list. Domains are always
+matched caselessly. The return value is one of the following:
+.display
+OK $rm{match succeeded}
+FAIL $rm{match failed}
+DEFER $rm{match deferred}
+.endd
+DEFER is usually caused by some kind of lookup defer, such as the
+inability to contact a database.
+
+.item "int lss@_match@_local@_part(uschar *localpart, uschar *list, BOOL caseless)"
+This function checks for a match in a local part list. The third argument
+controls case-sensitivity. The return values are as for
+\*lss@_match@_domain()*\.
+
+.item "int lss@_match@_address(uschar *address, uschar *list, BOOL caseless)"
+This function checks for a match in an address list. The third argument
+controls the case-sensitivity of the local part match. The domain is always
+matched caselessly. The return values are as for \*lss@_match@_domain()*\.
+
+.item "int lss@_match@_host(uschar *host@_name, uschar *host@_address, uschar *list)"
+This function checks for a match in a host list. The most common usage is
+expected to be
+.display asis
+lss_match_host(sender_host_name, sender_host_address, ...)
+.endd
+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.
+
+.item "void log@_write(unsigned int selector, int which, char *format, ...)"
+This function writes to Exim's log files. The first argument should be zero (it
+is concerned with \log@_selector\). The second argument can be \"LOG@_MAIN"\ or
+\"LOG@_REJECT"\ or
+\"LOG@_PANIC"\ or the inclusive `or' of any combination of them. It specifies
+to which log or logs the message is written.
+The remaining arguments are a format and relevant insertion arguments. The
+string should not contain any newlines, not even at the end.
+
+
+.item "void receive@_add@_recipient(uschar *address, int pno)"
+This function adds an additional recipient to the message. The first argument
+is the recipient address. If it is unqualified (has no domain), it is qualified
+with the \qualify@_recipient\ domain. The second argument must always be -1.
+
+This function does not allow you to specify a private \errors@_to\ address (as
+described with the structure of \recipient@_item\ above), because it pre-dates
+the addition of that field to the structure. However, it is easy to add such a
+value afterwards. For example:
+.display asis
+receive_add_recipient(US"monitor@mydom.example", -1);
+recipients_list[recipients_count-1].errors_to =
+ US"postmaster@mydom.example";
+.endd
+
+.item "uschar *rfc2047@_decode(uschar *string, BOOL lencheck, uschar *target, int zeroval, int *lenptr, uschar **error)"
+This function decodes strings that are encoded according to RFC 2047. Typically
+these are the contents of header lines. First, each encoded `word' is decoded
+from the Q or B encoding into a byte-string. Then, if provided with the name of
+a charset encoding, and if the \*iconv()*\ function is available, an attempt is
+made to translate the result to the named character set. If this fails, the
+binary string is returned with an error message.
+
+The first argument is the string to be decoded. If \lencheck\ is TRUE, the
+maximum MIME word length is enforced. The third argument is the target
+encoding, or NULL if no translation is wanted.
+
+.index binary zero||in RFC 2047 decoding
+If a binary zero is encountered in the decoded string, it is replaced by the
+contents of the \zeroval\ argument. For use with Exim headers, the value must
+not be 0 because header lines are handled as zero-terminated strings.
+
+The function returns the result of processing the string, zero-terminated; if
+\lenptr\ is not NULL, the length of the result is set in the variable to which
+it points. When \zeroval\ is 0, \lenptr\ should not be NULL.
+
+If an error is encountered, the function returns NULL and uses the \error\
+argument to return an error message. The variable pointed to by \error\ is set
+to NULL if there is no error; it may be set non-NULL even when the function
+returns a non-NULL value if decoding was successful, but there was a problem
+with translation.
+
+
+.item "int smtp@_fflush(void)"
+This function is used in conjunction with \*smtp@_printf()*\, as described
+below.
+
+.item "void smtp@_printf(char *, ...)"
+The arguments of this function are like \*printf()*\; it writes to the SMTP
+output stream. You should use this function only when there is an SMTP output
+stream, that is, when the incoming message is being received via interactive
+SMTP. This is the case when \smtp@_input\ is TRUE and \smtp@_batched@_input\ is
+FALSE. If you want to test for an incoming message from another host (as
+opposed to a local process that used the \-bs-\ command line option), you can
+test the value of \sender@_host@_address\, which is non-NULL when a remote host
+is involved.
+
+If an SMTP TLS connection is established, \*smtp@_printf()*\ uses the TLS
+output function, so it can be used for all forms of SMTP connection.
+
+Strings that are written by \*smtp@_printf()*\ from within \*local@_scan()*\
+must start with an appropriate response code: 550 if you are going to return
+\\LOCAL@_SCAN@_REJECT\\, 451 if you are going to return
+\\LOCAL@_SCAN@_TEMPREJECT\\, and 250 otherwise. Because you are writing the
+initial lines of a multi-line response, the code must be followed by a hyphen
+to indicate that the line is not the final response line. You must also ensure
+that the lines you write terminate with CRLF. For example:
+.display asis
+smtp_printf("550-this is some extra info\r\n");
+return LOCAL_SCAN_REJECT;
+.endd
+Note that you can also create multi-line responses by including newlines in
+the data returned via the \return@_text\ argument. The added value of using
+\*smtp@_printf()*\ is that, for instance, you could introduce delays between
+multiple output lines.
+
+The \*smtp@_printf()*\ function does not return any error indication, because it
+does not automatically flush pending output, and therefore does not test
+the state of the stream. (In the main code of Exim, flushing and error
+detection is done when Exim is ready for the next SMTP input command.) If
+you want to flush the output and check for an error (for example, the
+dropping of a TCP/IP connection), you can call \*smtp@_fflush()*\, which has no
+arguments. It flushes the output stream, and returns a non-zero value if there
+is an error.
+
+.item "void *store@_get(int)"
+This function accesses Exim's internal store (memory) manager. It gets a new
+chunk of memory whose size is given by the argument. Exim bombs out if it ever
+runs out of memory. See the next section for a discussion of memory handling.
+
+.item "void *store@_get@_perm(int)"
+This function is like \*store@_get()*\, but it always gets memory from the
+permanent pool. See the next section for a discussion of memory handling.
+
+.item "uschar *string@_copy(uschar *string)"
+.item "uschar *string@_copyn(uschar *string, int length)" 0
+.item "uschar *string@_sprintf(char *format, ...)" 0
+These three functions create strings using Exim's dynamic memory facilities.
+The first makes a copy of an entire string. The second copies up to a maximum
+number of characters, indicated by the second argument. The third uses a format
+and insertion arguments to create a new string. In each case, the result is a
+pointer to a new string
+in the current memory pool. See the next section for more discussion.
+
+.enditems
+
+
+
+.section More about Exim's memory handling
+.rset SECTmemhanloc "~~chapter.~~section"
+.index \*local@_scan()*\ function||memory handling
+No function is provided for freeing memory, because that is never needed.
+The dynamic memory that Exim uses when receiving a message is automatically
+recycled if another message is received by the same process (this applies only
+to incoming SMTP connections -- other input methods can supply only one message
+at a time). After receiving the last message, a reception process terminates.
+
+Because it is recycled, the normal dynamic memory cannot be used for holding
+data that must be preserved over a number of incoming messages on the same SMTP
+connection. However, Exim in fact uses two pools of dynamic memory; the second
+one is not recycled, and can be used for this purpose.
+
+If you want to allocate memory that remains available for subsequent messages
+in the same SMTP connection, you should set
+.display asis
+store_pool = POOL_PERM
+.endd
+before calling the function that does the allocation. There is no need to
+restore the value if you do not need to; however, if you do want to revert to
+the normal pool, you can either restore the previous value of \store@_pool\ or
+set it explicitly to \\POOL@_MAIN\\.
+
+The pool setting applies to all functions that get dynamic memory, including
+\*expand@_string()*\, \*store@_get()*\, and the \*string@_xxx()*\ functions.
+There is also a convenience function called \*store@_get@_perm()*\ that gets a
+block of memory from the permanent pool while preserving the value of
+\store@_pool\.
+
+
+
+
+
+.
+.
+.
+.
+. ============================================================================
+.chapter System-wide message filtering
+.set runningfoot "system filtering"
+.rset CHAPsystemfilter "~~chapter"
+.index filter||system filter
+.index filtering all mail
+.index system filter
+The previous chapters (on ACLs and the local scan function) describe checks
+that can be applied to messages before they are accepted by a host. There is
+also a mechanism for checking messages once they have been received, but before
+they are delivered. This is called the $it{system filter}.
+
+The system filter operates in a similar manner to users' filter files, but it
+is run just once per message (however many recipients the message has).
+It should not normally be used as a substitute for routing, because \deliver\
+commands in a system router provide new envelope recipient addresses.
+The system filter must be an Exim filter. It cannot be a Sieve filter.
+
+The system filter is run at the start of a delivery attempt, before any routing
+is done. If a message fails to be completely delivered at the first attempt,
+the system filter is run again at the start of every retry.
+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.
+
+\**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
+want to run a centrally-specified filter for each recipient address
+independently, you can do so by setting up a suitable \%redirect%\ router, as
+described in section ~~SECTperaddfil below.
+
+.section Specifying a system filter
+.index uid (user id)||system filter
+.index gid (group id)||system filter
+The name of the file that contains the system filter must be specified by
+setting \system@_filter\. If you want the filter to run under a uid and gid
+other than root, you must also set \system@_filter@_user\ and
+\system@_filter@_group\ as appropriate. For example:
+.display asis
+system_filter = /etc/mail/exim.filter
+system_filter_user = exim
+.endd
+If a system filter generates any deliveries directly to files or pipes (via the
+\save\ or \pipe\ commands), transports to handle these deliveries must be
+specified by setting \system@_filter@_file@_transport\ and
+\system@_filter@_pipe@_transport\, respectively. Similarly,
+\system@_filter@_reply@_transport\ must be set to handle any messages generated
+by the \reply\ command.
+
+.section Testing a system filter
+You can run simple tests of a system filter in the same way as for a user
+filter, but you should use \-bF-\ rather than \-bf-\, so that features that
+are permitted only in system filters are recognized.
+
+.section Contents of a system filter
+The language used to specify system filters is the same as for users' filter
+files. It is described in the separate end-user document \*Exim's interface to
+mail filtering*\. However, there are some additional features that are
+available only in system filters; these are described in subsequent sections.
+If they are encountered in a user's filter file or when testing with \-bf-\,
+they cause errors.
+
+.index frozen messages||manual thaw, testing in filter
+There are two special conditions which, though available in users' filter
+files, are designed for use in system filters. The condition \first@_delivery\
+is true only for the first attempt at delivering a message, and
+\manually@_thawed\ is true only if the message has been frozen, and
+subsequently thawed by an admin user. An explicit forced delivery counts as a
+manual thaw, but thawing as a result of the \auto__thaw\ setting does not.
+
+\**Warning**\: If a system filter uses the \first@_delivery\ condition to
+specify an `unseen' (non-significant) delivery, and that delivery does not
+succeed, it will not be tried again.
+If you want Exim to retry an unseen delivery until it succeeds, you should
+arrange to set it up every time the filter runs.
+
+When a system filter finishes running, the values of the variables \$n0$\ --
+\$n9$\ are copied into \$sn0$\ -- \$sn9$\ and are thereby made available to
+users' filter files. Thus a system filter can, for example, set up `scores' to
+which users' filter files can refer.
+
+
+.section Additional variable for system filters
+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.
+
+
+.section Defer, freeze, and fail commands for system filters
+.index freezing messages
+.index message||freezing
+.index message||forced failure
+.index \fail\||in system filter
+.index \freeze\ in system filter
+.index \defer\ in system filter
+There are three extra commands (\defer\, \freeze\ and \fail\) which are always
+available in system filters, but are not normally enabled in users' filters.
+(See the \allow@_defer\,
+\allow@_freeze\ and \allow@_fail\ options for the \%redirect%\ router.) These
+commands can optionally be followed by the word \text\ and a string containing
+an error message, for example:
+.display asis
+fail text "this message looks like spam to me"
+.endd
+The keyword \text\ is optional if the next character is a double quote.
+
+The \defer\ command defers delivery of the original recipients of the message.
+The \fail\ command causes all the original recipients to be failed, and a
+bounce message to be created. The \freeze\ command suspends all delivery
+attempts for the original recipients. In all cases, any new deliveries that are
+specified by the filter are attempted as normal after the filter has run.
+
+The \freeze\ command is ignored if the message has been manually unfrozen and
+not manually frozen since. This means that automatic freezing by a system
+filter can be used as a way of checking out suspicious messages. If a message
+is found to be all right, manually unfreezing it allows it to be delivered.
+
+.index log||\fail\ command log line
+.index \fail\||log line, reducing
+The text given with a fail command is used as part of the bounce message as
+well as being written to the log. If the message is quite long, this can fill
+up a lot of log space when such failures are common. To reduce the size of the
+log message, Exim interprets the text in a special way if it starts with the
+two characters \"@<@<"\ and contains \"@>@>"\ later. The text between these two
+strings is written to the log, and the rest of the text is used in the bounce
+message. For example:
+.display asis
+fail "<<filter test 1>>Your message is rejected \
+ because it contains attachments that we are \
+ not prepared to receive."
+.endd
+
+.index loop||caused by \fail\
+Take great care with the \fail\ command when basing the decision to fail on the
+contents of the message, because the bounce message will of course include the
+contents of the original message and will therefore trigger the \fail\ command
+again (causing a mail loop) unless steps are taken to prevent this. Testing the
+\error@_message\ condition is one way to prevent this. You could use, for
+example
+.display asis
+if $message_body contains "this is spam" and not error_message
+ then fail text "spam is not wanted here" endif
+.endd
+though of course that might let through unwanted bounce messages. The
+alternative is clever checking of the body and/or headers to detect bounces
+generated by the filter.
+
+The interpretation of a system filter file ceases after a
+\defer\,
+\freeze\, or \fail\ command is obeyed. However, any deliveries that were set up
+earlier in the filter file are honoured, so you can use a sequence such as
+.display asis
+mail ...
+freeze
+.endd
+to send a specified message when the system filter is freezing (or deferring or
+failing) a message. The normal deliveries for the message do not, of course,
+take place.
+
+
+.section Adding and removing headers in a system filter
+.index header lines||adding in system filter
+.index header lines||removing in system filter
+.index filter||header lines, adding/removing
+Two filter commands that are available only in system filters are:
+.display asis
+headers add <<string>>
+headers remove <<string>>
+.endd
+The argument for the \headers add\ is a string which is expanded and then added
+to the end of the message's headers. It is the responsibility of the filter
+maintainer to make sure it conforms to RFC 2822 syntax. Leading white space is
+ignored, and if the string is otherwise empty, or if the expansion is forced to
+fail, the command has no effect.
+
+If the message is not delivered at the first attempt, header lines that were
+added by the system filter are stored with the message, and so are still
+present at the next delivery attempt. For that reason, it is usual to make the
+\headers add\ command conditional on \first@_delivery\.
+
+.em
+You can use `@\n' within the string, followed by white space, to specify
+continued header lines. More than one header may be added in one command by
+including `@\n' within the string without any following white space. For
+example:
+.display asis
+headers add "X-header-1: ....\n \
+ continuation of X-header-1 ...\n\
+ X-header-2: ...."
+.endd
+Note that the header line continuation white space after the first newline must
+be placed before the backslash that continues the input string, because white
+space after input continuations is ignored.
+
+Header lines that are added by a system filter are visible to users' filter
+files and to all routers and transports.
+.nem
+
+The argument for \headers remove\ is a colon-separated list of header names.
+This command applies only to those headers that are stored with the message;
+those that are added at delivery time (such as ::Envelope-To:: and
+::Return-Path::) cannot be removed by this means.
+If there is more than one header with the same name, they are all removed.
+
+
+.section Setting an errors address in a system filter
+.index envelope sender
+In a system filter, if a \deliver\ command is followed by
+.display
+errors@_to <<some address>>
+.endd
+in order to change the envelope sender (and hence the error reporting) for that
+delivery, any address may be specified. (In a user filter, only the current
+user's address can be set.) For example, if some mail is being monitored, you
+might use
+.display asis
+unseen deliver monitor@spying.example errors_to root@local.example
+.endd
+to take a copy which would not be sent back to the normal error reporting
+address if its delivery failed.
+
+
+.section Per-address filtering
+.rset SECTperaddfil "~~chapter.~~section"
+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
+such as \$local@_part$\ and \$domain$\ can be used, and indeed, the choice of
+filter file could be made dependent on them. This is an example of a router
+which implements such a filter:
+.display asis
+central_filter:
+.newline
+.em
+ check_local_user
+.newline
+.nem
+ driver = redirect
+ domains = +local_domains
+ file = /central/filters/$local_part
+ no_verify
+ allow_filter
+ allow_freeze
+.endd
+.em
+The filter is run in a separate process under its own uid. Therefore, either
+\check@_local@_user\ must be set (as above), in which case the filter is run as
+the local user, or the \user\ option must be used to specify which user to use.
+If both are set, \user\ overrides.
+.nem
+
+Care should be taken to ensure that none of the commands in the filter file
+specify a significant delivery if the message is to go on to be delivered to
+its intended recipient. The router will not then claim to have dealt with the
+address, so it will be passed on to subsequent routers to be delivered in the
+normal way.
+
+
+
+
+
+.
+.
+.
+.
+. ============================================================================
+.chapter Customizing bounce and warning messages
+.set runningfoot "customizing messages"
+.rset CHAPemsgcust "~~chapter"
+When a message fails to be delivered, or remains on the queue for more than a
+configured amount of time, Exim sends a message to the original sender, or
+to an alternative configured address. The text of these messages is built into
+the code of Exim, but it is possible to change it, either by adding a single
+string, or by replacing each of the paragraphs by text supplied in a file.
+
+The ::From:: and ::To:: header lines are automatically generated; you can cause
+a ::Reply-To:: line to be added by setting the \errors@_reply@_to\ option. Exim
+also adds the line
+.display asis
+Auto-Submitted: auto-generated
+.endd
+to all warning and bounce messages,
+
+.section Customizing bounce messages
+.index customizing||bounce message
+.index bounce message||customizing
+If \bounce@_message@_text\ is set, its contents are included in the default
+message immediately after `This message was created automatically by mail
+delivery software.' The string is not expanded. It is not used if
+\bounce@_message@_file\ is set.
+
+When \bounce@_message@_file\ is set, it must point to a template file for
+constructing error messages. The file consists of a series of text items,
+separated by lines consisting of exactly four asterisks. If the file cannot be
+opened, default text is used and a message is written to the main and panic
+logs. If any text item in the file is empty, default text is used for that
+item.
+
+Each item of text that is read from the file is expanded, and there are two
+expansion variables which can be of use here: \$bounce@_recipient$\ is set to
+the recipient of an error message while it is being created, and
+\$return@_size@_limit$\ contains the value of the \return@_size@_limit\ option,
+rounded to a whole number.
+
+The items must appear in the file in the following order:
+.numberpars $.
+The first item is included in the headers, and should include at least a
+::Subject:: header. Exim does not check the syntax of these headers.
+.nextp
+The second item forms the start of the error message. After it, Exim lists the
+failing addresses with their error messages.
+.nextp
+The third item is used to introduce any text from pipe transports that is to be
+returned to the sender. It is omitted if there is no such text.
+.nextp
+The fourth item is used to introduce the copy of the message that is returned
+as part of the error report.
+.nextp
+The fifth item is added after the fourth one if the returned message is
+truncated because it is bigger than \return@_size@_limit\.
+.nextp
+The sixth item is added after the copy of the original message.
+.endp
+The default state (\bounce@_message@_file\ unset) is equivalent to the
+following file, in which the sixth item is empty. The ::Subject:: line has been
+split into two here in order to fit it on the page:
+.if ~~sys.fancy
+.display flow asis
+.fontgroup 0
+.font 54
+.else
+.rule
+.display flow asis
+.linelength 80em
+.indent 0
+.fi
+Subject: Mail delivery failed
+ ${if eq{$sender_address}{$bounce_recipient}{: returning message to sender}}
+****
+This message was created automatically by mail delivery software.
+
+A message ${if eq{$sender_address}{$bounce_recipient}{that you sent }{sent by
+
+ <$sender_address>
+
+}}could not be delivered to all of its recipients.
+The following address(es) failed:
+****
+The following text was generated during the delivery attempt(s):
+****
+------ This is a copy of the message, including all the headers. ------
+****
+------ The body of the message is $message_size characters long; only the first
+------ $return_size_limit or so are included here.
+****
+.endd
+.if !~~sys.fancy
+.rule
+.fi
+
+.section Customizing warning messages
+.rset SECTcustwarn "~~chapter.~~section"
+.index customizing||warning message
+.index warning of delay||customizing the message
+The option
+\warn@_message@_file\
+can be pointed at a template file for use when
+warnings about message delays are created. In this case there are only three
+text sections:
+.numberpars $.
+The first item is included in the headers, and should include at least a
+::Subject:: header. Exim does not check the syntax of these headers.
+.nextp
+The second item forms the start of the warning message. After it, Exim lists
+the delayed addresses.
+.nextp
+The third item then ends the message.
+.endp
+The default state is equivalent to the following file, except that the line
+starting `A message' has been split here, in order to fit it on the page:
+.if ~~sys.fancy
+.display asis
+.fontgroup 0
+.font 54
+.else
+.rule
+.display asis
+.linelength 80em
+.indent 0
+.fi
+.newline
+Subject: Warning: message $message_id delayed $warn_message_delay
+****
+This message was created automatically by mail delivery software.
+
+A message ${if eq{$sender_address}{$warn_message_recipients}
+ {that you sent }{sent by
+
+ <$sender_address>
+
+}}has not been delivered to all of its recipients after
+more than $warn_message_delay on the queue on $primary_hostname.
+.newline
+
+The message identifier is: $message_id
+The subject of the message is: $h_subject
+The date of the message is: $h_date
+
+The following address(es) have not yet been delivered:
+****
+No action is required on your part. Delivery attempts will continue for
+some time, and this warning may be repeated at intervals if the message
+remains undelivered. Eventually the mail delivery software will give up,
+and when that happens, the message will be returned to you.
+.endd
+.if !~~sys.fancy
+.rule
+.fi
+except that in the default state the subject and date lines are omitted if no
+appropriate headers exist. During the expansion of this file,
+\$warn@_message@_delay$\
+is set to the delay time in one of the forms `<<n>> minutes'
+or `<<n>> hours', and
+\$warn@_message@_recipients$\
+contains a list of recipients for the warning message. There may be more than
+one if there are multiple addresses with different \errors@_to\ settings on the
+routers that handled them.
+
+
+
+
+.
+.
+.
+. ============================================================================
+.chapter Some common configuration requirements
+.set runningfoot "common configuration requirements"
+.rset CHAPcomconreq "~~chapter"
+This chapter discusses some configuration requirements that seem to be fairly
+common. More examples and discussion can be found in the Exim book.
+
+
+.section Sending mail to a smart host
+.index smart host||example router
+If you want to send all mail for non-local domains to a `smart host', you
+should replace the default \%dnslookup%\ router with a router which does the
+routing explicitly:
+.display asis
+send_to_smart_host:
+ driver = manualroute
+ route_list = !+local_domains smart.host.name
+ transport = remote_smtp
+.endd
+You can use the smart host's IP address instead of the name if you wish.
+
+
+.section Using Exim to handle mailing lists
+.rset SECTmailinglists "~~chapter.~~section"
+.index mailing lists
+Exim can be used to run simple mailing lists, but for large and/or complicated
+requirements, the use of additional specialized mailing list software such as
+Majordomo or Mailman is recommended.
+
+The \%redirect%\ router can be used to handle mailing lists where each list
+is maintained in a separate file, which can therefore be managed by an
+independent manager. The \domains\ router option can be used to run these
+lists in a separate domain from normal mail. For example:
+.display asis
+lists:
+ driver = redirect
+ domains = lists.example
+ file = /usr/lists/$local_part
+ forbid_pipe
+ forbid_file
+ errors_to = $local_part-request@lists.example
+ no_more
+.endd
+This router is skipped for domains other than \*lists.example*\. For addresses
+in that domain, it looks for a file that matches the local part. If there is no
+such file, the router declines, but because \no@_more\ is set, no subsequent
+routers are tried, and so the whole delivery fails.
+
+The \forbid@_pipe\ and \forbid@_file\ options prevent a local part from being
+expanded into a file name or a pipe delivery, which is usually inappropriate in
+a mailing list.
+
+.index \errors@_to\
+The \errors@_to\ option specifies that any delivery errors caused by addresses
+taken from a mailing list are to be sent to the given address rather than the
+original sender of the message. However, before acting on this, Exim verifies
+the error address, and ignores it if verification fails.
+
+For example, using the configuration above, mail sent to
+\*dicts@@lists.example*\ is passed on to those addresses contained in
+\(/usr/lists/dicts)\, with error reports directed to
+\*dicts-request@@lists.example*\, provided that this address can be verified.
+There could be a file called \(/usr/lists/dicts-request)\ containing
+the address(es) of this particular list's manager(s), but other approaches,
+such as setting up an earlier router (possibly using the \local@_part@_prefix\
+or \local@_part@_suffix\ options) to handle addresses of the form \owner-xxx\
+or \xxx-request\, are also possible.
+
+
+.section Syntax errors in mailing lists
+.index mailing lists||syntax errors in
+If an entry in redirection data contains a syntax error, Exim normally defers
+delivery of the original address. That means that a syntax error in a mailing
+list holds up all deliveries to the list. This may not be appropriate when a
+list is being maintained automatically from data supplied by users, and the
+addresses are not rigorously checked.
+
+If the \skip@_syntax@_errors\ option is set, the \%redirect%\ router just skips
+entries that fail to parse, noting the incident in the log. If in addition
+\syntax@_errors@_to\ is set to a verifiable address, a message is sent to it
+whenever a broken address is skipped. It is usually appropriate to set
+\syntax@_errors@_to\ to the same address as \errors@_to\.
+
+
+.section Re-expansion of mailing lists
+.index mailing lists||re-expansion of
+Exim remembers every individual address to which a message has been delivered,
+in order to avoid duplication, but it normally stores only the original
+recipient addresses with a message. If all the deliveries to a mailing list
+cannot be done at the first attempt, the mailing list is re-expanded when the
+delivery is next tried. This means that alterations to the list are taken into
+account at each delivery attempt, so addresses that have been added to
+the list since the message arrived will therefore receive a copy of the
+message, even though it pre-dates their subscription.
+
+If this behaviour is felt to be undesirable, the \one@_time\ option can be set
+on the \%redirect%\ router. If this is done, any addresses generated by the
+router that fail to deliver at the first attempt are added to the message as
+`top level' addresses, and the parent address that generated them is marked
+`delivered'. Thus, expansion of the mailing list does not happen again at the
+subsequent delivery attempts. The disadvantage of this is that if any of the
+failing addresses are incorrect, correcting them in the file has no effect on
+pre-existing messages.
+
+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 the
+\all@_parents\ selector is set, but for mailing lists there is normally only
+one level of expansion anyway.
+
+
+.section Closed mailing lists
+.index mailing lists||closed
+The examples so far have assumed open mailing lists, to which anybody may
+send mail. It is also possible to set up closed lists, where mail is accepted
+from specified senders only. This is done by making use of the generic
+\senders\ option to restrict the router that handles the list.
+
+The following example uses the same file as a list of recipients and as a list
+of permitted senders. It requires three routers:
+.display asis
+lists_request:
+ driver = redirect
+ domains = lists.example
+ local_part_suffix = -request
+ file = /usr/lists/$local_part$local_part_suffix
+ no_more
+
+lists_post:
+ driver = redirect
+ domains = lists.example
+ senders = ${if exists {/usr/lists/$local_part}\
+ {lsearch;/usr/lists/$local_part}{*}}
+ file = /usr/lists/$local_part
+ forbid_pipe
+ forbid_file
+ errors_to = $local_part-request@lists.example
+ no_more
+
+lists_closed:
+ driver = redirect
+ domains = lists.example
+ allow_fail
+ data = :fail: $local_part@lists.example is a closed mailing list
+.endd
+All three routers have the same \domains\ setting, so for any other domains,
+they are all skipped. The first router runs only if the local part ends in
+\@-request\. It handles messages to the list manager(s) by means of an open
+mailing list.
+
+The second router runs only if the \senders\ precondition is satisfied. It
+checks for the existence of a list that corresponds to the local part, and then
+checks that the sender is on the list by means of a linear search. It is
+necessary to check for the existence of the file before trying to search it,
+because otherwise Exim thinks there is a configuration error. If the file does
+not exist, the expansion of \senders\ is $*$, which matches all senders. This
+means that the router runs, but because there is no list, declines, and
+\no@_more\ ensures that no further routers are run. The address fails with an
+`unrouteable address' error.
+
+The third router runs only if the second router is skipped, which happens when
+a mailing list exists, but the sender is not on it. This router forcibly fails
+the address, giving a suitable error message.
+
+
+
+.section Virtual domains
+.rset SECTvirtualdomains "~~chapter.~~section"
+.index virtual domains
+.index domain||virtual
+The phrase \*virtual domain*\ is unfortunately used with two rather different
+meanings:
+.numberpars $.
+A domain for which there are no real mailboxes; all valid local parts are
+aliases for other email addresses. Common examples are organizational
+top-level domains and `vanity' domains.
+.nextp
+One of a number of independent domains that are all handled by the same host,
+with mailboxes on that host, but where the mailbox owners do not necessarily
+have login accounts on that host.
+.endp
+The first usage is probably more common, and does seem more `virtual' than the
+second. This kind of domain can be handled in Exim with a straightforward
+aliasing router. One approach is to create a separate alias file for each
+virtual domain. Exim can test for the existence of the alias file to determine
+whether the domain exists. The \%dsearch%\ lookup type is useful here, leading
+to a router of this form:
+.display asis
+virtual:
+ driver = redirect
+ domains = dsearch;/etc/mail/virtual
+ data = ${lookup{$local_part}lsearch{/etc/mail/virtual/$domain}}
+ no_more
+.endd
+The \domains\ option specifies that the router is to be skipped, unless there
+is a file in the \(/etc/mail/virtual)\ directory whose name is the same as the
+domain that is being processed. When the router runs, it looks up the local
+part in the file to find a new address (or list of addresses). The \no@_more\
+setting ensures that if the lookup fails (leading to \data\ being an empty
+string), Exim gives up on the address without trying any subsequent routers.
+
+This one router can handle all the virtual domains because the alias file names
+follow a fixed pattern. Permissions can be arranged so that appropriate people
+can edit the different alias files. A successful aliasing operation results in
+a new envelope recipient address, which is then routed from scratch.
+
+The other kind of `virtual' domain can also be handled in a straightforward
+way. One approach is to create a file for each domain containing a list of
+valid local parts, and use it in a router like this:
+.display asis
+my_domains:
+ driver = accept
+ domains = dsearch;/etc/mail/domains
+ local_parts = lsearch;/etc/mail/domains/$domain
+ transport = my_mailboxes
+.endd
+The address is accepted if there is a file for the domain, and the local part
+can be found in the file. The \domains\ option is used to check for the file's
+existence because \domains\ is tested before the \local@_parts\ option (see
+section ~~SECTrouprecon). You can't use \require@_files\, because that option
+is tested after \local@_parts\. The transport is as follows:
+.display asis
+my_mailboxes:
+ driver = appendfile
+ file = /var/mail/$domain/$local_part
+ user = mail
+.endd
+This uses a directory of mailboxes for each domain. The \user\ setting is
+required, to specify which uid is to be used for writing to the mailboxes.
+
+The configuration shown here is just one example of how you might support this
+requirement. There are many other ways this kind of configuration can be set
+up, for example, by using a database instead of separate files to hold all the
+information about the domains.
+
+
+.section Multiple user mailboxes
+.rset SECTmulbox "~~chapter.~~section"
+.index multiple mailboxes
+.index mailbox||multiple
+.index local part||prefix
+.index local part||suffix
+Heavy email users often want to operate with multiple mailboxes, into which
+incoming mail is automatically sorted. A popular way of handling this is to
+allow users to use multiple sender addresses, so that replies can easily be
+identified. Users are permitted to add prefixes or suffixes to their local
+parts for this purpose. The wildcard facility of the generic router options
+\local@_part@_prefix\ and \local@_part@_suffix\ can be used for this. For
+example, consider this router:
+.display asis
+userforward:
+ driver = redirect
+ check_local_user
+ file = $home/.forward
+ local_part_suffix = -*
+ local_part_suffix_optional
+ allow_filter
+.endd
+It runs a user's \(.forward)\ file for all local parts of the form
+\*username-$*$*\. Within the filter file the user can distinguish different
+cases by testing the variable \$local@_part@_suffix$\. For example:
+.display asis
+if $local_part_suffix contains -special then
+ save /home/$local_part/Mail/special
+endif
+.endd
+If the filter file does not exist, or does not deal with such addresses, they
+fall through to subsequent routers, and, assuming no subsequent use of the
+\local@_part@_suffix\ option is made, they presumably fail. Thus, users have
+control over which suffixes are valid.
+
+Alternatively, a suffix can be used to trigger the use of a different
+\(.forward)\ file -- which is the way a similar facility is implemented in
+another MTA:
+.display asis
+userforward:
+ driver = redirect
+ check_local_user
+ file = $home/.forward$local_part_suffix
+ local_part_suffix = -*
+ local_part_suffix_optional
+ allow_filter
+.endd
+If there is no suffix, \(.forward)\ is used; if the suffix is \*-special*\, for
+example, \(.forward-special)\ is used. Once again, if the appropriate file
+does not exist, or does not deal with the address, it is passed on to
+subsequent routers, which could, if required, look for an unqualified
+\(.forward)\ file to use as a default.
+
+
+.section Simplified vacation processing
+.index vacation processing
+The traditional way of running the \*vacation*\ program is for a user to set up
+a pipe command in a \(.forward)\ file
+(see section ~~SECTspecitredli for syntax details).
+This is prone to error by inexperienced users. There are two features of Exim
+that can be used to make this process simpler for users:
+.numberpars $.
+A local part prefix such as `vacation-' can be specified on a router which
+can cause the message to be delivered directly to the \*vacation*\ program, or
+alternatively can use Exim's \%autoreply%\ transport. The contents of a user's
+\(.forward)\ file are then much simpler. For example:
+.display asis
+spqr, vacation-spqr
+.endd
+.nextp
+The \require@_files\ generic router option can be used to trigger a
+vacation delivery by checking for the existence of a certain file in the
+user's home directory. The \unseen\ generic option should also be used, to
+ensure that the original delivery also proceeds. In this case, all the user has
+to do is to create a file called, say, \(.vacation)\, containing a vacation
+message.
+.endp
+Another advantage of both these methods is that they both work even when the
+use of arbitrary pipes by users is locked out.
+
+
+.section Taking copies of mail
+.index message||copying every
+Some installations have policies that require archive copies of all messages to
+be made. A single copy of each message can easily be taken by an appropriate
+command in a system filter, which could, for example, use a different file for
+each day's messages.
+
+There is also a shadow transport mechanism that can be used to take copies of
+messages that are successfully delivered by local transports, one copy per
+delivery. This could be used, $it{inter alia}, to implement automatic
+notification of delivery by sites that insist on doing such things.
+
+
+.section Intermittently connected hosts
+.index intermittently connected hosts
+It has become quite common (because it is cheaper) for hosts to connect to the
+Internet periodically rather than remain connected all the time. The normal
+arrangement is that mail for such hosts accumulates on a system that is
+permanently connected.
+
+Exim was designed for use on permanently connected hosts, and so it is not
+particularly well-suited to use in an intermittently connected environment.
+Nevertheless there are some features that can be used.
+
+.section Exim on the upstream server host
+It is tempting to arrange for incoming mail for the intermittently connected
+host to remain on Exim's queue until the client connects. However, this
+approach does not scale very well. Two different kinds of waiting message are
+being mixed up in the same queue -- those that cannot be delivered because of
+some temporary problem, and those that are waiting for their destination host
+to connect. This makes it hard to manage the queue, as well as wasting
+resources, because each queue runner scans the entire queue.
+
+A better approach is to separate off those messages that are waiting for an
+intermittently connected host. This can be done by delivering these messages
+into local files in batch SMTP, `mailstore', or other envelope-preserving
+format, from where they are transmitted by other software when their
+destination connects. This makes it easy to collect all the mail for one host
+in a single directory, and to apply local timeout rules on a per-message basis
+if required.
+
+On a very small scale, leaving the mail on Exim's queue can be made to work. If
+you are doing this, you should configure Exim with a long retry period for the
+intermittent host. For example:
+.display
+cheshire.wonderland.fict.example * F,5d,24h
+.endd
+This stops a lot of failed delivery attempts from occurring, but Exim remembers
+which messages it has queued up for that host. Once the intermittent host comes
+online, forcing delivery of one message (either by using the \-M-\ or \-R-\
+options, or by using the \\ETRN\\ SMTP command (see section ~~SECTETRN)
+causes all the queued up messages to be delivered, often down a single SMTP
+connection. While the host remains connected, any new messages get delivered
+immediately.
+
+If the connecting hosts do not have fixed IP addresses, that is, if a host is
+issued with a different IP address each time it connects, Exim's retry
+mechanisms on the holding host get confused, because the IP address is normally
+used as part of the key string for holding retry information. This can be
+avoided by unsetting \retry__include__ip__address\ on the \%smtp%\ transport.
+Since this has disadvantages for permanently connected hosts, it is best to
+arrange a separate transport for the intermittently connected ones.
+
+
+.section Exim on the intermittently connected client host
+The value of \smtp@_accept@_queue@_per@_connection\ should probably be
+increased, or even set to zero (that is, disabled) on the intermittently
+connected host, so that all incoming messages down a single connection get
+delivered immediately.
+
+.index SMTP||passed connection
+.index SMTP||multiple deliveries
+.index multiple SMTP deliveries
+Mail waiting to be sent from an intermittently connected host will probably
+not have been routed, because without a connection DNS lookups are not
+possible. This means that if a normal queue run is done at connection time,
+each message is likely to be sent in a separate SMTP session. This can be
+avoided by starting the queue run with a command line option beginning with
+\-qq-\ instead of \-q-\. In this case, the queue is scanned twice. In the first
+pass, routing is done but no deliveries take place. The second pass is a normal
+queue run; since all the messages have been previously routed, those destined
+for the same host are likely to get sent as multiple deliveries in a single
+SMTP connection.
+
+
+
+
+
+.
+.
+.
+.
+. ============================================================================
+.chapter SMTP processing
+.set runningfoot "smtp processing"
+.rset CHAPSMTP ~~chapter
+.index SMTP||processing details
+.index LMTP||processing details
+Exim supports a number of different ways of using the SMTP protocol, and its
+LMTP variant, which is an interactive protocol for transferring messages into a
+closed mail store application. This chapter contains details of how SMTP is
+processed. For incoming mail, the following are available:
+.numberpars $.
+SMTP over TCP/IP (Exim daemon or \*inetd*\);
+.nextp
+SMTP over the standard input and output (the \-bs-\ option);
+.nextp
+Batched SMTP on the standard input (the \-bS-\ option).
+.endp
+For mail delivery, the following are available:
+.numberpars $.
+SMTP over TCP/IP (the \%smtp%\ transport);
+.nextp
+LMTP over TCP/IP (the \%smtp%\ transport with the \protocol\ option set to
+`lmtp');
+.nextp
+LMTP over a pipe to a process running in the local host (the \%lmtp%\
+transport);
+.nextp
+Batched SMTP to a file or pipe (the \%appendfile%\ and \%pipe%\ transports with
+the \use@_bsmtp\ option set).
+.endp
+\*Batched SMTP*\ is the name for a process in which batches of messages are
+stored in or read from files (or pipes), in a format in which SMTP commands are
+used to contain the envelope information.
+
+
+.section Outgoing SMTP and LMTP over TCP/IP
+.rset SECToutSMTPTCP "~~chapter.~~section"
+.index SMTP||outgoing over TCP/IP
+.index outgoing SMTP over TCP/IP
+.index LMTP||over TCP/IP
+.index outgoing LMTP over TCP/IP
+.index \\EHLO\\
+.index \\HELO\\
+.index \\SIZE\\ option on \\MAIL\\ command
+Outgoing SMTP and LMTP over TCP/IP is implemented by the \%smtp%\ transport.
+The \protocol\ option selects which protocol is to be used, but the actual
+processing is the same in both cases.
+
+If, in response to its \\EHLO\\ command, Exim is told that the \\SIZE\\
+parameter is supported, it adds \\SIZE\\=<<n>> to each subsequent \\MAIL\\
+command. The value of <<n>> is the message size plus the value of the
+\size@_addition\ option (default 1024) to allow for additions to the message
+such as per-transport header lines, or changes made in a
+.index transport||filter
+.index filter||transport filter
+transport filter. If \size@_addition\ is set negative, the use of \\SIZE\\ is
+suppressed.
+
+If the remote server advertises support for \\PIPELINING\\, Exim uses the
+pipelining extension to SMTP (RFC 2197) to reduce the number of TCP/IP packets
+required for the transaction.
+
+If the remote server advertises support for the \\STARTTLS\\ command, and Exim
+was built to support TLS encryption, it tries to start a TLS session unless the
+server matches \hosts@_avoid@_tls\. See chapter ~~CHAPTLS for more details.
+
+If the remote server advertises support for the \\AUTH\\ command, Exim scans
+the authenticators configuration for any suitable client settings, as described
+in chapter ~~CHAPSMTPAUTH.
+
+.index carriage return
+.index linefeed
+Responses from the remote host are supposed to be terminated by CR followed by
+LF. However, there are known to be hosts that do not send CR characters, so in
+order to be able to interwork with such hosts, Exim treats LF on its own as a
+line terminator.
+
+If a message contains a number of different addresses, all those with the same
+characteristics (for example, the same envelope sender) that resolve to the
+same set of hosts, in the same order, are sent in a single SMTP transaction,
+even if they are for different domains, unless there are more than the setting
+of the \max@_rcpts\ option in the \%smtp%\ transport allows, in which case they
+are split into groups containing no more than \max@_rcpts\ addresses each. If
+\remote@_max@_parallel\ is greater than one, such groups may be sent in
+parallel sessions. The order of hosts with identical MX values is not
+significant when checking whether addresses can be batched in this way.
+
+When the \%smtp%\ transport suffers a temporary failure that is not
+message-related, Exim updates its transport-specific database, which contains
+records indexed by host name that remember which messages are waiting for each
+particular host. It also updates the retry database with new retry times.
+.index hints database||retry keys
+Exim's retry hints are based on host name plus IP address, so if one address of
+a multi-homed host is broken, it will soon be skipped most of the time.
+See the next section for more detail about error handling.
+
+.index SMTP||passed connection
+.index SMTP||batching over TCP/IP
+When a message is successfully delivered over a TCP/IP SMTP connection, Exim
+looks in the hints database for the transport to see if there are any queued
+messages waiting for the host to which it is connected. If it finds one, it
+creates a new Exim process using the \-MC-\ option (which can only be used by a
+process running as root or the Exim user) and passes the TCP/IP socket to it so
+that it can deliver another message using the same socket. The new process does
+only those deliveries that are routed to the connected host, and may in turn
+pass the socket on to a third process, and so on.
+
+The \connection@_max@_messages\ option of the \%smtp%\ transport can be used to
+limit the number of messages sent down a single TCP/IP connection.
+.index asterisk||after IP address
+The second and subsequent messages delivered down an existing connection are
+identified in the main log by the addition of an asterisk after the closing
+square bracket of the IP address.
+
+
+
+.section Errors in outgoing SMTP
+.rset SECToutSMTPerr "~~chapter.~~section"
+.index error||in outgoing SMTP
+.index SMTP||errors in outgoing
+.index host||error
+Three different kinds of error are recognized for outgoing SMTP: host errors,
+message errors, and recipient errors.
+.numberpars
+A host error is not associated with a particular message or with a
+particular recipient of a message. The host errors are:
+.numberpars $.
+Connection refused or timed out,
+.nextp
+Any error response code on connection,
+.nextp
+Any error response code to \\EHLO\\ or \\HELO\\,
+.nextp
+Loss of connection at any time, except after `.',
+.nextp
+I/O errors at any time,
+.nextp
+Timeouts during the session, other than in response to \\MAIL\\, \\RCPT\\ or
+the `.' at the end of the data.
+.endp
+For a host error, a permanent error response on connection, or in response to
+\\EHLO\\, causes all addresses routed to the host to be failed. Any other host
+error causes all addresses to be deferred, and retry data to be created for the
+host. It is not tried again, for any message, until its retry time arrives. If
+the current set of addresses are not all delivered in this run (to some
+alternative host), the message is added to the list of those waiting for this
+host, so if it is still undelivered when a subsequent successful delivery is
+made to the host, it will be sent down the same SMTP connection.
+.nextp
+.index message||error
+A message error is associated with a particular message when sent to a
+particular host, but not with a particular recipient of the message. The
+message errors are:
+.numberpars $.
+Any error response code to \\MAIL\\, \\DATA\\, or the `.' that terminates
+the data,
+.nextp
+Timeout after \\MAIL\\,
+.nextp
+Timeout
+or loss of connection after the `.' that terminates the data. A timeout after
+the \\DATA\\ command itself is treated as a host error, as is loss of
+connection at any other time.
+.endp
+For a message error, a permanent error response (5$it{xx}) causes all addresses
+to be failed, and a delivery error report to be returned to the sender. A
+temporary error response (4$it{xx}), or one of the timeouts, causes all
+addresses to be deferred. Retry data is not created for the host, but instead,
+a retry record for the combination of host plus message id is created. The
+message is not added to the list of those waiting for this host. This ensures
+that the failing message will not be sent to this host again until the retry
+time arrives. However, other messages that are routed to the host are not
+affected, so if it is some property of the message that is causing the error,
+it will not stop the delivery of other mail.
+
+If the remote host specified support for the \\SIZE\\ parameter in its response
+to \\EHLO\\, Exim adds SIZE=$it{nnn} to the \\MAIL\\ command, so an
+over-large message will cause a message error because the error arrives as a
+response to \\MAIL\\.
+.nextp
+.index recipient||error
+A recipient error is associated with a particular recipient of a message. The
+recipient errors are:
+.numberpars $.
+Any error response to \\RCPT\\,
+.nextp
+Timeout after \\RCPT\\.
+.endp
+For a recipient error, a permanent error response (5$it{xx}) causes the
+recipient address to be failed, and a bounce message to be returned to the
+sender. A temporary error response (4$it{xx}) or a timeout causes the failing
+address to be deferred, and routing retry data to be created for it. This is
+used to delay processing of the address in subsequent queue runs, until its
+routing retry time arrives. This applies to all messages, but because it
+operates only in queue runs, one attempt will be made to deliver a new message
+to the failing address before the delay starts to operate. This ensures that,
+if the failure is really related to the message rather than the recipient
+(`message too big for this recipient' is a possible example), other messages
+have a chance of getting delivered. If a delivery to the address does succeed,
+the retry information gets cleared, so all stuck messages get tried again, and
+the retry clock is reset.
+
+The message is not added to the list of those waiting for this host. Use of the
+host for other messages is unaffected, and except in the case of a timeout,
+other recipients are processed independently, and may be successfully delivered
+in the current SMTP session. After a timeout it is of course impossible to
+proceed with the session, so all addresses get deferred. However, those other
+than the one that failed do not suffer any subsequent retry delays. Therefore,
+if one recipient is causing trouble, the others have a chance of getting
+through when a subsequent delivery attempt occurs before the failing
+recipient's retry time.
+.endp
+
+In all cases, if there are other hosts (or IP addresses) available for the
+current set of addresses (for example, from multiple MX records), they are
+tried in this run for any undelivered addresses, subject of course to their
+own retry data. In other words, recipient error retry data does not take effect
+until the next delivery attempt.
+
+Some hosts have been observed to give temporary error responses to every
+\\MAIL\\ command at certain times (`insufficient space' has been seen). It
+would be nice if such circumstances could be recognized, and defer data for the
+host itself created, but this is not possible within the current Exim design.
+What actually happens is that retry data for every (host, message) combination
+is created.
+
+The reason that timeouts after \\MAIL\\ and \\RCPT\\ are treated specially is
+that these can sometimes arise as a result of the remote host's verification
+procedures. Exim makes this assumption, and treats them as if a temporary error
+response had been received. A timeout after `.' is treated specially because it
+is known that some broken implementations fail to recognize the end of the
+message if the last character of the last line is a binary zero. Thus, it is
+helpful to treat this case as a message error.
+
+Timeouts at other times are treated as host errors, assuming a problem with the
+host, or the connection to it. If a timeout after \\MAIL\\, \\RCPT\\,
+or `.' is really a connection problem, the assumption is that at the next try
+the timeout is likely to occur at some other point in the dialogue, causing it
+then to be treated as a host error.
+
+There is experimental evidence that some MTAs drop the connection after the
+terminating `.' if they do not like the contents of the message for some
+reason, in contravention of the RFC, which indicates that a 5$it{xx} response
+should be given. That is why Exim treats this case as a message rather than a
+host error, in order not to delay other messages to the same host.
+
+
+
+
+.section Variable Envelope Return Paths (VERP)
+.index VERP
+.index Variable Envelope Return Paths
+.index envelope sender
+Variable Envelope Return Paths -- see
+\?ftp://koobera.math.uic.edu/www/proto/verp.txt?\ -- can be supported in Exim
+by using the \return@_path\ generic transport option to rewrite the return path
+at transport time. For example, the following could be used on an \%smtp%\
+transport:
+.display asis
+return_path = \
+ ${if match {$return_path}{^(.+?)-request@your.dom.example\$}\
+ {$1-request=$local_part%$domain@your.dom.example}fail}
+.endd
+This has the effect of rewriting the return path (envelope sender) on all
+outgoing SMTP messages, if the local part of the original return path ends in
+`-request', and the domain is \*your.dom.example*\. The rewriting inserts the
+local part and domain of the recipient into the return path. Suppose, for
+example, that a message whose return path has been set to
+\*somelist-request@@your.dom.example*\ is sent to
+\*subscriber@@other.dom.example*\. In the transport, the return path is
+rewritten as
+.display asis
+somelist-request=subscriber%other.dom.example@your.dom.example
+.endd
+For this to work, you must arrange for outgoing messages that have `-request'
+in their return paths to have just a single recipient. This can be done by
+setting
+.display asis
+max_rcpt = 1
+.endd
+in the \%smtp%\ transport. Otherwise a single copy of a message might be
+addressed to several different recipients in the same domain, in which case
+\$local@_part$\ is not available (because it is not unique). Of course, if you
+do start sending out messages with this kind of return path, you must also
+configure Exim to accept the bounce messages that come back to those paths.
+Typically this would be done by setting an \local@_part@_suffix\ option for a
+suitable router.
+
+The overhead incurred in using VERP depends very much on the size of the
+message, the number of recipient addresses that resolve to the same remote
+host, and the speed of the connection over which the message is being sent. If
+a lot of addresses resolve to the same host and the connection is slow, sending
+a separate copy of the message for each address may take substantially longer
+than sending a single copy with many recipients (for which VERP cannot be
+used).
+
+
+.section Incoming SMTP messages over TCP/IP
+.index SMTP||incoming over TCP/IP
+.index incoming SMTP over TCP/IP
+.index inetd
+.index daemon
+Incoming SMTP messages can be accepted in one of two ways: by running a
+listening daemon, or by using \*inetd*\. In the latter case, the entry in
+\(/etc/inetd.conf)\ should be like this:
+.display asis
+smtp stream tcp nowait exim /opt/exim/bin/exim in.exim -bs
+.endd
+Exim distinguishes between this case and the case of a locally running user
+agent using the \-bs-\ option by checking whether or not the standard input is
+a socket. When it is, either the port must be privileged (less than 1024), or
+the caller must be root or the Exim user. If any other user passes a socket
+with an unprivileged port number, Exim prints a message on the standard error
+stream and exits with an error code.
+
+By default, Exim does not make a log entry when a remote host connects or
+disconnects (either via the daemon or \*inetd*\), unless the disconnection is
+unexpected. It can be made to write such log entries by setting the
+\smtp@_connection\ log selector.
+
+.index carriage return
+.index linefeed
+Commands from the remote host are supposed to be terminated by CR followed by
+LF. However, there are known to be hosts that do not send CR characters. In
+order to be able to interwork with such hosts, Exim treats LF on its own as a
+line terminator.
+Furthermore, because common code is used for receiving messages from all
+sources, a CR on its own is also interpreted as a line terminator. However, the
+sequence `CR, dot, CR' does not terminate incoming SMTP data.
+
+.index \\EHLO\\||invalid data
+.index \\HELO\\||invalid data
+One area that sometimes gives rise to problems concerns the \\EHLO\\ or
+\\HELO\\ commands. Some clients send syntactically invalid versions of these
+commands, which Exim rejects by default. (This is nothing to do with verifying
+the data that is sent, so \helo@_verify@_hosts\ is not relevant.) You can tell
+Exim not to apply a syntax check by setting \helo@_accept@_junk@_hosts\ to
+match the broken hosts that send invalid commands.
+
+.index \\SIZE\\ option on \\MAIL\\ command
+.index \\MAIL\\||\\SIZE\\ option
+The amount of disk space available is checked whenever \\SIZE\\ is received on
+a \\MAIL\\ command, independently of whether \message@_size@_limit\ or
+\check@_spool@_space\ is configured, unless \smtp__check__spool__space\ is set
+false. A temporary error is given if there is not enough space. If
+\check@_spool@_space\ is set, the check is for that amount of space plus the
+value given with \\SIZE\\, that is, it checks that the addition of the incoming
+message will not reduce the space below the threshold.
+
+When a message is successfully received, Exim includes the local message id in
+its response to the final `.' that terminates the data. If the remote host logs
+this text it can help with tracing what has happened to a message.
+
+The Exim daemon can limit the number of simultaneous incoming connections it is
+prepared to handle (see the \smtp@_accept@_max\ option). It can also limit the
+number of simultaneous incoming connections from a single remote host (see the
+\smtp@_accept@_max@_per@_host\ option). Additional connection attempts are
+rejected using the SMTP temporary error code 421.
+
+The Exim daemon does not rely on the \\SIGCHLD\\ signal to detect when a
+subprocess has finished, as this can get lost at busy times. Instead, it looks
+for completed subprocesses every time it wakes up. Provided there are other
+things happening (new incoming calls, starts of queue runs), completed
+processes will be noticed and tidied away. On very quiet systems you may
+sometimes see a `defunct' Exim process hanging about. This is not a problem; it
+will be noticed when the daemon next wakes up.
+
+When running as a daemon, Exim can reserve some SMTP slots for specific hosts,
+and can also be set up to reject SMTP calls from non-reserved hosts at times of
+high system load -- for details see the \smtp@_accept@_reserve\,
+\smtp@_load@_reserve\, and \smtp@_reserve@_hosts\ options. The load check
+applies in both the daemon and \*inetd*\ cases.
+
+Exim normally starts a delivery process for each message received, though this
+can be varied by means of the \-odq-\ command line option and the
+\queue@_only\, \queue@_only@_file\, and \queue@_only@_load\ options. The number
+of simultaneously running delivery processes started in this way from SMTP
+input can be limited by the \smtp__accept__queue\ and
+\smtp__accept__queue__per__connection\ options. When either limit is reached,
+subsequently received messages are just put on the input queue without starting
+a delivery process.
+
+The controls that involve counts of incoming SMTP calls (\smtp@_accept@_max\,
+\smtp@_accept@_queue\, \smtp__accept__reserve\) are not available when Exim is
+started up from the \*inetd*\ daemon, because in that case each connection is
+handled by an entirely independent Exim process. Control by load average is,
+however, available with \*inetd*\.
+
+Exim can be configured to verify addresses in incoming SMTP commands as they
+are received. See chapter ~~CHAPACL for details. It can also be configured to
+rewrite addresses at this time -- before any syntax checking is done. See
+section ~~SECTrewriteS.
+
+Exim can also be configured to limit the rate at which a client host submits
+\\MAIL\\ and \\RCPT\\ commands in a single SMTP session. See the
+\smtp@_ratelimit@_hosts\ option.
+
+
+.section Unrecognized SMTP commands
+.index SMTP||unrecognized commands
+If Exim receives more than \smtp@_max@_unknown@_commands\ unrecognized SMTP
+commands during a single SMTP connection, it drops the connection after sending
+the error response to the last command. The default value for
+\smtp@_max@_unknown@_commands\ is 3. This is a defence against some kinds of
+abuse that subvert web servers into making connections to SMTP ports; in these
+circumstances, a number of non-SMTP lines are sent first.
+
+.section Syntax and protocol errors in SMTP commands
+.index SMTP||syntax errors
+.index SMTP||protocol errors
+A syntax error is detected if an SMTP command is recognized, but there is
+something syntactically wrong with its data, for example, a malformed email
+address in a \\RCPT\\ command. Protocol errors include invalid command
+sequencing such as \\RCPT\\ before \\MAIL\\. If Exim receives more than
+\smtp@_max@_synprot@_errors\ such commands during a single SMTP connection, it
+drops the connection after sending the error response to the last command. The
+default value for \smtp__max__synprot__errors\ is 3. This is a defence against
+broken clients that loop sending bad commands (yes, it has been seen).
+
+
+.section Use of non-mail SMTP commands
+.index SMTP||non-mail commands
+The `non-mail' SMTP commands are those other than \\MAIL\\, \\RCPT\\, and
+\\DATA\\. Exim counts such commands, and drops the connection if there are too
+many of them in a single SMTP session. This action catches some
+denial-of-service attempts and things like repeated failing \\AUTH\\s, or a mad
+client looping sending \\EHLO\\. The global option \smtp@_accept@_max@_nonmail\
+defines what `too many' means. Its default value is 10.
+
+When a new message is expected, one occurrence of \\RSET\\ is not counted. This
+allows a client to send one \\RSET\\ between messages (this is not necessary,
+but some clients do it). Exim also allows one uncounted occurence of \\HELO\\
+or \\EHLO\\, and one occurrence of \\STARTTLS\\ between messages. After
+starting up a TLS session, another \\EHLO\\ is expected, and so it too is not
+counted.
+
+The first occurrence of \\AUTH\\ in a connection, or immediately following
+\\STARTTLS\\ is also not counted. Otherwise, all commands other than \\MAIL\\,
+\\RCPT\\, \\DATA\\, and \\QUIT\\ are counted.
+
+You can control which hosts are subject to the limit set by
+\smtp@_accept@_max@_nonmail\ by setting
+\smtp@_accept@_max@_nonmail@_hosts\. The default value is \"$*$"\, which makes
+the limit apply to all hosts. This option means that you can exclude any
+specific badly-behaved hosts that you have to live with.
+
+
+
+.section The \\VRFY\\ and \\EXPN\\ commands
+When Exim receives a \\VRFY\\ or \\EXPN\\ command on a TCP/IP connection, it
+runs the ACL specified by \acl@_smtp@_vrfy\ or \acl@_smtp@_expn\ (as
+appropriate) in order to decide whether the command should be accepted or not.
+If no ACL is defined, the command is rejected.
+
+.index \\VRFY\\||processing
+When \\VRFY\\ is accepted, it runs exactly the same code as when Exim is
+called with the \-bv-\ option.
+.index \\EXPN\\||processing
+When \\EXPN\\ is accepted, a single-level expansion of the address is done.
+\\EXPN\\ is treated as an `address test' (similar to the \-bt-\ option) rather
+than a verification (the \-bv-\ option). If an unqualified local part is given
+as the argument to \\EXPN\\, it is qualified with \qualify@_domain\. Rejections
+of \\VRFY\\ and \\EXPN\\ commands are logged on the main and reject logs, and
+\\VRFY\\ verification failures are logged on the main log for consistency with
+\\RCPT\\ failures.
+
+
+.section The \\ETRN\\ command
+.rset SECTETRN "~~chapter.~~section"
+.index \\ETRN\\||processing
+RFC 1985 describes an SMTP command called \\ETRN\\ that is designed to
+overcome the security problems of the \\TURN\\ command (which has fallen into
+disuse). When Exim receives an \\ETRN\\ command on a TCP/IP connection, it runs
+the ACL specified by \acl@_smtp@_etrn\ in order to decide whether the command
+should be accepted or not. If no ACL is defined, the command is rejected.
+
+The \\ETRN\\ command is concerned with `releasing' messages that are awaiting
+delivery to certain hosts. As Exim does not organize its message queue by host,
+the only form of \\ETRN\\ that is supported by default is the one where the
+text starts with the `@#' prefix, in which case the remainder of the text is
+specific to the SMTP server. A valid \\ETRN\\ command causes a run of Exim with
+the \-R-\ option to happen, with the remainder of the \\ETRN\\ text as its
+argument. For example,
+.display asis
+ETRN #brigadoon
+.endd
+runs the command
+.display asis
+exim -R brigadoon
+.endd
+which causes a delivery attempt on all messages with undelivered addresses
+containing the text `brigadoon'. When \smtp@_etrn@_serialize\ is set (the
+default), Exim prevents the simultaneous execution of more than one queue run
+for the same argument string as a result of an \\ETRN\\ command. This stops
+a misbehaving client from starting more than one queue runner at once.
+
+.index hints database||\\ETRN\\ serialization
+Exim implements the serialization by means of a hints database in which a
+record is written whenever a process is started by \\ETRN\\, and deleted when
+the process completes. However, Exim does not keep the SMTP session waiting for
+the \\ETRN\\ process to complete. Once \\ETRN\\ is accepted, the client is sent
+a `success' return code. Obviously there is scope for hints records to get left
+lying around if there is a system or program crash. To guard against this, Exim
+ignores any records that are more than six hours old.
+
+.index \smtp@_etrn@_command\
+For more control over what \\ETRN\\ does, the \smtp@_etrn@_command\ option can
+used. This specifies a command that is run whenever \\ETRN\\ is received,
+whatever the form of its argument. For
+example:
+.display asis
+smtp_etrn_command = /etc/etrn_command $domain $sender_host_address
+.endd
+The string is split up into arguments which are independently expanded. The
+expansion variable \$domain$\ is set to the argument of the \\ETRN\\ command,
+and no syntax checking is done on the contents of this argument. Exim does not
+wait for the command to complete, so its status code is not checked. Exim runs
+under its own uid and gid when receiving incoming SMTP, so it is not possible
+for it to change them before running the command.
+
+
+.section Incoming local SMTP
+.index SMTP||local incoming
+Some user agents use SMTP to pass messages to their local MTA using the
+standard input and output, as opposed to passing the envelope on the command
+line and writing the message to the standard input. This is supported by the
+\-bs-\ option. This form of SMTP is handled in the same way as incoming
+messages over TCP/IP (including the use of ACLs), except that the envelope
+sender given in a \\MAIL\\ command is ignored unless the caller is trusted. In
+an ACL you can detect this form of SMTP input by testing for an empty host
+identification. It is common to have this as the first line in the ACL that
+runs for \\RCPT\\ commands:
+.display asis
+accept hosts = :
+.endd
+This accepts SMTP messages from local processes without doing any other tests.
+
+
+.section Outgoing batched SMTP
+.rset SECTbatchSMTP "~~chapter.~~section"
+.index SMTP||batched outgoing
+.index batched SMTP output
+Both the \%appendfile%\ and \%pipe%\ transports can be used for handling batched
+SMTP. Each has an option called \use@_bsmtp\ which causes messages to be output
+in BSMTP format. No SMTP responses are possible for this form of delivery. All
+it is doing is using SMTP commands as a way of transmitting the envelope along
+with the message.
+
+The message is written to the file or pipe preceded by the SMTP commands
+\\MAIL\\ and \\RCPT\\, and followed by a line containing a single dot. Lines in
+the message that start with a dot have an extra dot added. The SMTP command
+\\HELO\\ is not normally used. If it is required, the \message@_prefix\ option
+can be used to specify it.
+
+Because \%appendfile%\ and \%pipe%\ are both local transports, they accept only
+one recipient address at a time by default. However, you can arrange for them
+to handle several addresses at once by setting the \batch@_max\ option. When
+this is done for BSMTP, messages may contain multiple \\RCPT\\ commands. See
+chapter ~~CHAPbatching for more details.
+
+When one or more addresses are routed to a BSMTP transport by a router that
+sets up a host list, the name of the first host on the list is available to the
+transport in the variable \$host$\. Here is an example of such a transport and
+router:
+.display asis
+begin routers
+route_append:
+ driver = manualroute
+ transport = smtp_appendfile
+ route_list = domain.example batch.host.example
+
+begin transports
+smtp_appendfile:
+ driver = appendfile
+ directory = /var/bsmtp/$host
+ batch_max = 1000
+ use_bsmtp
+ user = exim
+.endd
+This causes messages addressed to \*domain.example*\ to be written in BSMTP
+format to \(/var/bsmtp/batch.host.example)\, with only a single copy of each
+message (unless there are more than 1000 recipients).
+
+
+.section Incoming batched SMTP
+.rset SECTincomingbatchedSMTP "~~chapter.~~section"
+.index SMTP||batched incoming
+.index batched SMTP input
+The \-bS-\ command line option causes Exim to accept one or more messages by
+reading SMTP on the standard input, but to generate no responses. If the caller
+is trusted, the senders in the \\MAIL\\ commands are believed; otherwise the
+sender is always the caller of Exim. Unqualified senders and receivers are not
+rejected (there seems little point) but instead just get qualified. \\HELO\\
+and \\EHLO\\ act as \\RSET\\; \\VRFY\\, \\EXPN\\, \\ETRN\\ and \\HELP\\, act
+as \\NOOP\\; \\QUIT\\ quits.
+
+No policy checking is done for BSMTP input. That is, no ACL is run at anytime.
+In this respect it is like non-SMTP local input.
+
+If an error is detected while reading a message, including a missing `.' at
+the end, Exim gives up immediately. It writes details of the error to the
+standard output in a stylized way that the calling program should be able to
+make some use of automatically, for example:
+.display asis
+554 Unexpected end of file
+Transaction started in line 10
+Error detected in line 14
+.endd
+It writes a more verbose version, for human consumption, to the standard error
+file, for example:
+.display asis
+An error was detected while processing a file of BSMTP input.
+The error message was:
+
+ 501 '>' missing at end of address
+
+The SMTP transaction started in line 10.
+The error was detected in line 12.
+The SMTP command at fault was:
+
+ rcpt to:<malformed@in.com.plete
+
+1 previous message was successfully processed.
+The rest of the batch was abandoned.
+.endd
+The return code from Exim is zero only if there were no errors. It is 1 if some
+messages were accepted before an error was detected, and 2 if no messages were
+accepted.
+
+
+
+
+.
+.
+.
+.
+. ============================================================================
+.chapter Message processing
+.set runningfoot "message processing"
+.rset CHAPmsgproc "~~chapter"
+.index message||general processing
+Exim performs various transformations on the sender and recipient addresses of
+all messages that it handles, and also on the messages' header lines. Some of
+these are optional and configurable, while others always take place. All of
+this processing, except rewriting as a result of routing, and the addition or
+removal of header lines while delivering, happens when a message is received,
+before it is placed on Exim's queue.
+
+Some of the automatic processing takes place
+.em
+by default
+.nem
+only for `locally-originated' messages. This adjective is used to describe
+messages that are not received over TCP/IP, but instead are passed to an Exim
+process on its standard input. This includes the interactive `local SMTP' case
+that is set up by the \-bs-\ command line option. \**Note**\: messages received
+over TCP/IP on the loopback interface (127.0.0.1 or @:@:1) are not considered
+to be locally-originated. Exim does not treat the loopback interface specially
+in any way.
+
+.em
+.index message||submission
+Processing that happens automatically for locally-originated messages can also
+be requested for other messages. This is done by obeying the modifier
+.display asis
+control = submission
+.endd
+in one of the ACLs that are run for an incoming message (see section
+~~SECTACLmodi). 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). In the descriptions below, the term
+`submission mode' is used to describe this state.
+
+When a ::From:: or ::Sender:: header is generated in submission mode, the value
+of \qualify@_domain\ is used by default. However, it is possible to specify
+another domain by a setting such as
+.display asis
+control = submission/domain=some.other.domain
+.endd
+.nem
+
+
+
+.section Line endings
+.rset SECTlineendings "~~chapter.~~section"
+.index line endings
+.index carriage return
+.index linefeed
+RFC 2821 specifies that CRLF (two characters: carriage-return, followed by
+linefeed) is the line ending for messages transmitted over the Internet using
+SMTP over TCP/IP. However, within individual operating systems, different
+conventions are used. For example, Unix-like systems use just LF, but others
+use CRLF or just CR.
+
+Exim was designed for Unix-like systems, and internally, it stores messages
+using the system's convention of a single LF as a line terminator. When
+receiving a message, all line endings are translated to this standard format.
+Originally, it was thought that programs that passed messages directly to an
+MTA within an operating system would use that system's convention. Experience
+has shown that this is not the case; for example, there are Unix applications
+that use CRLF in this circumstance. For this reason, and for compatibility with
+other MTAs, the way Exim handles line endings for all messages is now as
+follows:
+.numberpars $.
+LF not preceded by CR is treated as a line ending.
+.nextp
+CR is treated as a line ending; if it is immediately followed by LF, the LF
+is ignored.
+.nextp
+The sequence `CR, dot, CR' does not terminate an incoming SMTP message,
+nor a local message in the state where a line containing only a dot is a
+terminator.
+.nextp
+If a bare CR is encountered within a header line, an extra space is added after
+the line terminator so as not to end the header line. The reasoning behind this
+is that bare CRs in header lines are most likely either to be mistakes, or
+people trying to play silly games.
+.nextp
+.em
+If the first header line received in a message ends with CRLF, a subsequent
+bare LF in a header line is treated in the same way as a bare CR in a header
+line.
+.nem
+.endp
+
+
+
+.section Unqualified addresses
+.index unqualified addresses
+.index address||qualification
+By default, Exim expects every address it receives from an external host to be
+fully qualified. Unqualified addresses cause negative responses to SMTP
+commands. However, because SMTP is used as a means of transporting messages
+from MUAs running on personal workstations, there is sometimes a requirement to
+accept unqualified addresses from specific hosts or IP networks.
+
+Exim has two options that separately control which hosts may send unqualified
+sender or receipient addresses in SMTP commands, namely
+\sender__unqualified__hosts\ and \recipient__unqualified__hosts\. In both
+cases, if an unqualified address is accepted, it is qualified by adding the
+value of \qualify__domain\ or \qualify__recipient\, as appropriate.
+.index \qualify@_domain\
+.index \qualify@_recipient\
+
+
+.section The UUCP From line
+.index `From' line
+.index UUCP||`From' line
+.index sender||address
+.index \uucp@_from@_pattern\
+.index \uucp@_from@_sender\
+.index envelope sender
+.index Sendmail compatibility||`From' line
+Messages that have come from UUCP (and some other applications) often begin
+with a line containing the envelope sender and a timestamp, following the word
+`From'. Examples of two common formats are:
+.display asis
+From a.oakley@berlin.mus Fri Jan 5 12:35 GMT 1996
+From f.butler@berlin.mus Fri, 7 Jan 97 14:00:00 GMT
+.endd
+This line precedes the RFC 2822 header lines. For compatibility with Sendmail,
+Exim recognizes such lines at the start of messages that are submitted to it
+via the command line (that is, on the standard input). It does not recognize
+such lines in incoming SMTP messages, unless the sending host matches
+\ignore@_fromline@_hosts\ or the \-bs-\ option was used for a local message and
+\ignore@_fromline@_local\ is set. The recognition is controlled by a regular
+expression that is defined by the \uucp@_from@_pattern\ option, whose default
+value matches the two common cases shown above and puts the address that
+follows `From' into \$1$\.
+
+.index numerical variables (\$1$\, \$2$\, etc)||in `From ' line handling
+When the caller of Exim for a non-SMTP message that contains a `From' line is a
+trusted user, the message's sender address is constructed by expanding the
+contents of \uucp@_sender@_address\, whose default value is `@$1'. This is then
+parsed as an RFC 2822 address. If there is no domain, the local part is
+qualified with \qualify@_domain\ unless it is the empty string. However, if the
+command line \-f-\ option is used, it overrides the `From' line.
+
+If the caller of Exim is not trusted, the `From' line is recognized, but the
+sender address is not changed. This is also the case for incoming SMTP messages
+that are permitted to contain `From' lines.
+
+Only one `From' line is recognized. If there is more than one, the second is
+treated as a data line that starts the body of the message, as it is not valid
+as a header line. This also happens if a `From' line is present in an incoming
+SMTP message from a source that is not permitted to send them.
+
+
+.section Resent- header lines
+.index \Resent@-\ header lines
+RFC 2822 makes provision for sets of header lines starting with the string
+\"Resent-"\ to be added to a message when it is resent by the original
+recipient to somebody else. These headers are ::Resent-Date::, ::Resent-From::,
+::Resent-Sender::, ::Resent-To::, ::Resent-Cc::, ::Resent-Bcc:: and
+::Resent-Message-ID::. The RFC says:
+
+\*Resent fields are strictly informational. They MUST NOT be used in the normal
+processing of replies or other such automatic actions on messages.*\
+
+This leaves things a bit vague as far as other processing actions such as
+address rewriting are concerned. Exim treats \Resent@-\ header lines as
+follows:
+.numberpars $.
+A ::Resent-From:: line that just contains the login id of the submitting user
+is automatically rewritten in the same way as ::From:: (see below).
+.nextp
+If there's a rewriting rule for a particular header line, it is also applied to
+\Resent@-\ header lines of the same type. For example, a rule that rewrites
+::From:: also rewrites ::Resent-From::.
+.nextp
+For local messages, if ::Sender:: is removed on input, ::Resent-Sender:: is also
+removed.
+.nextp
+For a locally-submitted message,
+if there are any \Resent@-\ header lines but no ::Resent-Date::,
+::Resent-From::, or ::Resent-Message-Id::, they are added as necessary. It is
+the contents of ::Resent-Message-Id:: (rather than ::Message-Id::) which are
+included in log lines in this case.
+.nextp
+The logic for adding ::Sender:: is duplicated for ::Resent-Sender:: when any
+\Resent@-\ header lines are present.
+.endp
+
+
+.section The Auto-Submitted: header line
+Whenever Exim generates a bounce or a delay warning message, it includes the
+header line
+.display asis
+Auto-Submitted: auto-generated
+.endd
+
+
+.section The Bcc: header line
+.index ::Bcc:: header line
+If Exim is called with the \-t-\ option, to take recipient addresses from a
+message's header, it removes any ::Bcc:: header line that may exist (after
+extracting its addresses). If \-t-\ is not present on the command line, any
+existing ::Bcc:: is not removed.
+
+.section The Date: header line
+.index ::Date:: header line
+If a locally-generated
+.em
+or submission-mode
+.nem
+message has no ::Date:: header line, Exim adds one, using the current date and
+time.
+
+.section The Delivery-date: header line
+.index ::Delivery-date:: header line
+.index \delivery@_date@_remove\
+::Delivery-date:: header lines are not part of the standard RFC 2822 header
+set. Exim can be configured to add them to the final delivery of messages. (See
+the generic \delivery@_date@_add\ transport option.) They should not be present
+in messages in transit. If the \delivery@_date@_remove\ configuration option is
+set (the default), Exim removes ::Delivery-date:: header lines from incoming
+messages.
+
+.section The Envelope-to: header line
+.index ::Envelope-to:: header line
+.index \envelope@_to@_remove\
+::Envelope-to:: header lines are not part of the standard RFC 2822 header set.
+Exim can be configured to add them to the final delivery of messages. (See the
+generic \envelope@_to@_add\ transport option.) They should not be present in
+messages in transit. If the \envelope@_to@_remove\ configuration option is set
+(the default), Exim removes ::Envelope-to:: header lines from incoming
+messages.
+
+.section The From: header line
+.index ::From:: header line
+.index Sendmail compatibility||`From' line
+.em
+If a submission-mode message does not contain a ::From:: header line, Exim adds
+one if either of the following conditions is true:
+.numberpars alpha
+The envelope sender address is not empty (that is, this is not a bounce
+message); the added header line copies the envelope sender address.
+.nextp
+The SMTP session is authenticated and \$authenticated@_id$\ is not empty; the
+added header's local part is \$authenticated@_id$\ and the domain is
+the domain specified on the submission control, or \$qualify@_domain$\ if that
+is not set.
+.endp
+A non-empty envelope sender takes precedence.
+.nem
+
+If a locally-generated incoming message does not contain a ::From:: header
+line, Exim adds one containing the sender's address. The calling user's login
+name and full name are used to construct the address, as described in section
+~~SECTconstr. They are obtained from the password data by calling
+\*getpwuid()*\ (but see the \unknown@_login\ configuration option). The address
+is qualified with \qualify@_domain\.
+
+For compatibility with Sendmail, if an incoming, non-SMTP message has a
+::From:: header line containing just the unqualified login name of the calling
+user, this is replaced by an address containing the user's login name and full
+name as described in section ~~SECTconstr.
+
+.section The Message-ID: header line
+.index ::Message-ID:: header line
+If a locally-generated
+.em
+or submission-mode
+.nem
+incoming message does not contain a ::Message-ID:: or ::Resent-Message-ID::
+header line, Exim adds one to the message. If there are any ::Resent-:: headers
+in the message, it creates ::Resent-Message-ID::. The id is constructed from
+Exim's internal message id, preceded by the letter E to ensure it starts with a
+letter, and followed by @@ and the primary host name. Additional information
+can be included in this header line by setting the
+.index \message@_id@_header@_text\
+\message@_id@_header@_text\ and/or \message__id__header__domain\ options.
+
+
+.section The Received: header line
+.index ::Received:: header line
+A ::Received:: header line is added at the start of every message. The contents
+are defined by the \received@_header@_text\ configuration option, and Exim
+automatically adds a semicolon and a timestamp to the configured string.
+
+.em
+The ::Received:: header is generated as soon as the message's header lines have
+been received. At this stage, the timestamp in the ::Received:: header line is
+the time that the message started to be received. This is the value that is
+seen by the \\DATA\\ ACL and by the \*local@_scan()*\ function.
+
+Once a message is accepted, the timestamp in the ::Received:: header line is
+changed to the time of acceptance, which is (apart from a small delay while the
+-H spool file is written) the earliest time at which delivery could start.
+.nem
+
+
+.section The Return-path: header line
+.index ::Return-path:: header line
+.index \return@_path@_remove\
+::Return-path:: header lines are defined as something an MTA may insert when
+it does the final delivery of messages. (See the generic \return@_path@_add\
+transport option.) Therefore, they should not be present in messages in
+transit. If the \return@_path@_remove\ configuration option is set (the
+default), Exim removes ::Return-path:: header lines from incoming messages.
+
+
+.section The Sender: header line
+.rset SECTthesenhea "~~chapter.~~section"
+.index ::Sender:: header line
+For a locally-originated message from an untrusted user, Exim may remove an
+existing ::Sender:: header line, and it may add a new one. You can modify these
+actions by setting \local@_sender@_retain\ true or \local@_from@_check\ false.
+
+When a local message is received from an untrusted user and
+\local@_from@_check\ is true (the default), a check is made to see if the
+address given in the ::From:: header line is the correct (local) sender of the
+message. The address that is expected has the login name as the local part and
+the value of \qualify@_domain\ as the domain. Prefixes and suffixes for the
+local part can be permitted by setting \local@_from@_prefix\ and
+\local@_from@_suffix\ appropriately. If ::From:: does not contain the correct
+sender, a ::Sender:: line is added to the message.
+
+If you set \local@_from@_check\ false, this checking does not occur. However,
+the removal of an existing ::Sender:: line still happens, unless you also set
+\local@_sender@_retain\ to be true. It is not possible to set both of these
+options true at the same time.
+
+.em
+By default, no processing of ::Sender:: header lines is done for messages
+received by TCP/IP or for messages submitted by trusted users. However, when a
+message is received over TCP/IP in submission mode, ::Sender:: header lines are
+always removed. If the SMTP session is authenticated, and \$authenticated@_id$\
+is not empty, a sender address is created with \$authenticated@_id$\ as the
+local part and either the domain specified in the submission control or, if
+that is not specified, \$qualify@_domain$\ as the domain. This is compared with
+the address in the ::From:: header line. If they are different, a ::Sender::
+header line is added. Prefixes and suffixes for the local part in ::From:: can
+be permitted by setting \local@_from@_prefix\ and \local@_from@_suffix\
+appropriately.
+.nem
+
+
+.section Adding and removing header lines
+.index header lines||adding
+.index header lines||removing
+.rset SECTheadersaddrem "~~chapter.~~section"
+When a message is delivered, the addition and removal of header lines can be
+specified on any of the routers and transports, and also in the system filter.
+Changes specified in the system filter affect all deliveries of a message.
+
+Header changes specified on a router affect all addresses handled by that
+router, and also any new addresses it generates. If an address passes through
+several routers, the changes are cumulative. When a message is processed by a
+transport, the message's original set of header lines is output, except for
+those named in any \headers@_remove\ options that the address has encountered
+as it was processed, and any in the transport's own \headers@_remove\ option.
+Then the new header lines from \headers@_add\ options are output.
+
+
+.section Constructed addresses
+.rset SECTconstr "~~chapter.~~section"
+.index address||constructed
+.index constructed address
+When Exim constructs a sender address for a locally-generated message, it uses
+the form
+.display
+<<user name>> <$$<<login>>@@<<qualify@_domain>>$$>
+.endd
+For example:
+.display asis
+Zaphod Beeblebrox <zaphod@end.univ.example>
+.endd
+The user name is obtained from the \-F-\ command line option if set, or
+otherwise by looking up the calling user by \*getpwuid()*\ and extracting the
+`gecos' field from the password entry. If the `gecos' field contains an
+ampersand character, this is replaced by the login name with the first letter
+upper cased, as is conventional in a number of operating systems. See the
+\gecos@_name\ option for a way to tailor the handling of the `gecos' field. The
+\unknown@_username\ option can be used to specify user names in cases when
+there is no password file entry.
+
+In all cases, the user name is made to conform to RFC 2822 by quoting all or
+parts of it if necessary. In addition, if it contains any non-printing
+characters, it is encoded as described in RFC 2047, which defines a way of
+including non-ASCII characters in header lines.
+The value of the \headers@_charset\ option specifies the name of the encoding
+that is used (the characters are assumed to be in this encoding).
+The setting of \print@_topbitchars\ controls whether characters with the top
+bit set (that is, with codes greater than 127) count as printing characters or
+not.
+
+
+.section Case of local parts
+.index case of local parts
+.index local part||case of
+RFC 2822 states that the case of letters in the local parts of addresses cannot
+be assumed to be non-significant. Exim preserves the case of local parts of
+addresses, but by default it uses a lower-cased form when it is routing,
+because on most Unix systems, usernames are in lower case and case-insensitive
+routing is required. However, any particular router can be made to use the
+original case for local parts by setting the \caseful@_local@_part\ generic
+router option.
+
+.index mixed-case login names
+If you must have mixed-case user names on your system, the best way to proceed,
+assuming you want case-independent handling of incoming email, is to set up
+your first router to convert incoming local parts in your domains to the
+correct case by means of a file lookup. For example:
+.display asis
+correct_case:
+ driver = redirect
+ domains = +local_domains
+ data = ${lookup{$local_part}cdb\
+ {/etc/usercased.cdb}{$value}fail}\
+ @$domain
+.endd
+For this router, the local part is forced to lower case by the default action
+(\caseful@_local@_part\ is not set). The lower-cased local part is used to look
+up a new local part in the correct case. If you then set \caseful@_local@_part\
+on any subsequent routers which process your domains, they will operate on
+local parts with the correct case in a case-sensitive manner.
+
+
+.section Dots in local parts
+.index dot||in local part
+.index local part||dots in
+RFC 2822 forbids empty components in local parts. That is, an unquoted local
+part may not begin or end with a dot, nor have two consecutive dots in the
+middle. However, it seems that many MTAs do not enforce this, so Exim permits
+empty components for compatibility.
+
+
+.section Rewriting addresses
+.index rewriting||addresses
+Rewriting of sender and recipient addresses, and addresses in headers, can
+happen automatically, or as the result of configuration options, as described
+in chapter ~~CHAPrewrite. The headers that may be affected by this are ::Bcc::,
+::Cc::, ::From::, ::Reply-To::, ::Sender::, and ::To::.
+
+Automatic rewriting includes qualification, as mentioned above. The other case
+in which it can happen is when an incomplete non-local domain is given. The
+routing process may cause this to be expanded into the full domain name. For
+example, a header such as
+.display asis
+To: hare@teaparty
+.endd
+might get rewritten as
+.display asis
+To: hare@teaparty.wonderland.fict.example
+.endd
+Rewriting as a result of routing is the one kind of message processing that
+does not happen at input time, as it cannot be done until the address has
+been routed.
+
+Strictly, one should not do $it{any} deliveries of a message until all its
+addresses have been routed, in case any of the headers get changed as a
+result of routing. However, doing this in practice would hold up many
+deliveries for unreasonable amounts of time, just because one address could not
+immediately be routed. Exim therefore does not delay other deliveries when
+routing of one or more addresses is deferred.
+
+
+
+
+
+.
+.
+.
+.
+. ============================================================================
+.chapter Log files
+.set runningfoot "log files"
+.rset CHAPlog "~~chapter"
+.index log||types of
+.index log||general description
+Exim writes three different logs, referred to as the main log, the reject log,
+and the panic log:
+.numberpars $.
+.index main log
+The main log records the arrival of each message and each delivery in a single
+line in each case. The format is as compact as possible, in an attempt to keep
+down the size of log files. Two-character flag sequences make it easy to pick
+out these lines. A number of other events are recorded in the main log. Some of
+them are optional, in which case the \log@_selector\ option controls whether
+they are included or not. A Perl script called \*eximstats*\, which does simple
+analysis of main log files, is provided in the Exim distribution (see section
+~~SECTmailstat).
+.nextp
+.index reject log
+The reject log records information from messages that are rejected as a result
+of a configuration option (that is, for policy reasons).
+.em
+The first line of each rejection is a copy of the line that is also written to
+the main log. Then, if the message's header has been read at the time the log
+is written, its contents are written to this log. Only the original header
+lines are available; header lines added by ACLs are not logged. You can use the
+reject log to check that your policy controls are working correctly; on a busy
+host this may be easier than scanning the main log for rejection messages. You
+can suppress the writing of the reject log by setting \write@_rejectlog\ false.
+.nem
+.nextp
+.index panic log
+.index system log
+When certain serious errors occur, Exim writes entries to its panic log. If the
+error is sufficiently disastrous, Exim bombs out afterwards. Panic log entries
+are usually written to the main log as well, but can get lost amid the mass of
+other entries. The panic log should be empty under normal circumstances. It is
+therefore a good idea to check it (or to have a \*cron*\ script check it)
+regularly, in order to become aware of any problems. When Exim cannot open its
+panic log, it tries as a last resort to write to the system log (syslog). This
+is opened with LOG@_PID+LOG@_CONS and the facility code of LOG@_MAIL. The
+message itself is written at priority LOG@_CRIT.
+.endp
+Every log line starts with a timestamp, in the format shown in this example:
+.display asis
+2001-09-16 16:09:47 SMTP connection from [127.0.0.1] closed by QUIT
+.endd
+By default, the timestamps are in the local timezone. There are two
+ways of changing this:
+.numberpars $.
+You can set the \timezone\ option to a different time zone; in particular, if
+you set
+.display asis
+timezone = UTC
+.endd
+the timestamps will be in UTC (aka GMT).
+.nextp
+If you set \log@_timezone\ true, the time zone is added to the timestamp, for
+example:
+.display asis
+2003-04-25 11:17:07 +0100 Start queue run: pid=12762
+.endd
+.endp
+
+
+
+.section Where the logs are written
+.rset SECTwhelogwri "~~chapter.~~section"
+.index log||destination
+.index log||to file
+.index log||to syslog
+.index syslog
+The logs may be written to local files, or to syslog, or both. However, it
+should be noted that many syslog implementations use UDP as a transport, and
+are therefore unreliable in the sense that messages are not guaranteed to
+arrive at the loghost, nor is the ordering of messages necessarily maintained.
+It has also been reported that on large log files (tens of megabytes) you may
+need to tweak syslog to prevent it syncing the file with each write -- on Linux
+this has been seen to make syslog take 90% plus of CPU time.
+
+The destination for Exim's logs is configured by setting \\LOG@_FILE@_PATH\\ in
+\(Local/Makefile)\ or by setting \log@_file@_path\ in the run time
+configuration. This latter string is expanded, so it can contain, for example,
+references to the host name:
+.display asis
+log_file_path = /var/log/$primary_hostname/exim_%slog
+.endd
+It is generally advisable, however, to set the string in \(Local/Makefile)\
+rather than at run time, because then the setting is available right from the
+start of Exim's execution. Otherwise, if there's something it wants to log
+before it has read the configuration file (for example, an error in the
+configuration file) it will not use the path you want, and may not be able to
+log at all.
+
+The value of \\LOG@_FILE@_PATH\\ or \log@_file@_path\ is a colon-separated
+list, currently limited to at most two items. This is one option where the
+facility for changing a list separator may not be used. The list must always be
+colon-separated. If an item in the list is `syslog' then syslog is used;
+otherwise the item must either be an absolute path, containing \"%s"\ at the
+point where `main', `reject', or `panic' is to be inserted, or be empty,
+implying the use of a default path.
+
+When Exim encounters an empty item in the list, it searches the list defined by
+\\LOG@_FILE@_PATH\\, and uses the first item it finds that is neither empty nor
+`syslog'. This means that an empty item in \log@_file@_path\ can be used to
+mean `use the path specified at build time'. It no such item exists, log files
+are written in the \(log)\ subdirectory of the spool directory. This is
+equivalent to the setting:
+.display asis
+log_file_path = $spool_directory/log/%slog
+.endd
+If you do not specify anything at build time or run time, that is where the
+logs are written.
+
+A log file path may also contain \"%D"\ if datestamped log file names are in
+use -- see section ~~SECTdatlogfil below.
+
+Here are some examples of possible settings:
+.display
+.tabs 42
+LOG@_FILE@_PATH=syslog $t $rm{syslog only}
+LOG@_FILE@_PATH=:syslog $t $rm{syslog and default path}
+LOG@_FILE@_PATH=syslog : /usr/log/exim@_%s $t $rm{syslog and specified path}
+LOG@_FILE@_PATH=/usr/log/exim@_%s $t $rm{specified path only}
+.endd
+If there are more than two paths in the list, the first is used and a panic
+error is logged.
+
+
+.section Logging to local files that are periodically `cycled'
+.index log||cycling local files
+.index cycling logs
+.index \*exicyclog*\
+.index log||local files, writing to
+Some operating systems provide centralized and standardised methods for cycling
+log files. For those that do not, a utility script called \*exicyclog*\ is
+provided (see section ~~SECTcyclogfil). This renames and compresses the main
+and reject logs each time it is called. The maximum number of old logs to keep
+can be set. It is suggested this script is run as a daily \*cron*\ job.
+
+An Exim delivery process opens the main log when it first needs to write to it,
+and it keeps the file open in case subsequent entries are required -- for
+example, if a number of different deliveries are being done for the same
+message. However, remote SMTP deliveries can take a long time, and this means
+that the file may be kept open long after it is renamed if \*exicyclog*\ or
+something similar is being used to rename log files on a regular basis. To
+ensure that a switch of log files is noticed as soon as possible, Exim calls
+\*stat()*\ on the main log's name before reusing an open file, and if the file
+does not exist, or its inode has changed, the old file is closed and Exim
+tries to open the main log from scratch. Thus, an old log file may remain open
+for quite some time, but no Exim processes should write to it once it has been
+renamed.
+
+
+.section Datestamped log files
+.rset SECTdatlogfil "~~chapter.~~section"
+.index log||datestamped files
+Instead of cycling the main and reject log files by renaming them
+periodically, some sites like to use files whose names contain a datestamp,
+for example, \(mainlog-20031225)\. The datestamp is in the form \(yyyymmdd)\.
+Exim has support for this way of working. It is enabled by setting the
+\log@_file@_path\ option to a path that includes \"%D"\ at the point where the
+datestamp is required. For example:
+.display asis
+log_file_path = /var/spool/exim/log/%slog-%D
+log_file_path = /var/log/exim-%s-%D.log
+log_file_path = /var/spool/exim/log/%D-%slog
+.endd
+As before, \"%s"\ is replaced by `main' or `reject'; the following are examples
+of names generated by the above examples:
+.display asis
+/var/spool/exim/log/mainlog-20021225
+/var/log/exim-reject-20021225.log
+/var/spool/exim/log/20021225-mainlog
+.endd
+When this form of log file is specified, Exim automatically switches to new
+files at midnight. It does not make any attempt to compress old logs; you
+will need to write your own script if you require this. You should not
+run \*exicyclog*\ with this form of logging.
+
+The location of the panic log is also determined by \log@_file@_path\, but it
+is not datestamped, because rotation of the panic log does not make sense.
+When generating the name of the panic log, \"%D"\ is removed from the string.
+In addition, if it immediately follows a slash, a following non-alphanumeric
+character is removed; otherwise a preceding non-alphanumeric character is
+removed. Thus, the three examples above would give these panic log names:
+.display asis
+/var/spool/exim/log/paniclog
+/var/log/exim-panic.log
+/var/spool/exim/log/paniclog
+.endd
+
+
+.section Logging to syslog
+.index log||syslog, writing to
+The use of syslog does not change what Exim logs or the format of its messages,
+except in one respect. If \syslog@_timestamp\ is set false, the timestamps on
+Exim's log lines are omitted when these lines are sent to syslog. Apart from
+that, the same strings are written to syslog as to log files. The syslog
+`facility' is set to \\LOG@_MAIL\\, and the program name to `exim'
+by default, but you can change these by setting the \syslog@_facility\ and
+\syslog@_processname\ options, respectively. If Exim was compiled with
+\\SYSLOG@_LOG@_PID\\ set in \(Local/Makefile)\ (this is the default in
+\(src/EDITME)\), then, on systems that permit it (all except ULTRIX), the
+\\LOG@_PID\\ flag is set so that the \*syslog()*\ call adds the pid as well as
+the time and host name to each line.
+The three log streams are mapped onto syslog priorities as follows:
+.numberpars " "
+\*mainlog*\ is mapped to \\LOG@_INFO\\
+.nextp
+\*rejectlog*\ is mapped to \\LOG@_NOTICE\\
+.nextp
+\*paniclog*\ is mapped to \\LOG@_ALERT\\
+.endp
+Many log lines are written to both \*mainlog*\ and \*rejectlog*\, and some are
+written to both \*mainlog*\ and \*paniclog*\, so there will be duplicates if
+these are routed by syslog to the same place. You can suppress this duplication
+by setting \syslog@_duplication\ false.
+
+Exim's log lines can sometimes be very long, and some of its \*rejectlog*\
+entries contain multiple lines when headers are included. To cope with both
+these cases, entries written to syslog are split into separate \*syslog()*\
+calls at each internal newline, and also after a maximum of
+870 data characters. (This allows for a total syslog line length of 1024, when
+additions such as timestamps are added.) If you are running a syslog
+replacement that can handle lines longer than the 1024 characters allowed by
+RFC 3164, you should set
+.display asis
+SYSLOG_LONG_LINES=yes
+.endd
+in \(Local/Makefile)\ before building Exim. That stops Exim from splitting long
+lines, but it still splits at internal newlines in \*reject*\ log entries.
+
+To make it easy to re-assemble split lines later, each component of a split
+entry starts with a string of the form `[<<n>>/<<m>>]' or `[<<n>>@\<<m>>]'
+where <<n>> is the component number and <<m>> is the total number of components
+in the entry. The / delimiter is used when the line was split because it was
+too long; if it was split because of an internal newline, the @\ delimiter is
+used. For example, supposing the length limit to be 70 instead of 1000, the
+following would be the result of a typical rejection message to \*mainlog*\
+(LOG@_INFO), each line in addition being preceded by the time, host name, and
+pid as added by syslog:
+.display
+.indent 0
+$smc{[1/3] 2002-09-16 16:09:43 16RdAL-0006pc-00 rejected from [127.0.0.1] (ph10):
+[2/3] syntax error in 'From' header when scanning for sender: missing or ma
+[3/3] lformed local part in "<>" (envelope sender is <ph10@@cam.example>)}
+.endd
+The same error might cause the following lines to be written to `rejectlog'
+(LOG@_NOTICE):
+.display flow
+.indent 0
+$smc{[1/14] 2002-09-16 16:09:43 16RdAL-0006pc-00 rejected from [127.0.0.1] (ph10):
+[2/14] syntax error in 'From' header when scanning for sender: missing or ma
+[3@\14] lformed local part in "@<@>" (envelope sender is <ph10@@cam.example>)
+[4@\14] Recipients: ph10@@some.domain.cam.example
+[5@\14] P Received: from [127.0.0.1] (ident=ph10)
+[6@\14] by xxxxx.cam.example with smtp (Exim 4.00)
+[7@\14] id 16RdAL-0006pc-00
+[8@\14] for ph10@@cam.example; Mon, 16 Sep 2002 16:09:43 +0100
+[9@\14] F From: @<@>
+[10@\14] Subject: this is a test header
+[11@\14] X-something: this is another header
+[12@\14] I Message-Id: <E16RdAL-0006pc-00@@xxxxx.cam.example>
+[13@\14] B Bcc:
+[14/14] Date: Mon, 16 Sep 2002 16:09:43 +0100}
+.endd
+Log lines that are neither too long nor contain newlines are written to syslog
+without modification.
+
+If only syslog is being used, the Exim monitor is unable to provide a log tail
+display, unless syslog is routing \*mainlog*\ to a file on the local host and
+the environment variable \\EXIMON@_LOG@_FILE@_PATH\\ is set to tell the monitor
+where it is.
+
+
+.section Log line flags
+One line is written to the main log for each message received, and for each
+successful, unsuccessful, and delayed delivery. These lines can readily be
+picked out by the distinctive two-character flags that immediately follow the
+timestamp. The flags are:
+.display
+.tabs 6
+<= $t $rm{message arrival}
+=> $t $rm{normal message delivery}
+-> $t $rm{additional address in same delivery}
+*> $t $rm{delivery suppressed by \-N-\}
+** $t $rm{delivery failed; address bounced}
+== $t $rm{delivery deferred; temporary problem}
+.endd
+
+
+.section Logging message reception
+.index log||reception line
+The format of the single-line entry in the main log that is written for every
+message received is shown in the basic example below, which is split over
+several lines in order to fit it on the page:
+.display
+.indent 0
+2002-10-31 08:57:53 16ZCW1-0005MB-00 <= kryten@@dwarf.fict.example
+ H=mailer.fict.example [192.168.123.123] U=exim
+ P=smtp S=5678 id=<<incoming message id>>
+.endd
+The address immediately following `<=' is the envelope sender address. A bounce
+message is shown with the sender address `<>', and if it is locally generated,
+this is followed by an item of the form
+.display
+R=<<message id>>
+.endd
+which is a reference to the message that caused the bounce to be sent.
+
+.index \\HELO\\
+.index \\EHLO\\
+For messages from other hosts, the H and U fields identify the remote host and
+record the RFC 1413 identity of the user that sent the message, if one was
+received. The number given in square brackets is the IP address of the sending
+host. If there is a single, unparenthesized host name in the H field, as
+above, it has been verified to correspond to the IP address (see the
+\host@_lookup\ option). If the name is in parentheses, it was the name quoted
+by the remote host in the SMTP \\HELO\\ or \\EHLO\\ command, and has not been
+verified. If verification yields a different name to that given for \\HELO\\ or
+\\EHLO\\, the verified name appears first, followed by the \\HELO\\ or \\EHLO\\
+name in parentheses.
+
+Misconfigured hosts (and mail forgers) sometimes put an IP address, with or
+without brackets, in the \\HELO\\ or \\EHLO\\ command, leading to entries in
+the log containing text like these examples:
+.display
+H=(10.21.32.43) [192.168.8.34]
+H=([10.21.32.43]) [192.168.8.34]
+.endd
+This can be confusing. Only the final address in square brackets can be relied
+on.
+
+For locally generated messages (that is, messages not received over TCP/IP),
+the H field is omitted, and the U field contains the login name of the caller
+of Exim.
+
+.index authentication||logging
+.index \\AUTH\\||logging
+For all messages, the P field specifies the protocol used to receive the
+message. This is set to `asmtp' for messages received from hosts which have
+authenticated themselves using the SMTP \\AUTH\\ command. In this case there is
+an additional item A= followed by the name of the authenticator that was used.
+If an authenticated identification was set up by the authenticator's
+\server@_set@_id\ option, this is logged too, separated by a colon from the
+authenticator name.
+
+The id field records the existing message id, if present.
+.index size||of message
+The size of the received message is given by the S field. When the message is
+delivered, headers may get removed or added, so that the size of delivered
+copies of the message may not correspond with this value (and indeed may be
+different to each other).
+
+The \log@_selector\ option can be used to request the logging of additional
+data when a message is received. See section ~~SECTlogselector below.
+
+
+.section Logging deliveries
+.index log||delivery line
+The format of the single-line entry in the main log that is written for every
+delivery is shown in one of the examples below, for local and remote deliveries,
+respectively. Each example has been split into two lines in order to fit
+it on the page:
+.display
+.indent 0
+2002-10-31 08:59:13 16ZCW1-0005MB-00 => marv <marv@@hitch.fict.example>
+ R=localuser T=local@_delivery
+2002-10-31 09:00:10 16ZCW1-0005MB-00 => monk@@holistic.fict.example
+ R=dnslookup T=remote@_smtp H=holistic.fict.example [192.168.234.234]
+.endd
+For ordinary local deliveries, the original address is given in angle brackets
+after the final delivery address, which might be a pipe or a file. If
+intermediate address(es) exist between the original and the final address, the
+last of these is given in parentheses after the final address. The R and T
+fields record the router and transport that were used to process the address.
+
+If a shadow transport was run after a successful local delivery, the log line
+for the successful delivery has an item added on the end, of the form
+.display
+ST=<<shadow transport name>>
+.endd
+If the shadow transport did not succeed, the error message is put in
+parentheses afterwards.
+
+When more than one address is included in a single delivery (for example, two
+SMTP \\RCPT\\ commands in one transaction) the second and subsequent
+addresses are flagged with `$tt{@-@>}' instead of `$tt{@=@>}'. When two or more
+messages are delivered down a single SMTP connection, an asterisk follows the
+IP address in the log lines for the second and subsequent messages.
+
+The generation of a reply message by a filter file gets logged as a `delivery'
+to the addressee, preceded by `>'.
+
+The \log@_selector\ option can be used to request the logging of additional
+data when a message is delivered. See section ~~SECTlogselector below.
+
+
+.section Discarded deliveries
+.index discarded messages
+.index message||discarded
+.index delivery||discarded, logging
+When a message is discarded as a result of the command `seen finish' being
+obeyed in a filter file which generates no deliveries, a log entry of the form
+.display
+2002-12-10 00:50:49 16auJc-0001UB-00 => discarded
+ <low.club@@bridge.example> R=userforward
+.endd
+is written, to record why no deliveries are logged. When a message is discarded
+because it is aliased to `:blackhole:' the log line is like this:
+.display asis
+1999-03-02 09:44:33 10HmaX-0005vi-00 => :blackhole:
+ <hole@nowhere.example> R=blackhole_router
+.endd
+
+
+.section Deferred deliveries
+When a delivery is deferred, a line of the following form is logged:
+.display
+.indent 0
+2002-12-19 16:20:23 16aiQz-0002Q5-00 == marvin@@endrest.example
+ R=dnslookup T=smtp defer (146): Connection refused
+.endd
+In the case of remote deliveries, the error is the one that was given for the
+last IP address that was tried. Details of individual SMTP failures are also
+written to the log, so the above line would be preceded by something like
+.display
+.indent 0
+2002-12-19 16:20:23 16aiQz-0002Q5-00 Failed to connect to
+ mail1.endrest.example [192.168.239.239]: Connection refused
+.endd
+When a deferred address is skipped because its retry time has not been reached,
+a message is written to the log, but this can be suppressed by setting an
+appropriate value in \log@_selector\.
+
+
+.section Delivery failures
+.index delivery||failure, logging
+If a delivery fails because an address cannot be routed, a line of the
+following form is logged:
+.display asis
+.indent 0
+1995-12-19 16:20:23 0tRiQz-0002Q5-00 ** jim@trek99.example
+ <jim@trek99.example>: unknown mail domain
+.endd
+If a delivery fails at transport time, the router and transport are shown, and
+the response from the remote host is included, as in this example:
+.display asis
+.indent 0
+2002-07-11 07:14:17 17SXDU-000189-00 ** ace400@pb.example R=dnslookup
+.newline
+.em
+ T=remote_smtp: SMTP error from remote mailer after pipelined
+.newline
+.nem
+ RCPT TO:<ace400@pb.example>: host pbmail3.py.example
+ [192.168.63.111]: 553 5.3.0 <ace400@pb.example>...
+ Addressee unknown
+.endd
+.em
+The word `pipelined' indicates that the SMTP \\PIPELINING\\ extension was being
+used. See \hosts@_avoid@_esmtp\ in the \%smtp%\ transport for a way of
+disabling \\PIPELINING\\.
+.nem
+
+The log lines for all forms of delivery failure are flagged with \"**"\.
+
+
+.section Fake deliveries
+.index delivery||fake, logging
+If a delivery does not actually take place because the \-N-\ option has been
+used to suppress it, a normal delivery line is written to the log, except that
+`=>' is replaced by `$*$>'.
+
+
+.section Completion
+A line of the form
+.display
+2002-10-31 09:00:11 16ZCW1-0005MB-00 Completed
+.endd
+is written to the main log when a message is about to be removed from the spool
+at the end of its processing.
+
+
+
+.section Summary of Fields in Log Lines
+.index log||summary of fields
+A summary of the field identifiers that are used in log lines is shown in
+the following table:
+.display flow
+.tabs 8
+A $t $rm{authenticator name (and optional id)}
+C $t $rm{SMTP confirmation on delivery}
+.newline
+.em
+CV $t $rm{certificate verification status}
+DN $t $rm{distinguished name from peer certificate}
+DT $t $rm{time taken for a delivery}
+.newline
+.nem
+F $t $rm{sender address (on delivery lines)}
+H $t $rm{host name and IP address}
+.newline
+.em
+I $t $rm{local interface used}
+.newline
+.nem
+id $t $rm{message id for incoming message}
+P $t $rm{on \"<="\ lines: protocol used}
+.newline
+.em
+ $t $rm{on \"=>"\ lines: return path}
+QT $t $rm{time spent on queue}
+.newline
+.nem
+R $t $rm{on \"<="\ lines: reference for local bounce}
+ $t $rm{on \"=>"\ lines: router name}
+S $t $rm{size of message}
+ST $t $rm{shadow transport name}
+T $t $rm{on \"<="\ lines: message subject (topic)}
+ $t $rm{on \"=>"\ lines: transport name}
+U $t $rm{local user or RFC 1413 identity}
+X $t $rm{TLS cipher suite}
+.endd
+
+
+.section Other log entries
+Various other types of log entry are written from time to time. Most should be
+self-explanatory. Among the more common are:
+.numberpars $.
+.index retry||time not reached
+\*retry time not reached*\##An address previously suffered a temporary error
+during routing or local delivery, and the time to retry has not yet arrived.
+This message is not written to an individual message log file unless it happens
+during the first delivery attempt.
+.nextp
+\*retry time not reached for any host*\##An address previously suffered
+temporary errors during remote delivery, and the retry time has not yet arrived
+for any of the hosts to which it is routed.
+.nextp
+.index spool directory||file locked
+\*spool file locked*\##An attempt to deliver a message cannot proceed because
+some other Exim process is already working on the message. This can be quite
+common if queue running processes are started at frequent intervals. The
+\*exiwhat*\ utility script can be used to find out what Exim processes are
+doing.
+.nextp
+.em
+.index error||ignored
+\*error ignored*\##There are several circumstances that give rise to this
+message:
+.numberpars " "
+Exim failed to deliver a bounce message whose age was greater than
+\ignore__bounce__errors__after\. The bounce was discarded.
+.nextp
+A filter file set up a delivery using the `noerror' option, and the delivery
+failed. The delivery was discarded.
+.nextp
+A delivery set up by a router configured with
+.display asis
+errors_to = <>
+.endd
+failed. The delivery was discarded.
+.endp
+.nem
+.endp
+
+
+
+.section Reducing or increasing what is logged
+.rset SECTlogselector "~~chapter.~~section"
+.index log||selectors
+By setting the \log@_selector\ global option, you can disable some of Exim's
+default logging, or you can request additional logging. The value of
+\log@_selector\ is made up of names preceded by plus or minus characters. For
+example:
+.display asis
+log_selector = +arguments -retry_defer
+.endd
+The list of optional log items is in the following table, with the default
+selection marked by asterisks:
+.display flow
+.tabs 32
+ address@_rewrite $t $rm{address rewriting}
+ all@_parents $t $rm{all parents in => lines}
+ arguments $t $rm{command line arguments}
+*connection@_reject $t $rm{connection rejections}
+*delay@_delivery $t $rm{immediate delivery delayed (message queued)}
+.newline
+.em
+ deliver@_time $t $rm{time taken to perform delivery}
+.newline
+.nem
+ delivery@_size $t $rm{add S=nnn to => lines}
+*dnslist@_defer $t $rm{defers of DNS list (aka RBL) lookups}
+*etrn $t $rm{ETRN commands}
+*host@_lookup@_failed $t $rm{as it says}
+.newline
+.em
+ ident@_timeout $t $rm{timeout for ident connection}
+.newline
+.nem
+ incoming@_interface $t $rm{incoming interface on <= lines}
+ incoming@_port $t $rm{incoming port on <= lines}
+*lost@_incoming@_connection $t $rm{as it says (includes timeouts)}
+.newline
+.em
+ outgoing@_port $t $rm{add remote port to => lines}
+.newline
+.nem
+*queue@_run $t $rm{start and end queue runs}
+.newline
+.em
+ queue@_time $t $rm{time on queue}
+.newline
+.nem
+ received@_recipients $t $rm{recipients on <= lines}
+ received@_sender $t $rm{sender on <= lines}
+*rejected@_header $t $rm{header contents on reject log}
+*retry@_defer $t $rm{`retry time not reached'}
+.newline
+.em
+ return@_path@_on@_delivery $t $rm{put return path on => and ** lines}
+.newline
+.nem
+ sender@_on@_delivery $t $rm{add sender to => lines}
+*size@_reject $t $rm{rejection because too big}
+*skip@_delivery $t $rm{`message is frozen', `spool file is locked'}
+.newline
+.em
+ smtp@_confirmation $t $rm{SMTP confirmation on => lines}
+.newline
+.nem
+ smtp@_connection $t $rm{SMTP connections}
+ smtp@_incomplete@_transaction $t $rm{incomplete SMTP transactions}
+ smtp@_protocol@_error $t $rm{SMTP protocol errors}
+ smtp@_syntax@_error $t $rm{SMTP syntax errors}
+ subject $t $rm{contents of ::Subject:: on <= lines}
+.newline
+.em
+ tls@_certificate@_verified $t $rm{certificate verification status}
+.newline
+.nem
+*tls@_cipher $t $rm{TLS cipher suite on <= and => lines}
+ tls@_peerdn $t $rm{TLS peer DN on <= and => lines}
+
+ all $t $rm{all of the above}
+.endd
+More details on each of these items follows:
+.numberpars $.
+.index log||rewriting
+.index rewriting||logging
+\address@_rewrite\: This applies both to global rewrites and per-transport
+rewrites,
+.em
+but not to rewrites in filters run as an unprivileged user (because such users
+cannot access the log).
+.nem
+.nextp
+.index log||full parentage
+\all@_parents\: Normally only the original and final addresses are logged on
+delivery lines; with this selector, intermediate parents are given in
+parentheses between them.
+.nextp
+.index log||Exim arguments
+.index Exim arguments, logging
+\arguments\: This causes Exim to write the arguments with which it was called
+to the main log,
+preceded by the current working directory.
+This is a debugging feature, added to make it easier to find out how certain
+MUAs call \(/usr/sbin/sendmail)\. The logging does not happen if Exim has given
+up root privilege because it was called with the \-C-\ or \-D-\ options.
+Arguments that are empty or that contain whitespace are quoted. Non-printing
+characters are shown as escape sequences.
+This facility cannot log unrecognized arguments, because the arguments are
+checked before the configuration file is read. The only way to log such cases
+is to interpose a script such as \(util/logargs.sh)\ between the caller and
+Exim.
+.nextp
+.index log||connection rejections
+\connection@_reject\: A log entry is written whenever an incoming SMTP
+connection is rejected, for whatever reason.
+.nextp
+.index log||delayed delivery
+.index delayed delivery, logging
+\delay@_delivery\: A log entry is written whenever a delivery process is not
+started for an incoming message because the load is too high or too many
+messages were received on one connection. Logging does not occur if no delivery
+process is started because \queue@_only\ is set or \-odq-\ was used.
+.nextp
+.em
+.index log||delivery duration
+\deliver@_time\: For each delivery, the amount of real time it has taken to
+perform the actual delivery is logged as DT=<<time>>, for example, \"DT=1s"\.
+.nem
+.nextp
+.index log||message size on delivery
+.index size||of message
+\delivery@_size\: For each delivery, the size of message delivered is added to
+the `=>' line, tagged with S=.
+.nextp
+.index log||dnslist defer
+.index DNS list||logging defer
+.index black list (DNS)
+\dnslist@_defer\: A log entry is written if an attempt to look up a host in a
+DNS black list suffers a temporary error.
+.nextp
+.index log||ETRN commands
+.index \\ETRN\\||logging
+\etrn\: Every legal ETRN command that is received is logged, before the ACL is
+run to determine whether or not it is actually accepted. An invalid ETRN
+command, or one received within a message transaction is not logged by this
+selector (see \smtp@_syntax@_error\ and \smtp@_protocol@_error\).
+.nextp
+.index log||host lookup failure
+\host@_lookup@_failed\: When a lookup of a host's IP addresses fails to find
+any addresses, or when a lookup of an IP address fails to find a host name, a
+log line is written. This logging does not apply to direct DNS lookups when
+routing email addresses, but it does apply to `byname' lookups.
+.nextp
+.em
+.index log||ident timeout
+.index RFC 1413||logging timeout
+\ident@_timeout\: A log line is written whenever an attempt to connect to a
+client's ident port times out.
+.nem
+.nextp
+.index log||incoming interface
+.index interface||logging
+\incoming@_interface\: The interface on which a message was received is added
+to the `<=' line as an IP address in square brackets, tagged by I= and followed
+by a colon and the port number.
+.em
+The local interface and port are also added to other SMTP log
+lines, for example `SMTP connection from', and to rejection lines.
+.nem
+.nextp
+.index log||incoming remote port
+.index port||logging remote
+.index TCP/IP||logging incoming remote port
+\incoming@_port\: The remote port number from which a message was received is
+added to log entries and ::Received:: header lines, following the IP address in
+square brackets, and separated from it by a colon. This is implemented by
+changing the value that is put in the \$sender@_fullhost$\ and
+\$sender@_rcvhost$\ variables. Recording the remote port number has become more
+important with the widening use of NAT (see RFC 2505).
+.nextp
+.index log||dropped connection
+\lost@_incoming@_connection\: A log line is written when an incoming SMTP
+connection is unexpectedly dropped.
+.nextp
+.em
+.index log||outgoing remote port
+.index port||logging outgoint remote
+.index TCP/IP||logging ougtoing remote port
+\outgoing@_port\: The remote port number is added to delivery log lines (those
+containing => tags) following the IP address. This option is not included in
+the default setting, because for most ordinary configurations, the remote port
+number is always 25 (the SMTP port).
+.nem
+.nextp
+.index log||queue run
+.index queue runner||logging
+\queue@_run\: The start and end of every queue run are logged.
+.nextp
+.em
+.index log||queue time
+\queue@_time\: The amount of time the message has been in the queue on the
+local host is logged as QT=<<time>>, for example, \"QT=3m45s"\. The clock
+starts when Exim starts to receive the message, so it includes reception time
+as well as the delivery time of the current address.
+.nem
+.nextp
+.index log||recipients
+\received@_recipients\: The recipients of a message are listed in the main log
+as soon as the message is received. The list appears at the end of the log line
+that is written when a message is received, preceded by the word `for'. The
+addresses are listed after they have been qualified, but before any rewriting
+has taken place.
+Recipients that were discarded by an ACL for \\MAIL\\ or \\RCPT\\ do not appear
+in the list.
+.nextp
+.index log||sender reception
+\received@_sender\: The unrewritten original sender of a message is added to
+the end of the log line that records the message's arrival, after the word
+`from' (before the recipients if \received@_recipients\ is also set).
+.nextp
+.index log||header lines for rejection
+\rejected@_header\: If a message's header has been received at the time a
+rejection is written to the reject log, the complete header is added to the
+log. Header logging can be turned off individually for messages that are
+rejected by the \*local@_scan()*\ function (see section ~~SECTapiforloc).
+.nextp
+.index log||retry defer
+\retry@_defer\: A log line is written if a delivery is deferred because a retry
+time has not yet been reached. However, this `retry time not reached' message
+is always omitted from individual message logs after the first delivery
+attempt.
+.nextp
+.index log||return path
+.em
+\return@_path@_on@_delivery\: The return path that is being transmitted with
+the message is included in delivery and bounce lines, using the tag P=.
+.nem
+.nextp
+.index log||sender on delivery
+\sender@_on@_delivery\: The message's sender address is added to every delivery
+and bounce line, tagged by F= (for `from').
+.em
+This is the original sender that was received with the message; it is not
+necessarily the same as the outgoing return path.
+.nem
+.nextp
+.index log||size rejection
+\size@_reject\: A log line is written whenever a message is rejected because it
+is too big.
+.nextp
+.index log||frozen messages, skipped
+.index frozen messages||logging skipping
+\skip@_delivery\: A log line is written whenever a message is skipped during a
+queue run because it is frozen or because another process is already delivering
+it.
+.nextp
+.index log||smtp confirmation
+.index SMTP||logging confirmation
+\smtp@_confirmation\: The response to the final `.' in the SMTP dialogue for
+outgoing messages is added to delivery log lines in the form `C="<<text>>"'. A
+number of MTAs (including Exim) return an identifying string in this response.
+.nextp
+.index log||SMTP connections
+.index SMTP||logging connections
+\smtp@_connection\: A log line is written whenever an SMTP connection is
+established or closed. (By contrast, \lost@_incoming@_connection\ applies only
+when the closure is unexpected.) This applies to connections from local
+processes that use \-bs-\ as well as to TCP/IP connections. If a connection is
+dropped in the middle of a message, a log line is always written, whether this
+selector is set or not, but otherwise nothing is written at the start and end
+of connections unless this selector is enabled.
+
+For TCP/IP connections to an Exim daemon, the current number of connections is
+included in the log message for each new connection, but note that the count is
+reset if the daemon is restarted.
+Also, because connections are closed (and the closure is logged) in
+subprocesses, the count may not include connections that have been closed but
+whose termination the daemon has not yet noticed. Thus, while it is possible to
+match up the opening and closing of connections in the log, the value of the
+logged counts may not be entirely accurate.
+.nextp
+.index log||SMTP transaction, incomplete
+.index SMTP||logging incomplete transactions
+\smtp@_incomplete@_transaction\: When a mail transaction is aborted by
+\\RSET\\, \\QUIT\\, loss of connection, or otherwise, the incident is logged,
+and the message sender plus any accepted recipients are included in the log
+line. This can provide evidence of dictionary attacks.
+.nextp
+.index log||SMTP protocol error
+.index SMTP||logging protocol error
+\smtp@_protocol@_error\: A log line is written for every SMTP protocol error
+encountered.
+.em
+Exim does not have perfect detection of all protocol errors because of
+transmission delays and the use of pipelining. If \\PIPELINING\\ has been
+advertised to a client, an Exim server assumes that the client will use it, and
+therefore it does not count `expected' errors (for example, \\RCPT\\ received
+after rejecting \\MAIL\\) as protocol errors.
+.nem
+.nextp
+.index SMTP||logging syntax errors
+.index SMTP||syntax errors, logging
+.index SMTP||unknown command, logging
+.index log||unknown SMTP command
+.index log||SMTP syntax error
+\smtp@_syntax@_error\: A log line is written for every SMTP syntax error
+encountered. An unrecognized command is treated as a syntax error. For an
+external connection, the host identity is given; for an internal connection
+using \-bs-\ the sender identification (normally the calling user) is given.
+.nextp
+.index log||subject
+.index subject, logging
+\subject\: The subject of the message is added to the arrival log line,
+preceded by `T=' (T for `topic', since S is already used for `size').
+Any MIME `words' in the subject are decoded. The \print@_topbitchars\ option
+specifies whether characters with values greater than 127 should be logged
+unchanged, or whether they should be rendered as escape sequences.
+.nextp
+.index log||certificate verification
+.em
+\tls@_certificate@_verified\: An extra item is added to <= and => log lines
+when TLS is in use. The item is \"CV=yes"\ if the peer's certificate was
+verified, and \"CV=no"\ if not.
+.nem
+.nextp
+.index log||TLS cipher
+.index TLS||logging cipher
+\tls@_cipher\: When a message is sent or received over an encrypted connection,
+the cipher suite used is added to the log line, preceded by X=.
+.nextp
+.index log||TLS peer DN
+.index TLS||logging peer DN
+\tls@_peerdn\: When a message is sent or received over an encrypted connection,
+and a certificate is supplied by the remote host, the peer DN is added to the
+log line, preceded by DN=.
+.endp
+
+.section Message log
+.index message||log file for
+.index log||message log, description of
+In addition to the general log files, Exim writes a log file for each message
+that it handles. The names of these per-message logs are the message ids, and
+.index \(msglog)\ directory
+they are kept in the \(msglog)\ sub-directory of the spool directory. Each
+message log contains copies of the log lines that apply to the message. This
+makes it easier to inspect the status of an individual message without having
+to search the main log. A message log is deleted when processing of the message
+is complete,
+.index \preserve@_message@_logs\
+unless \preserve__message__logs\ is set, but this should be used only with
+great care because they can fill up your disk very quickly.
+
+On a heavily loaded system, it may be desirable to disable the use of
+per-message logs, in order to reduce disk I/O. This can be done by setting the
+\message@_logs\ option false.
+
+
+
+.
+.
+.
+. ============================================================================
+.chapter Exim utilities
+.set runningfoot "utilities"
+.rset CHAPutils ~~chapter
+.index utilities
+A number of utility scripts and programs are supplied with Exim and are
+described in this chapter. There is also the Exim Monitor, which is covered in
+the next chapter. The utilities described here are:
+
+. This duplication seems to be the only way to arrange that the cross-
+. references are omitted in the Texinfo version. They look horribly ugly.
+
+.if ~~texinfo
+.display rm
+.tabs 22
+\*exiwhat*\ $t $rm{list what Exim processes are doing}
+.newline
+\*exiqgrep*\ $t $rm{grep the queue}
+.newline
+\*exiqsumm*\ $t $rm{summarize the queue}
+\*exigrep*\ $t $rm{search the main log}
+\*exipick*\ $t $rm{select messages on various criteria}
+\*exicyclog*\ $t $rm{cycle (rotate) log files}
+\*eximstats*\ $t $rm{extract statistics from the log}
+\*exim@_checkaccess*\ $t $rm{check address acceptance from given IP}
+\*exim@_dbmbuild*\ $t $rm{build a DBM file}
+\*exinext*\ $t $rm{extract retry information}
+\*exim@_dumpdb*\ $t $rm{dump a hints database}
+\*exim@_tidydb*\ $t $rm{clean up a hints database}
+\*exim@_fixdb*\ $t $rm{patch a hints database}
+\*exim@_lock*\ $t $rm{lock a mailbox file}
+.endd
+.
+.else
+.
+.display rm
+.tabs 22
+~~SECTfinoutwha \*exiwhat*\ $t $rm{list what Exim processes are doing}
+.newline
+~~SECTgreptheque \*exiqgrep*\ $t $rm{grep the queue}
+.newline
+~~SECTsumtheque \*exiqsumm*\ $t $rm{summarize the queue}
+~~SECTextspeinf \*exigrep*\ $t $rm{search the main log}
+.newline
+.em
+~~SECTexipick \*exipick*\ $t $rm{select messages on various criteria}
+.newline
+.nem
+~~SECTcyclogfil \*exicyclog*\ $t $rm{cycle (rotate) log files}
+~~SECTmailstat \*eximstats*\ $t $rm{extract statistics from the log}
+~~SECTcheckaccess \*exim@_checkaccess*\ $t $rm{check address acceptance from given IP}
+~~SECTdbmbuild \*exim@_dbmbuild*\ $t $rm{build a DBM file}
+~~SECTfinindret \*exinext*\ $t $rm{extract retry information}
+~~SECThindatmai \*exim@_dumpdb*\ $t $rm{dump a hints database}
+~~SECThindatmai \*exim@_tidydb*\ $t $rm{clean up a hints database}
+~~SECThindatmai \*exim@_fixdb*\ $t $rm{patch a hints database}
+~~SECTmailboxmaint \*exim@_lock*\ $t $rm{lock a mailbox file}
+.endd
+.fi
+
+.section Finding out what Exim processes are doing (exiwhat)
+.rset SECTfinoutwha "~~chapter.~~section"
+.index \*exiwhat*\
+.index process, querying
+.index \\SIGUSR1\\
+On operating systems that can restart a system call after receiving a signal
+(most modern OS), an Exim process responds to the \\SIGUSR1\\ signal by writing
+a line describing what it is doing to the file \(exim-process.info)\ in the
+Exim spool directory. The \*exiwhat*\ script sends the signal to all Exim
+processes it can find, having first emptied the file. It then waits for one
+second to allow the Exim processes to react before displaying the results.
+In order to run \*exiwhat*\ successfully you have to have sufficient privilege to
+send the signal to the Exim processes, so it is normally run as root.
+
+Unfortunately, the \*ps*\ command which \*exiwhat*\ uses to find Exim processes
+varies in different operating systems. Not only are different options used,
+but the format of the output is different. For this reason, there are some
+system configuration options that configure exactly how \*exiwhat*\ works. If it
+doesn't seem to be working for you, check the following compile-time options:
+.display
+EXIWHAT@_PS@_CMD $rm{the command for running \*ps*\}
+EXIWHAT@_PS@_ARG $rm{the argument for \*ps*\}
+EXIWHAT@_EGREP@_ARG $rm{the argument for \*egrep*\ to select from \*ps*\ output}
+EXIWHAT@_KILL@_ARG $rm{the argument for the \*kill*\ command}
+.endd
+An example of typical output from \*exiwhat*\ is
+.display
+.indent 0
+ 164 daemon: -q1h, listening on port 25
+10483 running queue: waiting for 0tAycK-0002ij-00 (10492)
+10492 delivering 0tAycK-0002ij-00 to mail.ref.example [10.19.42.42]
+ (editor@@ref.example)
+10592 handling incoming call from [192.168.243.242]
+10628 accepting a local non-SMTP message
+.endd
+The first number in the output line is the process number. The third line has
+been split here, in order to fit it on the page.
+
+
+.section Selective queue listing (exiqgrep)
+.rset SECTgreptheque "~~chapter.~~section"
+.index \*exiqgrep*\
+.index queue||grepping
+This utility is a Perl script contributed by Matt Hubbard. It runs
+.display asis
+exim -bpu
+.endd
+to obtain a queue listing with undelivered recipients only, and then greps the
+output to select messages that match given criteria. The following selection
+options are available:
+
+.startoptions
+
+.option f <<regex>>
+Match the sender address. The field that is tested is enclosed in angle
+brackets, so you can test for bounce messages with
+.display asis
+exiqgrep -f '^<>$'
+.endd
+
+.option r <<regex>>
+Match a recipient address. The field that is tested is not enclosed in angle
+brackets.
+
+.option s <<regex>>
+Match against the size field.
+
+.option y <<seconds>>
+Match messages that are younger than the given time.
+
+.option o <<seconds>>
+Match messages that are older than the given time.
+
+.option z
+Match only frozen messages.
+
+.option x
+Match only non-frozen messages.
+
+.endoptions
+
+The following options control the format of the output:
+
+.startoptions
+
+.option c
+Display only the count of matching messages.
+
+.option l
+Long format -- display the full message information as output by Exim. This is
+the default.
+
+.option i
+Display message ids only.
+
+.option b
+Brief format -- one line per message.
+
+.option R
+Display messages in reverse order.
+
+.endoptions
+
+There is one more option, \-h-\, which outputs a list of options.
+
+
+.section Summarising the queue (exiqsumm)
+.rset SECTsumtheque "~~chapter.~~section"
+.index \*exiqsumm*\
+.index queue||summary
+The \*exiqsumm*\ utility is a Perl script which reads the output of \*exim
+-bp*\ and produces a summary of the messages on the queue. Thus, you use it by
+running a command such as
+.display asis
+exim -bp | exiqsumm
+.endd
+The output consists of one line for each domain that has messages waiting for
+it, as in the following example:
+.display asis
+ 3 2322 74m 66m msn.com.example
+.endd
+Each line lists the number of
+pending deliveries for a domain, their total volume, and the length of time
+that the oldest and the newest messages have been waiting. Note that the number
+of pending deliveries is greater than the number of messages when messages
+have more than one recipient.
+
+A summary line is output at the end. By default the output is sorted on the
+domain name, but \*exiqsumm*\ has the options \-a-\ and \-c-\, which cause the
+output to be sorted by oldest message and by count of messages, respectively.
+
+The output of \*exim -bp*\ contains the original addresses in the message, so
+this also applies to the output from \*exiqsumm*\. No domains from addresses
+generated by aliasing or forwarding are included (unless the \one@_time\ option
+of the \%redirect%\ router has been used to convert them into `top level'
+addresses).
+
+
+
+.section Extracting specific information from the log (exigrep)
+.rset SECTextspeinf "~~chapter.~~section"
+.index \*exigrep*\
+.index log||extracts, grepping for
+The \*exigrep*\ utility is a Perl script that searches one or more main log
+files for entries that match a given pattern. When it finds a match, it
+extracts all the log entries for the relevant message, not just those that
+match the pattern. Thus, \*exigrep*\ can extract complete log entries for a
+given message, or all mail for a given user, or for a given host, for example.
+
+.em
+If a matching log line is not associated with a specific message, it is always
+included in \*exigrep*\'s output.
+.nem
+The usage is:
+.display asis
+exigrep [-l] [-t<n>] <pattern> [<log file>] ...
+.endd
+The \-t-\ argument specifies a number of seconds. It adds an additional
+condition for message selection. Messages that are complete are shown only if
+they spent more than <<n>> seconds on the queue.
+
+The \-l-\ flag means `literal', that is, treat all characters in the
+pattern as standing for themselves. Otherwise the pattern must be a Perl
+regular expression. The pattern match is case-insensitive. If no file names are
+given on the command line, the standard input is read.
+
+If the location of a \*zcat*\ command is known from the definition of
+\\ZCAT@_COMMAND\\ in \(Local/Makefile)\, \*exigrep*\ automatically passes any
+file whose name ends in \\COMPRESS@_SUFFIX\\ through \*zcat*\ as it searches
+it.
+
+.em
+.section Selecting messages by various criteria (exipick)
+.rset SECTexipick "~~chapter.~~section"
+.index \*exipick*\
+John Jetmore's \*exipick*\ utility is included in the Exim distribution. It
+lists messages from the queue according to a variety of criteria. For details,
+run:
+.display asis
+exipick --help
+.endd
+.nem
+
+
+.section Cycling log files (exicyclog)
+.rset SECTcyclogfil "~~chapter.~~section"
+.index log||cycling local files
+.index cycling logs
+.index \*exicyclog*\
+The \*exicyclog*\ script can be used to cycle (rotate) \*mainlog*\ and
+\*rejectlog*\ files. This is not necessary if only syslog is being used,
+or if you are using log files with datestamps in their names (see section
+~~SECTdatlogfil).
+Some operating systems have their own standard mechanisms for log cycling, and
+these can be used instead of \*exicyclog*\ if preferred.
+
+Each time \*exicyclog*\ is run the file names get `shuffled down' by one. If the
+main log file name is \(mainlog)\ (the default) then when \*exicyclog*\ is run
+\(mainlog)\ becomes \(mainlog.01)\, the previous \(mainlog.01)\ becomes
+\(mainlog.02)\ and so on, up to a limit which is set in the script, and which
+defaults to 10. Reject logs are handled similarly.
+
+If no \(mainlog)\ file exists, the script does nothing. Files that `drop off'
+the end are deleted. All files with numbers greater than 01 are compressed,
+using a compression command which is configured by the \\COMPRESS@_COMMAND\\
+setting in \(Local/Makefile)\. It is usual to run \*exicyclog*\ daily from a
+root \crontab\ entry of the form
+.display
+1 0 * * * su exim -c /usr/exim/bin/exicyclog
+.endd
+assuming you have used the name `exim' for the Exim user. You can run
+\*exicyclog*\ as root if you wish, but there is no need.
+
+
+.section Mail statistics (eximstats)
+.rset SECTmailstat "~~chapter.~~section"
+.index statistics
+.index \*eximstats*\
+A Perl script called \*eximstats*\ is provided for extracting statistical
+information from log files. The output is either plain text, or HTML.
+Exim log files are also suported by the \*Lire*\ system produced by the
+LogReport Foundation (\?http://www.logreport.org?\).
+
+The \*eximstats*\ script has been hacked about quite a bit over time. The
+latest version is the result of some extensive revision by Steve Campbell. A
+lot of information is given by default, but there are options for suppressing
+various parts of it. Following any options, the arguments to the script are a
+list of files, which should be main log files. For example:
+.display asis
+eximstats -nr /var/spool/exim/log/mainlog.01
+.endd
+By default, \*eximstats*\ extracts information about the number and volume of
+messages received from or delivered to various hosts. The information is sorted
+both by message count and by volume, and the top fifty hosts in each category
+are listed on the standard output. Similar information, based on email
+addresses or domains instead of hosts can be requested by means of various
+options. For messages delivered and received locally, similar statistics are
+also produced per user.
+
+The output also includes total counts and statistics about delivery errors, and
+histograms showing the number of messages received and deliveries made in each
+hour of the day. A delivery with more than one address in its envelope (for
+example, an SMTP transaction with more than one \\RCPT\\ command) is counted
+as a single delivery by \*eximstats*\.
+
+Though normally more deliveries than receipts are reported (as messages may
+have multiple recipients), it is possible for \*eximstats*\ to report more
+messages received than delivered, even though the queue is empty at the start
+and end of the period in question. If an incoming message contains no valid
+recipients, no deliveries are recorded for it. A bounce message is handled as
+an entirely separate message.
+
+\*eximstats*\ always outputs a grand total summary giving the volume and number
+of messages received and deliveries made, and the number of hosts involved in
+each case. It also outputs the number of messages that were delayed (that is,
+not completely delivered at the first attempt), and the number that had at
+least one address that failed.
+
+The remainder of the output is in sections that can be independently disabled
+or modified by various options. It consists of a summary of deliveries by
+transport, histograms of messages received and delivered per time interval
+(default per hour), information about the time messages spent on the queue,
+a list of relayed messages, lists of the top fifty sending hosts, local
+senders, destination hosts, and destination local users by count and by volume,
+and a list of delivery errors that occurred.
+
+The relay information lists messages that were actually relayed, that is, they
+came from a remote host and were directly delivered to some other remote host,
+without being processed (for example, for aliasing or forwarding) locally.
+
+The options for \*eximstats*\ are as follows:
+
+.startoptions
+.index \*eximstats*\||options
+.option bydomain
+The `league tables' are computed on the basis of the superior domains of the
+sending hosts instead of the sending and receiving hosts. This option may be
+combined with \-byhost-\ and/or \-byemail-\.
+
+.option byedomain
+This is a synonym for \-byemaildomain-\.
+
+.option byemail
+The `league tables' are computed on the basis of complete email addresses,
+instead of sending and receiving hosts. This option may be combined with
+\-byhost-\ and/or \-bydomain-\.
+
+.option byemaildomain
+The `league tables' are computed on the basis of the sender's email domain
+instead of the sending and receiving hosts. This option may be combined with
+\-byhost-\, \-bydomain-\, or \-byemail-\.
+
+.option byhost
+The `league tables' are computed on the basis of sending and receiving hosts.
+This is the default option. It may be combined with \-bydomain-\ and/or
+\-byemail-\.
+
+.option cache
+Cache results of \*timegm()*\ lookups. This results in a significant speedup
+when processing hundreds of thousands of messages, at a cost of increasing the
+memory utilisation.
+
+.option chartdir <<dir>>
+When \-charts-\ is specified, create the charts in the directory <<dir>>.
+
+.option chartrel <<dir>>
+When \-charts-\ is specified, this option specifies the relative directory for
+the \"img src="\ tags from where to include the charts.
+
+.option charts
+Create graphical charts to be displayed in HTML output. This requires the
+\"GD"\, \"GDTextUtil"\, and \"GDGraph"\ Perl modules, which can be obtained
+from \?http://www.cpan.org/modules/01modules.index.html?\.
+
+To install these, download and unpack them, then use the normal Perl
+installation procedure:
+.display asis
+perl Makefile.PL
+make
+make test
+make install
+.endd
+
+.option d
+This is a debug flag. It causes \*eximstats*\ to output the \*eval()*\'d parser
+to the standard output, which makes it easier to trap errors in the eval
+section. Remember to add one to the line numbers to allow for the title.
+
+
+.option help
+Show help information about \*eximstats*\' options.
+
+.option h <<n>>
+This option controls the histograms of messages received and deliveries per
+time interval. By default the time interval is one hour. If \-h0-\ is given,
+the histograms are suppressed; otherwise the value of <<n>> gives the number of
+divisions per hour. Valid values are 0, 1, 2, 3, 5, 10, 15, 20, 30 or 60, so
+\-h2-\ sets an interval of 30 minutes, and the default is equivalent to \-h1-\.
+
+.option html
+Output the results in HTML instead of plain text.
+
+.option merge
+This option causes \*eximstats*\ to merge old reports into a combined report.
+When this option is used, the input files must be outputs from previous calls
+to \*eximstats*\, not raw log files. For example, you could produce a set of
+daily reports and a weekly report by commands such as
+.display asis
+eximstats mainlog.sun > report.sun.txt
+eximstats mainlog.mon > report.mon.txt
+eximstats mainlog.tue > report.tue.txt
+eximstats mainlog.wed > report.wed.txt
+eximstats mainlog.thu > report.thu.txt
+eximstats mainlog.fri > report.fri.txt
+eximstats mainlog.sat > report.sat.txt
+eximstats -merge -html report.*.txt > weekly_report.html
+.endd
+You can merge text or html reports and output the results as text or html. You
+can use all the normal \*eximstats*\ output options, but only data included in
+the original reports can be shown. When merging reports, some loss of accuracy
+may occur in the `league tables', towards the ends of the lists. The order of
+items in the `league tables' may vary when the data volumes round to the same
+value.
+
+.option ne
+Suppress the display of information about failed deliveries (errors).
+
+.option nr
+Suppress information about messages relayed through this host.
+
+.option nr /pattern/
+Suppress information about relayed messages that match the pattern, which is
+matched against a string of the following form (split over two lines here in
+order to fit it on the page):
+.display asis
+H=<host> [<ip address>] A=<sender address> =>
+ H=<host> A=<recipient address>
+.endd
+for example
+.display asis
+H=in.host [1.2.3.4] A=from@some.where.example =>
+ H=out.host A=to@else.where.example
+.endd
+The sending host name appears in parentheses if it has not been verified as
+matching the IP address. The mail addresses are taken from the envelope, not
+the headers. This option allows you to screen out hosts whom you are happy to
+have using your host as a relay.
+
+.option nt
+Suppress the statistics about delivery by transport.
+
+.option nt/<<pattern>>/
+Suppress the statistics about delivery by any transport whose name matches the
+pattern. If you are using one transport to send all messages to a scanning
+mechanism before doing the real delivery, this feature can be used to omit that
+transport from your normal statistics (on the grounds that it is of no
+interest).
+
+
+.option "pattern" "#<<description>>#/<<pattern>>/"
+Count lines matching specified patterns and show them in
+the results. For example:
+.display asis
+-pattern 'Refused connections' '/refused connection/'
+.endd
+This option can be specified multiple times.
+
+.option q0
+Suppress information about times messages spend on the queue.
+
+.option q <<n1>>...
+This option sets an alternative list of time intervals for the queueing
+information. The values are separated by commas and are in seconds, but can
+involve arithmetic multipliers, so for example you can set 3$*$60 to specify 3
+minutes. A setting such as
+.display asis
+-q60,5*60,10*60
+.endd
+causes \*eximstats*\ to give counts of messages that stayed on the queue for less
+than one minute, less than five minutes, less than ten minutes, and over ten
+minutes.
+
+.option t <<n>>
+Sets the `top' count to <<n>>. This controls the listings of the `top <<n>>'
+hosts and users by count and volume. The default is 50, and setting 0
+suppresses the output altogether.
+
+.option tnl
+Omit local information from the `top' listings.
+
+.option t@_remote@_users
+Include remote users in the `top' listings.
+
+.endoptions
+
+
+.section Checking access policy (exim@_checkaccess)
+.rset SECTcheckaccess "~~chapter.~~section"
+.index \*exim@_checkaccess*\
+.index policy control||checking access
+.index checking access
+The \-bh-\ command line argument allows you to run a fake SMTP session with
+debugging output, in order to check what Exim is doing when it is applying
+policy controls to incoming SMTP mail. However, not everybody is sufficiently
+familiar with the SMTP protocol to be able to make full use of \-bh-\, and
+sometimes you just want to answer the question \*Does this address have
+access?*\ without bothering with any further details.
+
+The \*exim@_checkaccess*\ utility is a `packaged' version of \-bh-\. It takes
+two arguments, an IP address and an email address:
+.display asis
+exim_checkaccess 10.9.8.7 A.User@a.domain.example
+.endd
+The utility runs a call to Exim with the \-bh-\ option, to test whether the
+given email address would be accepted in a \\RCPT\\ command in a TCP/IP
+connection from the host with the given IP address. The output of the utility
+is either the word `accepted', or the SMTP error response, for example:
+.display asis
+Rejected:
+ 550 Relay not permitted
+.endd
+When running this test, the utility uses \"<>"\ as the envelope sender address
+for the \\MAIL\\ command, but you can change this by providing additional
+options. These are passed directly to the Exim command. For example, to specify
+that the test is to be run with the sender address \*himself@@there.example*\
+you can use:
+.display asis
+exim_checkaccess 10.9.8.7 A.User@a.domain.example \
+ -f himself@there.example
+.endd
+Note that these additional Exim command line items must be given after the two
+mandatory arguments.
+
+Because the \exim@_checkaccess\ uses \-bh-\, it does not perform callouts while
+running its checks. You can run checks that include callouts by using \-bhc-\,
+but this is not yet available in a `packaged' form.
+
+
+.section Making DBM files (exim@_dbmbuild)
+.rset SECTdbmbuild "~~chapter.~~section"
+.index DBM||building dbm files
+.index building DBM files
+.index \*exim@_dbmbuild*\
+.index lower casing
+.index binary zero||in lookup key
+The \*exim@_dbmbuild*\ program reads an input file containing keys and data in
+the format used by the \%lsearch%\ lookup (see section ~~SECTsinglekeylookups).
+It writes a DBM file using the lower-cased alias names as keys and the
+remainder of the information as data. The lower-casing can be prevented by
+calling the program with the \-nolc-\ option.
+
+A terminating zero is included as part of the key string. This is expected by
+the \%dbm%\ lookup type. However, if the option \-nozero-\ is given,
+\*exim@_dbmbuild*\ creates files without terminating zeroes in either the key
+strings or the data strings. The \%dbmnz%\ lookup type can be used with such
+files.
+
+The program requires two arguments: the name of the input file (which can be a
+single hyphen to indicate the standard input), and the name of the output file.
+It creates the output under a temporary name, and then renames it if all went
+well.
+.index \\USE@_DB\\
+If the native DB interface is in use (\\USE@_DB\\ is set in a compile-time
+configuration file -- this is common in free versions of Unix) the two file
+names must be different, because in this mode the Berkeley DB functions create
+a single output file using exactly the name given. For example,
+.display asis
+exim_dbmbuild /etc/aliases /etc/aliases.db
+.endd
+reads the system alias file and creates a DBM version of it in
+\(/etc/aliases.db)\.
+
+In systems that use the \*ndbm*\ routines (mostly proprietary versions of Unix),
+two files are used, with the suffixes \(.dir)\ and \(.pag)\. In this
+environment, the suffixes are added to the second argument of
+\*exim@_dbmbuild*\, so it can be the same as the first. This is also the case
+when the Berkeley functions are used in compatibility mode (though this is not
+recommended), because in that case it adds a \(.db)\ suffix to the file name.
+
+If a duplicate key is encountered, the program outputs a warning, and when it
+finishes, its return code is 1 rather than zero, unless the \-noduperr-\ option
+is used. By default, only the first of a set of duplicates is used -- this
+makes it compatible with \%lsearch%\ lookups. There is an option \-lastdup-\
+which causes it to use the data for the last duplicate instead. There is also
+an option \-nowarn-\, which stops it listing duplicate keys to \stderr\. For
+other errors, where it doesn't actually make a new file, the return code is 2.
+
+
+
+.section Finding individual retry times (exinext)
+.rset SECTfinindret "~~chapter.~~section"
+.index retry||times
+.index \*exinext*\
+A utility called \*exinext*\ (mostly a Perl script) provides the ability to fish
+specific information out of the retry database. Given a mail domain (or a
+complete address), it looks up the hosts for that domain, and outputs any retry
+information for the hosts or for the domain. At present, the retry information
+is obtained by running \*exim@_dumpdb*\ (see below) and post-processing the
+output. For example:
+.display asis
+$ exinext piglet@milne.fict.example
+kanga.milne.fict.example:192.168.8.1 error 146: Connection refused
+ first failed: 21-Feb-1996 14:57:34
+ last tried: 21-Feb-1996 14:57:34
+ next try at: 21-Feb-1996 15:02:34
+roo.milne.fict.example:192.168.8.3 error 146: Connection refused
+ first failed: 20-Jan-1996 13:12:08
+ last tried: 21-Feb-1996 11:42:03
+ next try at: 21-Feb-1996 19:42:03
+ past final cutoff time
+.endd
+You can also give \*exinext*\ a local part, without a domain, and it
+will give any retry information for that local part in your default domain.
+A message id can be used to obtain retry information pertaining to a specific
+message. This exists only when an attempt to deliver a message to a remote host
+suffers a message-specific error (see section ~~SECToutSMTPerr). \*exinext*\ is
+not particularly efficient, but then it isn't expected to be run very often.
+
+.em
+The \*exinext*\ utility calls Exim to find out information such as the location
+of the spool directory. The utility has \-C-\ and \-D-\ options, which are
+passed on to the \*exim*\ commands. The first specifies an alternate Exim
+configuration file, and the second sets macros for use within the configuration
+file. These features are mainly to help in testing, but might also be useful in
+environments where more than one configuration file is in use.
+.nem
+
+
+
+.section Hints database maintenance (exim@_dumpdb, exim@_fixdb, exim@_tidydb)
+.rset SECThindatmai "~~chapter.~~section"
+.index hints database||maintenance
+.index maintaining Exim's hints database
+Three utility programs are provided for maintaining the DBM files that Exim
+uses to contain its delivery hint information. Each program requires two
+arguments. The first specifies the name of Exim's spool directory, and the
+second is the name of the database it is to operate on. These are as
+follows:
+.numberpars $.
+\*retry*\: the database of retry information
+.nextp
+\*wait-*\<<transport name>>: databases of information about messages waiting
+for remote hosts
+.nextp
+.em
+\*callout*\: the callout cache
+.nem
+.nextp
+\*misc*\: other hints data
+.endp
+.em
+The \*misc*\ database is used for
+.numberpars alpha
+Serializing \\ETRN\\ runs (when \smtp@_etrn@_serialize\ is set)
+.nextp
+Serializing delivery to a specific host (when \serialize@_hosts\ is set in an
+\%smtp%\ transport)
+.endp
+.nem
+.index \*exim@_dumpdb*\
+The entire contents of a database are written to the standard output by the
+\*exim@_dumpdb*\ program, which has no options or arguments other than the
+spool and database names. For example, to dump the retry database:
+.display asis
+exim_dumpdb /var/spool/exim retry
+.endd
+Two lines of output are produced for each entry:
+.display
+ T:mail.ref.example:192.168.242.242 146 77 Connection refused
+31-Oct-1995 12:00:12 02-Nov-1995 12:21:39 02-Nov-1995 20:21:39 *
+.endd
+The first item on the first line is the key of the record. It starts with one
+of the letters R, or T, depending on whether it refers to a routing or
+transport retry. For a local delivery, the next part is the local address; for
+a remote delivery it is the name of the remote host, followed by its failing IP
+address (unless \no@_retry@_include@_ip@_address\ is set on the \%smtp%\
+transport).
+.em
+If the remote port is not the standard one (port 25), it is added to the IP
+address.
+.nem
+Then there follows an error code, an additional error code, and a
+textual description of the error.
+
+The three times on the second line are the time of first failure, the time of
+the last delivery attempt, and the computed time for the next attempt. The line
+ends with an asterisk if the cutoff time for the last retry rule has been
+exceeded.
+
+Each output line from \*exim@_dumpdb*\ for the \*wait-*\$it{xxx} databases
+consists of a host name followed by a list of ids for messages that are or were
+waiting to be delivered to that host. If there are a very large number for any
+one host, continuation records, with a sequence number added to the host name,
+may be seen. The data in these records is often out of date, because a message
+may be routed to several alternative hosts, and Exim makes no effort to keep
+cross-references.
+
+.index \*exim@_tidydb*\
+The \*exim@_tidydb*\ utility program is used to tidy up the contents of the
+hints databases. If run with no options, it removes all records from a database
+that are more than 30 days old. The cutoff date can be altered by means of the
+\-t-\ option, which must be followed by a time. For example, to remove all
+records older than a week from the retry database:
+.display asis
+exim_tidydb -t 7d /var/spool/exim retry
+.endd
+Both the \*wait-*\$it{xxx} and \*retry*\ databases contain items that involve
+message ids. In the former these appear as data in records keyed by host --
+they were messages that were waiting for that host -- and in the latter they
+are the keys for retry information for messages that have suffered certain
+types of error. When \*exim@_tidydb*\ is run, a check is made to ensure that
+message ids in database records are those of messages that are still on the
+queue. Message ids for messages that no longer exist are removed from
+\*wait-*\$it{xxx} records, and if this leaves any records empty, they are
+deleted. For the \*retry*\ database, records whose keys are non-existent message
+ids are removed. The \*exim@_tidydb*\ utility outputs comments on the standard
+output whenever it removes information from the database.
+
+Removing records from a DBM file does not normally make the file smaller, but
+all the common DBM libraries are able to re-use the space that is released.
+It is therefore suggested that \*exim@_tidydb*\ be run periodically on all the
+hints databases, but at a quiet time of day, because it requires a database to
+be locked (and therefore inaccessible to Exim) while it does its work.
+
+.index \*exim@_fixdb*\
+The \*exim@_fixdb*\ program is a utility for interactively modifying databases.
+Its main use is for testing Exim, but it might also be occasionally useful for
+getting round problems in a live system. It has no options, and its interface
+is somewhat crude. On entry, it prompts for input with a right angle-bracket. A
+key of a database record can then be entered, and the data for that record is
+displayed.
+
+If `d' is typed at the next prompt, the entire record is deleted. For all
+except the \*retry*\ database, that is the only operation that can be carried
+out. For the \*retry*\ database, each field is output preceded by a number, and
+data for individual fields can be changed by typing the field number followed
+by new data, for example:
+.display asis
+> 4 951102:1000
+.endd
+resets the time of the next delivery attempt. Time values are given as a
+sequence of digit pairs for year, month, day, hour, and minute. Colons can be
+used as optional separators.
+
+
+
+.section Mailbox maintenance (exim@_lock)
+.rset SECTmailboxmaint "~~chapter.~~section"
+.index mailbox||maintenance
+.index \*exim@_lock*\
+.index locking mailboxes
+The \*exim@_lock*\ utility locks a mailbox file using the same algorithm as
+Exim. For a discussion of locking issues, see section ~~SECTopappend.
+\*Exim@_lock*\ can be used to prevent any modification of a mailbox by Exim or
+a user agent while investigating a problem. The utility requires the name of
+the file as its first argument. If the locking is successful, the second
+argument is run as a command (using C's \*system()*\ function); if there is no
+second argument, the value of the SHELL environment variable is used; if this
+is unset or empty, \(/bin/sh)\ is run. When the command finishes, the mailbox
+is unlocked and the utility ends. The following options are available:
+
+.startoptions
+
+.option fcntl
+Use \*fcntl()*\ locking on the open mailbox.
+
+.option flock
+Use \*flock()*\ locking on the open mailbox, provided the operating system
+supports it.
+
+.option interval
+This must be followed by a number, which is a number of seconds; it sets the
+interval to sleep between retries (default 3).
+
+.option lockfile
+Create a lock file before opening the mailbox.
+
+.option mbx
+Lock the mailbox using MBX rules.
+
+.option q
+Suppress verification output.
+
+.option retries
+This must be followed by a number; it sets the number of times to try to get
+the lock (default 10).
+
+.option restore@_time
+This option causes \exim@_lock\ to restore the modified and read times to the
+locked file before exiting. This allows you to access a locked mailbox (for
+example, to take a backup copy) without disturbing the times that the user
+subsequently sees.
+
+.option timeout
+This must be followed by a number, which is a number of seconds; it sets a
+timeout to be used with a blocking \*fcntl()*\ lock. If it is not set (the
+default), a non-blocking call is used.
+
+.option v
+Generate verbose output.
+
+.endoptions
+
+If none of \-fcntl-\,
+\-flock-\,
+\-lockfile-\ or \-mbx-\ are given, the default is to create a lock file and
+also to use \*fcntl()*\ locking on the mailbox, which is the same as Exim's
+default. The use of
+\-flock-\
+or \-fcntl-\ requires that the file be writeable; the use of
+\-lockfile-\ requires that the directory containing the file be writeable.
+Locking by lock file does not last for ever; Exim assumes that a lock file is
+expired if it is more than 30 minutes old.
+
+The \-mbx-\ option can be used with either or both of \-fcntl-\ or \-flock-\.
+It assumes \-fcntl-\ by default.
+MBX locking causes a shared lock to be taken out on the open mailbox, and an
+exclusive lock on the file \(/tmp/.$it{n}.$it{m})\ where $it{n} and $it{m} are
+the device number and inode number of the mailbox file. When the locking is
+released, if an exclusive lock can be obtained for the mailbox, the file in
+\(/tmp)\ is deleted.
+
+The default output contains verification of the locking that takes place. The
+\-v-\ option causes some additional information to be given. The \-q-\ option
+suppresses all output except error messages.
+
+A command such as
+.display asis
+exim_lock /var/spool/mail/spqr
+.endd
+runs an interactive shell while the file is locked, whereas
+.display
+exim@_lock -q /var/spool/mail/spqr @<@<End
+<<some commands>>
+End
+.endd
+runs a specific non-interactive sequence of commands while the file is locked,
+suppressing all verification output. A single command can be run by a command
+such as
+.display asis
+exim_lock -q /var/spool/mail/spqr \
+ "cp /var/spool/mail/spqr /some/where"
+.endd
+Note that if a command is supplied, it must be entirely contained within the
+second argument -- hence the quotes.
+
+
+
+.
+.
+.
+.
+. ============================================================================
+.chapter The Exim monitor
+.set runningfoot "monitor"
+.rset CHAPeximon ~~chapter
+.index monitor
+.index Exim monitor
+.index X-windows
+.index \*eximon*\
+.index Local/eximon.conf
+.index \(exim@_monitor/EDITME)\
+The Exim monitor is an application which displays in an X window information
+about the state of Exim's queue and what Exim is doing. An admin user can
+perform certain operations on messages from this GUI interface; however all
+such facilities are also available from the command line, and indeed, the
+monitor itself makes use of the command line to perform any actions requested.
+
+
+.section Running the monitor
+The monitor is started by running the script called \*eximon*\. This is a shell
+script that sets up a number of environment variables, and then runs the
+binary called \(eximon.bin)\. The default appearance of the monitor window can
+be changed by editing the \(Local/eximon.conf)\ file created by editing
+\(exim@_monitor/EDITME)\. Comments in that file describe what the various
+parameters are for.
+
+The parameters that get built into the \*eximon*\ script can be overridden for a
+particular invocation by setting up environment variables of the same names,
+preceded by `$tt{EXIMON@_}'. For example, a shell command such as
+.display asis
+EXIMON_LOG_DEPTH=400 eximon
+.endd
+(in a Bourne-compatible shell) runs \*eximon*\ with an overriding setting of the
+\\LOG@_DEPTH\\ parameter. If \\EXIMON@_LOG@_FILE@_PATH\\ is set in the
+environment, it overrides the Exim log file configuration. This makes it
+possible to have \*eximon*\ tailing log data that is written to syslog, provided
+that MAIL.INFO syslog messages are routed to a file on the local host.
+
+X resources can be used to change the appearance of the window in the normal
+way. For example, a resource setting of the form
+.display asis
+Eximon*background: gray94
+.endd
+changes the colour of the background to light grey rather than white. The
+stripcharts are drawn with both the data lines and the reference lines in
+black. This means that the reference lines are not visible when on top of the
+data. However, their colour can be changed by setting a resource called
+`highlight' (an odd name, but that's what the Athena stripchart widget uses).
+For example, if your X server is running Unix, you could set up lighter
+reference lines in the stripcharts by obeying
+.display asis
+xrdb -merge <<End
+Eximon*highlight: gray
+End
+.endd
+
+.index admin user
+In order to see the contents of messages on the queue, and to operate on them,
+\*eximon*\ must either be run as root or by an admin user.
+
+The monitor's window is divided into three parts. The first contains one or
+more stripcharts and two action buttons, the second contains a `tail' of the
+main log file, and the third is a display of the queue of messages awaiting
+delivery, with two more action buttons. The following sections describe these
+different parts of the display.
+
+
+
+.section The stripcharts
+.index stripchart
+The first stripchart is always a count of messages on the queue. Its name can
+be configured by setting \\QUEUE@_STRIPCHART@_NAME\\ in the
+\(Local/eximon.conf)\ file. The remaining stripcharts are defined in the
+configuration script by regular expression matches on log file entries, making
+it possible to display, for example, counts of messages delivered to certain
+hosts or using certain transports. The supplied defaults display counts of
+received and delivered messages, and of local and SMTP deliveries. The default
+period between stripchart updates is one minute; this can be adjusted by a
+parameter in the \(Local/eximon.conf)\ file.
+
+The stripchart displays rescale themselves automatically as the value they are
+displaying changes. There are always 10 horizontal lines in each chart; the
+title string indicates the value of each division when it is greater than one.
+For example, `x2' means that each division represents a value of 2.
+
+It is also possible to have a stripchart which shows the percentage fullness of
+a particular disk partition, which is useful when local deliveries are confined
+to a single partition.
+.index \statvfs\ function
+This relies on the availability of the \*statvfs()*\ function or equivalent in
+the operating system. Most, but not all versions of Unix that support Exim have
+this. For this particular stripchart, the top of the chart always represents
+100%, and the scale is given as `x10%'. This chart is configured by setting
+\\SIZE@_STRIPCHART\\ and (optionally) \\SIZE@_STRIPCHART@_NAME\\ in the
+\(Local/eximon.conf)\ file.
+
+
+
+.section Main action buttons
+.index size||of monitor window
+.index monitor window size
+.index window size
+Below the stripcharts there is an action button for quitting the monitor. Next
+to this is another button marked `Size'. They are placed here so that shrinking
+the window to its default minimum size leaves just the queue count stripchart
+and these two buttons visible. Pressing the `Size' button causes the window to
+expand to its maximum size, unless it is already at the maximum, in which case
+it is reduced to its minimum.
+
+When expanding to the maximum, if the window cannot be fully seen where it
+currently is, it is moved back to where it was the last time it was at full
+size. When it is expanding from its minimum size, the old position is
+remembered, and next time it is reduced to the minimum it is moved back there.
+
+The idea is that you can keep a reduced window just showing one or two
+stripcharts at a convenient place on your screen, easily expand it to show
+the full window when required, and just as easily put it back to what it was.
+The idea is copied from what the \*twm*\ window manager does for its
+\*f.fullzoom*\ action. The minimum size of the window can be changed by setting
+the \\MIN@_HEIGHT\\ and \\MIN@_WIDTH\\ values in \(Local/eximon.conf)\.
+
+Normally, the monitor starts up with the window at its full size, but it can be
+built so that it starts up with the window at its smallest size, by setting
+\\START@_SMALL\\=yes in \(Local/eximon.conf)\.
+
+
+.section The log display
+.index log||tail of, in monitor
+The second section of the window is an area in which a display of the tail of
+the main log is maintained.
+To save space on the screen, the timestamp on each log line is shortened by
+removing the date and, if \log@_timezone\ is set, the timezone.
+The log tail is not available when the only destination for logging data is
+syslog, unless the syslog lines are routed to a local file whose name is passed
+to \*eximon*\ via the \\EXIMON@_LOG@_FILE@_PATH\\ environment variable.
+
+The log sub-window has a scroll bar at its lefthand side which can be used to
+move back to look at earlier text, and the up and down arrow keys also have a
+scrolling effect. The amount of log that is kept depends on the setting of
+\\LOG@_BUFFER\\ in \(Local/eximon.conf)\, which specifies the amount of memory
+to use. When this is full, the earlier 50% of data is discarded -- this is much
+more efficient than throwing it away line by line. The sub-window also has a
+horizontal scroll bar for accessing the ends of long log lines. This is the
+only means of horizontal scrolling; the right and left arrow keys are not
+available. Text can be cut from this part of the window using the mouse in the
+normal way. The size of this subwindow is controlled by parameters in the
+configuration file \(Local/eximon.conf)\.
+
+Searches of the text in the log window can be carried out by means of the ^R
+and ^S keystrokes, which default to a reverse and a forward search,
+respectively. The search covers only the text that is displayed in the window.
+It cannot go further back up the log.
+
+The point from which the search starts is indicated by a caret marker. This is
+normally at the end of the text in the window, but can be positioned explicitly
+by pointing and clicking with the left mouse button, and is moved automatically
+by a successful search. If new text arrives in the window when it is scrolled
+back, the caret remains where it is, but if the window is not scrolled back,
+the caret is moved to the end of the new text.
+
+Pressing ^R or ^S pops up a window into which the search text can be typed.
+There are buttons for selecting forward or reverse searching, for carrying out
+the search, and for cancelling. If the `Search' button is pressed, the search
+happens and the window remains so that further searches can be done. If the
+`Return' key is pressed, a single search is done and the window is closed. If
+^C is typed the search is cancelled.
+
+The searching facility is implemented using the facilities of the Athena text
+widget. By default this pops up a window containing both `search' and `replace'
+options. In order to suppress the unwanted `replace' portion for eximon, a
+modified version of the \TextPop\ widget is distributed with Exim. However, the
+linkers in BSDI and HP-UX seem unable to handle an externally provided version
+of \TextPop\ when the remaining parts of the text widget come from the standard
+libraries. The compile-time option \\EXIMON@_TEXTPOP\\ can be unset to cut out
+the modified \TextPop\, making it possible to build Eximon on these systems, at
+the expense of having unwanted items in the search popup window.
+
+
+.section The queue display
+.index queue||display in monitor
+The bottom section of the monitor window contains a list of all messages that
+are on the queue, which includes those currently being received or delivered,
+as well as those awaiting delivery. The size of this subwindow is controlled by
+parameters in the configuration file \(Local/eximon.conf)\, and the frequency
+at which it is updated is controlled by another parameter in the same file --
+the default is 5 minutes, since queue scans can be quite expensive. However,
+there is an `Update' action button just above the display which can be used to
+force an update of the queue display at any time.
+
+When a host is down for some time, a lot of pending mail can build up for it,
+and this can make it hard to deal with other messages on the queue. To help
+with this situation there is a button next to `Update' called `Hide'. If
+pressed, a dialogue box called `Hide addresses ending with' is put up. If you
+type anything in here and press `Return', the text is added to a chain of such
+texts, and if every undelivered address in a message matches at least one
+of the texts, the message is not displayed.
+
+If there is an address that does not match any of the texts, all the addresses
+are displayed as normal. The matching happens on the ends of addresses so, for
+example, \*cam.ac.uk*\ specifies all addresses in Cambridge, while
+\*xxx@@foo.com.example*\ specifies just one specific address. When any hiding
+has been set up, a button called `Unhide' is displayed. If pressed, it cancels
+all hiding. Also, to ensure that hidden messages do not get forgotten, a hide
+request is automatically cancelled after one hour.
+
+While the dialogue box is displayed, you can't press any buttons or do anything
+else to the monitor window. For this reason, if you want to cut text from the
+queue display to use in the dialogue box, you have to do the cutting before
+pressing the `Hide' button.
+
+The queue display contains, for each unhidden queued message, the length of
+time it has been on the queue, the size of the message, the message id, the
+message sender, and the first undelivered recipient, all on one line. If it is
+a bounce message, the sender is shown as `<>'. If there is more than one
+recipient to which the message has not yet been delivered, subsequent ones are
+listed on additional lines, up to a maximum configured number, following which
+an ellipsis is displayed. Recipients that have already received the message are
+not shown.
+.index frozen messages||display
+If a message is frozen, an asterisk is displayed at the left-hand side.
+
+The queue display has a vertical scroll bar, and can also be scrolled by means
+of the arrow keys. Text can be cut from it using the mouse in the normal way.
+The text searching facilities, as described above for the log window, are also
+available, but the caret is always moved to the end of the text when the queue
+display is updated.
+
+
+.section The queue menu
+.index queue||menu in monitor
+If the \shift\ key is held down and the left button is clicked when the mouse
+pointer is over the text for any message, an action menu pops up, and the first
+line of the queue display for the message is highlighted. This does not affect
+any selected text.
+
+If you want to use some other event for popping up the menu, you can set the
+\\MENU@_EVENT\\ parameter in \(Local/eximon.conf)\ to change the default, or
+set \\EXIMON@_MENU@_EVENT\\ in the environment before starting the monitor. The
+value set in this parameter is a standard X event description. For example, to
+run eximon using \ctrl\ rather than \shift\ you could use
+.display asis
+EXIMON_MENU_EVENT='Ctrl<Btn1Down>' eximon
+.endd
+The title of the menu is the message id, and it contains entries which act as
+follows:
+.numberpars $.
+\*message log*\: The contents of the message log for the message are displayed in
+a new text window.
+.nextp
+\*headers*\: Information from the spool file that contains the envelope
+information and headers is displayed in a new text window. See chapter
+~~CHAPspool for a description of the format of spool files.
+.nextp
+\*body*\: The contents of the spool file containing the body of the message are
+displayed in a new text window. There is a default limit of 20,000 bytes to the
+amount of data displayed. This can be changed by setting the \\BODY@_MAX\\
+option at compile time, or the \\EXIMON@_BODY@_MAX\\ option at run time.
+.nextp
+\*deliver message*\: A call to Exim is made using the \-M-\ option to request
+delivery of the message. This causes an automatic thaw if the message is
+frozen. The \-v-\ option is also set, and the output from Exim is displayed in
+a new text window. The delivery is run in a separate process, to avoid holding
+up the monitor while the delivery proceeds.
+.nextp
+\*freeze message*\: A call to Exim is made using the \-Mf-\ option to request
+that the message be frozen.
+.nextp
+.index thawing messages
+.index unfreezing messages
+.index frozen messages||thawing
+\*thaw message*\: A call to Exim is made using the \-Mt-\ option to request that
+the message be thawed.
+.nextp
+.index delivery||forcing failure
+\*give up on msg*\: A call to Exim is made using the \-Mg-\ option to request
+that Exim gives up trying to deliver the message. A bounce message is generated
+for any remaining undelivered addresses.
+.nextp
+\*remove message*\: A call to Exim is made using the \-Mrm-\ option to request
+that the message be deleted from the system without generating a bounce
+message.
+.nextp
+\*add recipient*\: A dialog box is displayed into which a recipient address can
+be typed. If the address is not qualified and the \\QUALIFY@_DOMAIN\\ parameter
+is set in \(Local/eximon.conf)\, the address is qualified with that domain.
+Otherwise it must be entered as a fully qualified address. Pressing \\RETURN\\
+causes a call to Exim to be made using the \-Mar-\ option to request that an
+additional recipient be added to the message, unless the entry box is empty, in
+which case no action is taken.
+.nextp
+\*mark delivered*\: A dialog box is displayed into which a recipient address can
+be typed. If the address is not qualified and the \\QUALIFY@_DOMAIN\\ parameter
+is set in \(Local/eximon.conf)\, the address is qualified with that domain.
+Otherwise it must be entered as a fully qualified address. Pressing \\RETURN\\
+causes a call to Exim to be made using the \-Mmd-\ option to mark the given
+recipient address as already delivered, unless the entry box is empty, in which
+case no action is taken.
+.nextp
+\*mark all delivered*\: A call to Exim is made using the \-Mmad-\ option to mark
+all recipient addresses as already delivered.
+.nextp
+\*edit sender*\: A dialog box is displayed initialized with the current sender's
+address. Pressing \\RETURN\\ causes a call to Exim to be made using the \-Mes-\
+option to replace the sender address, unless the entry box is empty, in which
+case no action is taken. If you want to set an empty sender (as in bounce
+messages), you must specify it as `<>'. Otherwise, if the address is not
+qualified and the \\QUALIFY@_DOMAIN\\ parameter is set in
+\(Local/eximon.conf)\, the address is qualified with that domain.
+.endp
+When a delivery is forced, a window showing the \-v-\ output is displayed. In
+other cases when a call to Exim is made, if there is any output from Exim (in
+particular, if the command fails) a window containing the command and the
+output is displayed. Otherwise, the results of the action are normally apparent
+from the log and queue displays. However, if you set \\ACTION@_OUTPUT\\=yes in
+\(Local/eximon.conf)\, a window showing the Exim command is always opened, even
+if no output is generated.
+
+The queue display is automatically updated for actions such as freezing and
+thawing, unless \\ACTION@_QUEUE@_UPDATE\\=no has been set in
+\(Local/eximon.conf)\. In this case the `Update' button has to be used to force
+an update of the display after one of these actions.
+
+In any text window that is displayed as result of a menu action, the normal
+cut-and-paste facility is available, and searching can be carried out using ^R
+and ^S, as described above for the log tail window.
+
+
+
+
+
+
+.
+.
+.
+.
+. ============================================================================
+.chapter Security considerations
+.set runningfoot "security"
+.rset CHAPsecurity ~~chapter
+.index security
+This chapter discusses a number of issues concerned with security, some of
+which are also covered in other parts of this manual.
+
+For reasons that this author does not understand, some people have promoted
+Exim as a `particularly secure' mailer. Perhaps it is because of the existence
+of this chapter in the documentation. However, the intent of the chapter is
+simply to describe the way Exim works in relation to certain security concerns,
+not to make any specific claims about the effectiveness of its security as
+compared with other MTAs.
+
+What follows is a description of the way Exim is supposed to be. Best efforts
+have been made to try to ensure that the code agrees with the theory, but an
+absence of bugs can never be guaranteed. Any that are reported will get fixed
+as soon as possible.
+
+.section Building a more `hardened' Exim
+.index security||build-time features
+There are a number of build-time options that can be set in \(Local/Makefile)\
+to create Exim binaries that are `harder' to attack, in particular by a rogue
+Exim administrator who does not have the root password, or by someone who has
+penetrated the Exim (but not the root) account. These options are as follows:
+.numberpars $.
+\\ALT@_CONFIG@_PREFIX\\ can be set to a string that is required to match the
+start of any file names used with the \-C-\ option. When it is set, these file
+names are also not allowed to contain the sequence `/../'. (However, if the
+value of the \-C-\ option is identical to the value of \\CONFIGURE@_FILE\\ in
+\(Local/Makefile)\, Exim ignores \-C-\ and proceeds as usual.) There is no
+default setting for \ALT@_CONFIG@_PREFIX\.
+
+If the permitted configuration files are confined to a directory to
+which only root has access, this guards against someone who has broken
+into the Exim account from running a privileged Exim with an arbitrary
+configuration file, and using it to break into other accounts.
+.nextp
+If \\ALT@_CONFIG@_ROOT@_ONLY\\ is defined, root privilege is retained for \-C-\
+and \-D-\ only if the caller of Exim is root. Without it, the Exim user may
+also use \-C-\ and \-D-\ and retain privilege. Setting this option locks out
+the possibility of testing a configuration using \-C-\ right through message
+reception and delivery, even if the caller is root. The reception works, but by
+that time, Exim is running as the Exim user, so when it re-execs to regain
+privilege for the delivery, the use of \-C-\ causes privilege to be lost.
+However, root can test reception and delivery using two separate commands.
+\\ALT@_CONFIG@_ROOT@_ONLY\\ is not set by default.
+.nextp
+If \\DISABLE@_D@_OPTION\\ is defined, the use of the \-D-\ command line option
+is disabled.
+.nextp
+\\FIXED@_NEVER@_USERS\\ can be set to a colon-separated list of users that are
+never to be used for any deliveries. This is like the \never@_users\ runtime
+option, but it cannot be overridden; the runtime option adds additional users
+to the list. The default setting is `root'; this prevents a non-root user who
+is permitted to modify the runtime file from using Exim as a way to get root.
+.endp
+
+
+.section Root privilege
+.index setuid
+.index root privilege
+The Exim binary is normally setuid to root, which means that it gains root
+privilege (runs as root) when it starts execution. In some special cases (for
+example, when the daemon is not in use and there are no local deliveries), it
+may be possible to run Exim setuid to some user other than root. This is
+discussed in the next section. However, in most installations, root privilege
+is required for two things:
+.numberpars $.
+To set up a socket connected to the standard SMTP port (25) when initialising
+the listening daemon. If Exim is run from \*inetd*\, this privileged action is
+not required.
+.nextp
+To be able to change uid and gid in order to read users' \(.forward)\ files and
+perform local deliveries as the receiving user or as specified in the
+configuration.
+.endp
+It is not necessary to be root to do any of the other things Exim does, such as
+receiving messages and delivering them externally over SMTP, and it is
+obviously more secure if Exim does not run as root except when necessary.
+For this reason, a user and group for Exim to use must be defined in
+\(Local/Makefile)\. These are known as `the Exim user' and `the Exim group'.
+Their values can be changed by the run time configuration, though this is not
+recommended. Often a user called \*exim*\ is used, but some sites use \*mail*\
+or another user name altogether.
+
+Exim uses \*setuid()*\ whenever it gives up root privilege. This is a permanent
+abdication; the process cannot regain root afterwards. Prior to release 4.00,
+\*seteuid()*\ was used in some circumstances, but this is no longer the case.
+
+After a new Exim process has interpreted its command line options, it changes
+uid and gid in the following cases:
+.numberpars $.
+.index \-C-\ option
+.index \-D-\ option
+If the \-C-\ option is used to specify an alternate configuration file, or if
+the \-D-\ option is used to define macro values for the configuration, and the
+calling process is not running as root or the Exim user, the uid and gid are
+changed to those of the calling process.
+However, if \\ALT@_CONFIG@_ROOT@_ONLY\\ is defined in \(Local/Makefile)\, only
+root callers may use \-C-\ and \-D-\ without losing privilege, and if
+\\DISABLE@_D@_OPTION\\ is set, the \-D-\ option may not be used at all.
+.nextp
+.index \-be-\ option
+.index \-bf-\ option
+.index \-bF-\ option
+If the expansion test option (\-be-\) or one of the filter testing options
+(\-bf-\ or \-bF-\) are used, the uid and gid are changed to those of the
+calling process.
+.nextp
+If the process is not a daemon process or a queue runner process or a delivery
+process or a process for testing address routing (started with \-bt-\), the uid
+and gid are changed to the Exim user and group. This means that Exim always
+runs under its own uid and gid when receiving messages. This also applies when
+testing address verification
+.index \-bv-\ option
+.index \-bh-\ option
+(the \-bv-\ option) and testing incoming message policy controls (the \-bh-\
+option).
+.nextp
+For a daemon, queue runner, delivery, or address testing process, the uid
+remains as root at this stage, but the gid is changed to the Exim group.
+.endp
+The processes that initially retain root privilege behave as follows:
+.numberpars $.
+A daemon process changes the gid to the Exim group and the uid to the Exim user
+after setting up one or more listening sockets. The \*initgroups()*\ function
+is called, so that if the Exim user is in any additional groups, they will be
+used during message reception.
+.nextp
+A queue runner process retains root privilege throughout its execution. Its job
+is to fork a controlled sequence of delivery processes.
+.nextp
+A delivery process retains root privilege throughout most of its execution,
+but any actual deliveries (that is, the transports themselves) are run in
+subprocesses which always change to a non-root uid and gid. For local
+deliveries this is typically the uid and gid of the owner of the mailbox; for
+remote deliveries, the Exim uid and gid are used. Once all the delivery
+subprocesses have been run, a delivery process changes to the Exim uid and gid
+while doing post-delivery tidying up such as updating the retry database and
+generating bounce and warning messages.
+
+While the recipient addresses in a message are being routed, the delivery
+process runs as root. However, if a user's filter file has to be processed,
+this is done in a subprocess that runs under the individual user's uid and
+gid. A system filter is run as root unless \system@_filter@_user\ is set.
+.nextp
+A process that is testing addresses (the \-bt-\ option) runs as root so that
+the routing is done in the same environment as a message delivery.
+.endp
+
+
+.section Running Exim without privilege
+.index privilege, running without
+.index unprivileged running
+.index root privilege||running without
+Some installations like to run Exim in an unprivileged state for more of its
+operation, for added security. Support for this mode of operation is provided
+by the global option \deliver@_drop@_privilege\. When this is set, the uid and
+gid are changed to the Exim user and group at the start of a delivery process
+(and also queue runner and address testing processes). This means that address
+routing is no longer run as root, and the deliveries themselves cannot change
+to any other uid.
+
+Leaving the binary setuid to root, but setting \deliver@_drop@_privilege\ means
+that the daemon can still be started in the usual way, and it can respond
+correctly to SIGHUP because the re-invocation regains root privilege.
+
+An alternative approach is to make Exim setuid to the Exim user and also setgid
+to the Exim group.
+If you do this, the daemon must be started from a root process. (Calling
+Exim from a root process makes it behave in the way it does when it is setuid
+root.) However, the daemon cannot restart itself after a SIGHUP signal because
+it cannot regain privilege.
+
+It is still useful to set \deliver@_drop@_privilege\ in this case, because it
+stops Exim from trying to re-invoke itself to do a delivery after a message has
+been received. Such a re-invocation is a waste of resources because it has no
+effect.
+
+If restarting the daemon is not an issue (for example, if \*inetd*\ is being
+used instead of a daemon), having the binary setuid to the Exim user seems a
+clean approach, but there is one complication:
+
+In this style of operation, Exim is running with the real uid and gid set to
+those of the calling process, and the effective uid/gid set to Exim's values.
+Ideally, any association with the calling process' uid/gid should be dropped,
+that is, the real uid/gid should be reset to the effective values so as to
+discard any privileges that the caller may have. While some operating systems
+have a function that permits this action for a non-root effective uid, quite a
+number of them do not. Because of this lack of standardization, Exim does not
+address this problem at this time.
+
+For this reason, the recommended approach for `mostly unprivileged' running is
+to keep the Exim binary setuid to root, and to set \deliver@_drop@_privilege\.
+This also has the advantage of allowing a daemon to be used in the most
+straightforward way.
+
+If you configure Exim not to run delivery processes as root, there are a
+number of restrictions on what you can do:
+.numberpars $.
+You can deliver only as the Exim user/group. You should explicitly use the
+\user\ and \group\ options to override routers or local transports that
+normally deliver as the recipient. This makes sure that configurations that
+work in this mode function the same way in normal mode. Any implicit or
+explicit specification of another user causes an error.
+.nextp
+Use of \(.forward)\ files is severely restricted, such that it is usually
+not worthwhile to include them in the configuration.
+.nextp
+Users who wish to use \(.forward)\ would have to make their home directory and
+the file itself accessible to the Exim user. Pipe and append-to-file entries,
+and their equivalents in Exim filters, cannot be used. While they could be
+enabled in the Exim user's name, that would be insecure and not very useful.
+.nextp
+Unless the local user mailboxes are all owned by the Exim user (possible in
+some POP3 or IMAP-only environments):
+.numberpars $*$
+They must be owned by the Exim group and be writable by that group. This
+implies you must set \mode\ in the appendfile configuration, as well as the
+mode of the mailbox files themselves.
+.nextp
+You must set \no@_check@_owner\, since most or all of the files will not be
+owned by the Exim user.
+.nextp
+You must set \file@_must@_exist\, because Exim cannot set the owner correctly
+on a newly created mailbox when unprivileged. This also implies that new
+mailboxes need to be created manually.
+.endp
+.endp
+These restrictions severely restrict what can be done in local deliveries.
+However, there are no restrictions on remote deliveries. If you are running a
+gateway host that does no local deliveries, setting \deliver@_drop@_privilege\
+gives more security at essentially no cost.
+
+
+.section Delivering to local files
+Full details of the checks applied by \%appendfile%\ before it writes to a file
+are given in chapter ~~CHAPappendfile.
+
+
+.section IPv4 source routing
+.index source routing||in IP packets
+.index IP source routing
+Many operating systems suppress IP source-routed packets in the kernel, but
+some cannot be made to do this, so Exim does its own check. It logs incoming
+IPv4 source-routed TCP calls, and then drops them. Things are all different in
+IPv6. No special checking is currently done.
+
+
+.section The VRFY, EXPN, and ETRN commands in SMTP
+Support for these SMTP commands is disabled by default. If required, they can
+be enabled by defining suitable ACLs.
+
+
+
+.section Privileged users
+.index trusted user
+.index admin user
+.index privileged user
+.index user||trusted
+.index user||admin
+Exim recognises two sets of users with special privileges. Trusted users are
+able to submit new messages to Exim locally, but supply their own sender
+addresses and information about a sending host. For other users submitting
+local messages, Exim sets up the sender address from the uid, and doesn't
+permit a remote host to be specified.
+
+.index \-f-\ option
+However, an untrusted user is permitted to use the \-f-\ command line option in
+the special form \-f @<@>-\ to indicate that a delivery failure for the message
+should not cause an error report. This affects the message's envelope, but it
+does not affect the ::Sender:: header. Untrusted users may also be permitted to
+use specific forms of address with the \-f-\ option by setting the
+\untrusted@_set@_sender\ option.
+
+Trusted users are used to run processes that receive mail messages from some
+other mail domain and pass them on to Exim for delivery either locally, or over
+the Internet. Exim trusts a caller that is running as root, as the Exim user,
+as any user listed in the \trusted@_users\ configuration option, or under any
+group listed in the \trusted@_groups\ option.
+
+Admin users are permitted to do things to the messages on Exim's queue. They
+can freeze or thaw messages, cause them to be returned to their senders, remove
+them entirely, or modify them in various ways. In addition, admin users can run
+the Exim monitor and see all the information it is capable of providing, which
+includes the contents of files on the spool.
+
+.index \-M-\ option
+.index \-q-\ option
+By default, the use of the \-M-\ and \-q-\ options to cause Exim to attempt
+delivery of messages on its queue is restricted to admin users. This
+restriction can be relaxed by setting the \no@_prod@_requires@_admin\ option.
+Similarly, the use of \-bp-\ (and its variants) to list the contents of the
+queue is also restricted to admin users. This restriction can be relaxed by
+setting \no@_queue@_list@_requires@_admin\.
+
+Exim recognises an admin user if the calling process is running as root or as
+the Exim user or if any of the groups associated with the calling process is
+the Exim group. It is not necessary actually to be running under the Exim
+group. However, if admin users who are not root or the Exim user are to access
+the contents of files on the spool via the Exim monitor (which runs
+unprivileged), Exim must be built to allow group read access to its spool
+files.
+
+
+.section Spool files
+.index spool directory||files
+Exim's spool directory and everything it contains is owned by the Exim user and
+set to the Exim group. The mode for spool files is defined in the
+\(Local/Makefile)\ configuration file, and defaults to 0640. This means that
+any user who is a member of the Exim group can access these files.
+
+
+.section Use of argv[0]
+Exim examines the last component of \argv[0]\, and if it matches one of a set
+of specific strings, Exim assumes certain options. For example, calling Exim
+with the last component of \argv[0]\ set to `rsmtp' is exactly equivalent to
+calling it with the option \-bS-\. There are no security implications in this.
+
+
+.section Use of %f formatting
+The only use made of `%f' by Exim is in formatting load average values. These
+are actually stored in integer variables as 1000 times the load average.
+Consequently, their range is limited and so therefore is the length of the
+converted output.
+
+
+.section Embedded Exim path
+Exim uses its own path name, which is embedded in the code, only when it needs
+to re-exec in order to regain root privilege. Therefore, it is not root when it
+does so. If some bug allowed the path to get overwritten, it would lead to an
+arbitrary program's being run as exim, not as root.
+
+
+.section Use of sprintf()
+.index \*sprintf()*\
+A large number of occurrences of `sprintf' in the code are actually calls to
+\*string@_sprintf()*\, a function that returns the result in malloc'd store.
+The intermediate formatting is done into a large fixed buffer by a function
+that runs through the format string itself, and checks the length of each
+conversion before performing it, thus preventing buffer overruns.
+
+The remaining uses of \*sprintf()*\ happen in controlled circumstances where
+the output buffer is known to be sufficiently long to contain the converted
+string.
+
+
+.section Use of debug@_printf() and log@_write()
+Arbitrary strings are passed to both these functions, but they do their
+formatting by calling the function \*string@_vformat()*\, which runs through
+the format string itself, and checks the length of each conversion.
+
+
+.section Use of strcat() and strcpy()
+These are used only in cases where the output buffer is known to be large
+enough to hold the result.
+
+
+
+
+.
+.
+.
+.
+. ============================================================================
+.chapter Format of spool files
+.set runningfoot "spool file format"
+.rset CHAPspool ~~chapter
+.index format||spool files
+.index spool directory||format of files
+.index spool||files, format of
+.index spool||files, editing
+A message on Exim's queue consists of two files, whose names are the message id
+followed by -D and -H, respectively. The data portion of the message is kept in
+the -D file on its own. The message's envelope, status, and headers are all
+kept in the -H file, whose format is described in this chapter. Each of these
+two files contains the final component of its own name as its first line. This
+is insurance against disk crashes where the directory is lost but the files
+themselves are recoverable.
+
+.em
+Some people are tempted into editing -D files in order to modify messages. You
+need to be extremely careful if you do this; it is not recommended and you are
+on your own if you do it. Here are some of the pitfalls:
+.numberpars $.
+You must use the \*exim@_lock*\ utility to ensure that Exim does not try to
+deliver the message while you are fiddling with it. The lock is implemented
+by opening the -D file and taking out a write lock on it. If you update the
+file in place, the lock will be retained. If you write a new file and rename
+it, the lock will be lost at the instant of rename.
+.nextp
+If you change the number of lines in the file, the value of
+\$body@_linecount$\, which is stored in the -H file, will be incorrect.
+.nextp
+If the message is in MIME format, you must take care not to break it.
+.nextp
+If the message is cryptographically signed, any change will invalidate the
+signature.
+.endp
+.nem
+
+Files whose names end with -J may also be seen in the \(input)\ directory (or
+its subdirectories when \split@_spool@_directory\ is set). These are journal
+files, used to record addresses to which the message has been delivered during
+the course of a delivery run. At the end of the run, the -H file is updated,
+and the -J file is deleted.
+
+.section Format of the -H file
+.index uid (user id)||in spool file
+.index gid (group id)||in spool file
+The second line of the -H file contains the login name for the uid of the
+process that called Exim to read the message, followed by the numerical uid and
+gid. For a locally generated message, this is normally the user who sent the
+message. For a message received over TCP/IP, it is normally the Exim user.
+
+The third line of the file contains the address of the message's sender as
+transmitted in the envelope, contained in angle brackets. The sender address is
+empty for bounce messages. For incoming SMTP mail, the sender address is given
+in the \\MAIL\\ command. For locally generated mail, the sender address is
+created by Exim from the login name of the current user and the configured
+\qualify@_domain\. However, this can be overridden by the \-f-\ option or a
+leading `From' line if the caller is trusted, or if the supplied address is
+`@<@>' or an address that matches \untrusted@_set@_senders\.
+
+The fourth line contains two numbers. The first is the time that the message
+was received, in the conventional Unix form -- the number of seconds since the
+start of the epoch. The second number is a count of the number of messages
+warning of delayed delivery that have been sent to the sender.
+
+There follow a number of lines starting with a hyphen. These can appear in any
+order, and are omitted when not relevant:
+.numberpars $.
+.em
+\-acl <<number>> <<length>>-\: A line of this form is present for every ACL
+variable that is not empty. The number identifies the variable; the
+\acl@_c\*x*\$$\ variables are numbered 0--9 and the \acl@_m\*x*\$$\ variables
+are numbered 10--19. The length is the length of the data string for the
+variable. The string itself starts at the beginning of the next line, and is
+followed by a newline character. It may contain internal newlines.
+.nextp
+\-allow@_unqualified@_recipient-\: This is present if unqualified recipient
+addresses are permitted in header lines (to stop such addresses from being
+qualified if rewriting occurs at transport time). Local messages that were
+input using \-bnq-\ and remote messages from hosts that match
+\recipient@_unqualified@_hosts\ set this flag.
+.nextp
+\-allow@_unqualified@_sender-\: This is present if unqualified sender
+addresses are permitted in header lines (to stop such addresses from being
+qualified if rewriting occurs at transport time). Local messages that were
+input using \-bnq-\ and remote messages from hosts that match
+\sender@_unqualified@_hosts\ set this flag.
+.nem
+.nextp
+\-auth@_id <<text>>-\: The id information for a message received on an
+authenticated SMTP connection -- the value of the \$authenticated@_id$\
+variable.
+.nextp
+\-auth@_sender <<address>>-\: The address of an authenticated sender -- the
+value of the \$authenticated@_sender$\ variable.
+.nextp
+\-body@_linecount <<number>>-\: This records the number of lines in the body of
+the message, and is always present.
+.nextp
+\-deliver@_firsttime-\: This is written when a new message is first added to
+the spool. When the spool file is updated after a deferral, it is omitted.
+.nextp
+.index frozen messages||spool data
+\-frozen <<time>>-\: The message is frozen, and the freezing happened at
+<<time>>.
+.nextp
+\-helo@_name <<text>>-\: This records the host name as specified by a remote
+host in a \\HELO\\ or \\EHLO\\ command.
+.nextp
+\-host@_address <<address>>.<<port>>-\: This records the IP address of the host
+from which the message was received and the remote port number that was used.
+It is omitted for locally generated messages.
+.nextp
+\-host@_auth <<text>>-\: If the message was received on an authenticated SMTP
+connection, this records the name of the authenticator -- the value of the
+\$sender@_host@_authenticated$\ variable.
+.nextp
+\-host@_lookup@_failed-\: This is present if an attempt to look up the sending
+host's name from its IP address failed. It corresponds to the
+\$host@_lookup@_failed$\ variable.
+.nextp
+.index DNS||reverse lookup
+.index reverse DNS lookup
+\-host@_name <<text>>-\: This records the name of the remote host from which
+the message was received, if the host name was looked up from the IP address
+when the message was being received. It is not present if no reverse lookup was
+done.
+.nextp
+\-ident <<text>>-\: For locally submitted messages, this records the login of
+the originating user, unless it was a trusted user and the \-oMt-\ option was
+used to specify an ident value. For messages received over TCP/IP, this records
+the ident string supplied by the remote host, if any.
+.nextp
+\-interface@_address <<address>>.<<port>>-\: This records the IP address of the
+local interface and the port number through which a message was received from a
+remote host. It is omitted for locally generated messages.
+.nextp
+\-local-\: The message is from a local sender.
+.nextp
+\-localerror-\: The message is a locally-generated bounce message.
+.nextp
+\-local@_scan <<string>>-\: This records the data string that was
+returned by the \*local@_scan()*\ function when the message was received -- the
+value of the \$local@_scan@_data$\ variable. It is omitted if no data was
+returned.
+.nextp
+\-manual@_thaw-\: The message was frozen but has been thawed manually, that is,
+by an explicit Exim command rather than via the auto-thaw process.
+.nextp
+\-N-\: A testing delivery process was started using the \-N-\ option to
+suppress any actual deliveries, but delivery was deferred. At any further
+delivery attempts, \-N-\ is assumed.
+.nextp
+\-received@_protocol-\: This records the value of the \$received@_protocol$\
+variable, which contains the name of the protocol by which the message was
+received.
+.nextp
+\-sender@_set@_untrusted-\: The envelope sender of this message was set by an
+untrusted local caller (used to ensure that the caller is displayed in queue
+listings).
+.nextp
+\-tls@_certificate@_verified-\: A TLS certificate was received from the client
+that sent this message, and the certificate was verified by the server.
+.nextp
+\-tls@_cipher <<cipher name>>-\: When the message was received over an
+encrypted connection, this records the name of the cipher suite that was used.
+.nextp
+\-tls@_peerdn <<peer DN>>-\: When the message was received over an encrypted
+connection, and a certificate was received from the client, this records the
+Distinguished Name from that certificate.
+.endp
+
+Following the options there is a list of those addresses to which the message
+is not to be delivered. This set of addresses is initialized from the command
+line when the \-t-\ option is used and \extract__addresses__remove__arguments\
+is set; otherwise it starts out empty. Whenever a successful delivery is made,
+the address is added to this set. The addresses are kept internally as a
+balanced binary tree, and it is a representation of that tree which is written
+to the spool file. If an address is expanded via an alias or forward file, the
+original address is added to the tree when deliveries to all its child
+addresses are complete.
+
+If the tree is empty, there is a single line in the spool file containing just
+the text `XX'. Otherwise, each line consists of two letters, which are either Y
+or N, followed by an address. The address is the value for the node of the
+tree, and the letters indicate whether the node has a left branch and/or a
+right branch attached to it, respectively. If branches exist, they immediately
+follow. Here is an example of a three-node tree:
+.display asis
+YY darcy@austen.fict.example
+NN alice@wonderland.fict.example
+NN editor@thesaurus.ref.example
+.endd
+After the non-recipients tree, there is a list of the message's recipients.
+This is a simple list, preceded by a count. It includes all the original
+recipients of the message, including those to whom the message has already been
+delivered. In the simplest case, the list contains one address per line. For
+example:
+.display asis
+4
+editor@thesaurus.ref.example
+darcy@austen.fict.example
+rdo@foundation
+alice@wonderland.fict.example
+.endd
+However, when a child address has been added to the top-level addresses as a
+result of the use of the \one@_time\ option on a \%redirect%\ router, each line
+is of the following form:
+.display
+<<top-level address>> <<errors@_to address>> <<length>>,<<parent number>>@#<<flag bits>>
+.endd
+The 01 flag bit indicates the presence of the three other fields that follow
+the top-level address. Other bits may be used in future to support additional
+fields. The <<parent number>> is the offset in the recipients list of the
+original parent of the `one time' address. The first two fields are the
+envelope sender that is associated with this address and its length. If the
+length is zero, there is no special envelope sender (there are then two space
+characters in the line). A non-empty field can arise from a \%redirect%\ router
+that has an \errors@_to\ setting.
+
+
+A blank line separates the envelope and status information from the headers
+which follow. A header may occupy several lines of the file, and to save effort
+when reading it in, each header is preceded by a number and an identifying
+character. The number is the number of characters in the header, including any
+embedded newlines and the terminating newline. The character is one of the
+following:
+.display
+.tabs 9
+<<blank>> $t $rm{header in which Exim has no special interest}
+#B $t $rm{::Bcc:: header}
+#C $t $rm{::Cc:: header}
+#F $t $rm{::From:: header}
+#I $t $rm{::Message-id:: header}
+#P $t $rm{::Received:: header -- P for `postmark'}
+#R $t $rm{::Reply-To:: header}
+#S $t $rm{::Sender:: header}
+#T $t $rm{::To:: header}
+#* $t $rm{replaced or deleted header}
+.endd
+Deleted or replaced (rewritten) headers remain in the spool file for debugging
+purposes. They are not transmitted when the message is delivered. Here is a
+typical set of headers:
+.display asis
+111P Received: by hobbit.fict.example with local (Exim 4.00)
+ id 14y9EI-00026G-00; Fri, 11 May 2001 10:28:59 +0100
+049 Message-Id: <E14y9EI-00026G-00@hobbit.fict.example>
+038* X-rewrote-sender: bb@hobbit.fict.example
+042* From: Bilbo Baggins <bb@hobbit.fict.example>
+049F From: Bilbo Baggins <B.Baggins@hobbit.fict.example>
+099* To: alice@wonderland.fict.example, rdo@foundation,
+ darcy@austen.fict.example, editor@thesaurus.ref.example
+109T To: alice@wonderland.fict.example, rdo@foundation.fict.example,
+ darcy@austen.fict.example, editor@thesaurus.ref.example
+038 Date: Fri, 11 May 2001 10:28:59 +0100
+.endd
+The asterisked headers indicate that the envelope sender, ::From:: header, and
+::To:: header have been rewritten, the last one because routing expanded the
+unqualified domain \*foundation*\.
+
+.
+.
+.
+.
+. ============================================================================
+.chapter Adding new drivers or lookup types
+.set runningfoot "adding drivers"
+.index adding drivers
+.index new drivers, adding
+.index drivers||adding new
+The following actions have to be taken in order to add a new router, transport,
+authenticator, or lookup type to Exim:
+.numberpars
+Choose a name for the driver or lookup type that does not conflict with any
+existing name; I will use `newdriver' in what follows.
+.nextp
+Add to \(src/EDITME)\ the line
+.display
+<<type>>@_NEWDRIVER=yes
+.endd
+where <<type>> is \\ROUTER\\, \\TRANSPORT\\, \\AUTH\\, or \\LOOKUP\\. If the
+code is not to be included in the binary by default, comment this line out. You
+should also add any relevant comments about the driver or lookup type.
+.nextp
+Add to \(src/config.h.defaults)\ the line
+.display
+@#define <<type>>@_NEWDRIVER
+.endd
+.nextp
+Edit \(src/drtables.c)\, adding conditional code to pull in the private header
+and create a table entry as is done for all the other drivers and lookup types.
+.nextp
+Edit \(Makefile)\ in the appropriate sub-directory (\(src/routers)\,
+\(src/transports)\, \(src/auths)\, or \(src/lookups)\); add a line for the new
+driver or lookup type and add it to the definition of OBJ.
+.nextp
+Create \(newdriver.h)\ and \(newdriver.c)\ in the appropriate sub-directory of
+\(src)\.
+.nextp
+Edit \(scripts/MakeLinks)\ and add commands to link the \(.h)\ and \(.c)\ files
+as for other drivers and lookups.
+.endp
+Then all you need to do is write the code! A good way to start is to make a
+proforma by copying an existing module of the same type, globally changing all
+occurrences of the name, and cutting out most of the code. Note that any
+options you create must be listed in alphabetical order, because the tables are
+searched using a binary chop procedure.
+
+There is a \(README)\ file in each of the sub-directories of \(src)\ describing
+the interface that is expected.
+
+.
+.
+.
+.
+. ============================================================================
+. Fudge for the index page number. We want it to be on a right-hand page.
+.
+.set indexpage ~~sys.pagenumber + 1
+.if even ~~indexpage
+.set indexpage ~~indexpage + 1
+.fi
+.if ~~sgcal
+.%index Index$e~~indexpage--
+.fi
+.
+.
+. End of Exim specification
diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog
new file mode 100644
index 000000000..adeaba70d
--- /dev/null
+++ b/doc/doc-txt/ChangeLog
@@ -0,0 +1,2058 @@
+$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.1 2004/10/07 15:04:35 ph10 Exp $
+
+Change log file for Exim from version 4.21
+-------------------------------------------
+
+
+Exim version 4.44
+-----------------
+
+1. Minor wording change to the doc/README.SIEVE file.
+
+
+Exim version 4.43
+-----------------
+
+ 1. Fixed a longstanding but relatively impotent bug: a long time ago, before
+ PIPELINING, the function smtp_write_command() used to return TRUE or FALSE.
+ Now it returns an integer. A number of calls were still expecting a T/F
+ return. Fortuitously, in all cases, the tests worked in OK situations,
+ which is the norm. However, things would have gone wrong on any write
+ failures on the smtp file descriptor. This function is used when sending
+ messages over SMTP and also when doing verify callouts.
+
+ 2. When Exim is called to do synchronous delivery of a locally submitted
+ message (the -odf or -odi options), it no longer closes stderr before doing
+ the delivery.
+
+ 3. Implemented the mua_wrapper option.
+
+ 4. Implemented mx_fail_domains and srv_fail_domains for the dnslookup router.
+
+ 5. Implemented the functions header_remove(), header_testname(),
+ header_add_at_position(), and receive_remove_recipient(), and exported them
+ to local_scan().
+
+ 6. If an ACL "warn" statement specified the addition of headers, Exim already
+ inserted X-ACL-Warn: at the start if there was no header name. However, it
+ was not making this test for the second and subsequent header lines if
+ there were newlines in the string. This meant that an invalid header could
+ be inserted if Exim was badly configured.
+
+ 7. Allow an ACL "warn" statement to add header lines at the start or after all
+ the Received: headers, as well as at the end.
+
+ 8. Added the rcpt_4xx retry error code.
+
+ 9. Added postmaster_mailfrom=xxx to callout verification option.
+
+10. Added mailfrom=xxxx to the callout verification option, for verify=
+ header_sender only.
+
+11. ${substr_1_:xxxx} and ${substr__3:xxxx} are now diagnosed as syntax errors
+ (they previously behaved as ${substr_1_0:xxxx} and ${substr:_0_3:xxxx}).
+
+12. Inserted some casts to stop certain compilers warning when using pointer
+ differences as field lengths or precisions in printf-type calls (mostly
+ affecting debugging statements).
+
+13. Added optional readline() support for -be (dynamically loaded).
+
+14. Obscure bug fix: if a message error (e.g. 4xx to MAIL) happened within the
+ same clock tick as a message's arrival, so that its received time was the
+ same as the "first fail" time on the retry record, and that message
+ remained on the queue past the ultimate address timeout, every queue runner
+ would try a delivery (because it was past the ultimate address timeout) but
+ after another failure, the ultimate address timeout, which should have then
+ bounced the address, did not kick in. This was a "< instead of <=" error;
+ in most cases the first failure would have been in the next clock tick
+ after the received time, and all would be well.
+
+15. The special items beginning with @ in domain lists (e.g. @mx_any) were not
+ being recognized when the domain list was tested by the match_domain
+ condition in an expansion string.
+
+16. Added the ${str2b64: operator.
+
+17. Exim was always calling setrlimit() to set a large limit for the number of
+ processes, without checking whether the existing limit was already
+ adequate. (It did check for the limit on file descriptors.) Furthermore,
+ errors from getrlimit() and setrlimit() were being ignored. Now they are
+ logged to the main and panic logs, but Exim does carry on, to try to do its
+ job under whatever limits there are.
+
+18. Imported PCRE 5.0.
+
+19. Trivial typo in log message " temporarily refused connection" (the leading
+ space).
+
+20. If the log selector return_path_on_delivery was set and an address was
+ redirected to /dev/null, the delivery process crashed because it assumed
+ that a return path would always be set for a "successful" delivery. In this
+ case, the whole delivery is bypassed as an optimization, and therefore no
+ return path is set.
+
+21. Internal re-arrangement: the function for sending a challenge and reading
+ a response while authentication was assuming a zero-terminated challenge
+ string. It's now changed to take a pointer and a length, to allow for
+ binary data in such strings.
+
+22. Added the cyrus_sasl authenticator (code supplied by MBM).
+
+23. Exim was not respecting finduser_retries when seeking the login of the
+ uid under which it was called; it was always trying 10 times. (The default
+ setting of finduser_retries is zero.) Also, it was sleeping after the final
+ failure, which is pointless.
+
+24. Implemented tls_on_connect_ports.
+
+25. Implemented acl_smtp_predata.
+
+26. If the domain in control=submission is set empty, Exim assumes that the
+ authenticated id is a complete email address when it generates From: or
+ Sender: header lines.
+
+27. Added "#define SOCKLEN_T int" to OS/os.h-SCO and OS/os.h-SCO_SV. Also added
+ definitions to OS/Makefile-SCO and OS/Makefile-SCO_SV that put basename,
+ chown and chgrp in /bin and hostname in /usr/bin.
+
+28. Exim was keeping the "process log" file open after each use, just as it
+ does for the main log. This opens the possibility of it remaining open for
+ long periods when the USR1 signal hits a daemon. Occasional processlog
+ errors were reported, that could have been caused by this. Anyway, it seems
+ much more sensible not to leave this file open at all, so that is what now
+ happens.
+
+29. The long-running daemon process does not normally write to the log once it
+ has entered its main loop, and it closes the log before doing so. This is
+ so that log files can straightforwardly be renamed and moved. However,
+ there are a couple of unusual error situations where the daemon does write
+ log entries, and I had neglected to close the log afterwards.
+
+30. The text of an SMTP error response that was received during a remote
+ delivery was being truncated at 512 bytes. This is too short for some of
+ the long messages that one sometimes sees. I've increased the limit to
+ 1024.
+
+31. It is now possible to make retry rules that apply only when a message has a
+ specific sender, in particular, an empty sender.
+
+32. Added "control = enforce_sync" and "control = no_enforce_sync". This makes
+ it possible to be selective about when SMTP synchronization is enforced.
+
+33. Added "control = caseful_local_part" and "control = "caselower_local_part".
+
+32. Implemented hosts_connection_nolog.
+
+33. Added an ACL for QUIT.
+
+34. Setting "delay_warning=" to disable warnings was not working; it gave a
+ syntax error.
+
+35. Added mailbox_size and mailbox_filecount to appendfile.
+
+36. Added control = no_multiline_responses to ACLs.
+
+37. There was a bug in the logic of the code that waits for the clock to tick
+ in the case where the clock went backwards by a substantial amount such
+ that the microsecond fraction of "now" was more than the microsecond
+ fraction of "then" (but the whole seconds number was less).
+
+38. Added support for the libradius Radius client library this is found on
+ FreeBSD (previously only the radiusclient library was supported).
+
+
+Exim version 4.42
+-----------------
+
+ 1. When certain lookups returned multiple values in the form name=value, the
+ quoting of the values was not always being done properly. Specifically:
+ (a) If the value started with a double quote, but contained no whitespace,
+ it was not quoted.
+ (b) If the value contained whitespace other than a space character (i.e.
+ tabs or newlines or carriage returns) it was not quoted.
+ This fix has been applied to the mysql and pgsql lookups by writing a
+ separate quoting function and calling it from the lookup code. The fix
+ should probably also be applied to nisplus, ibase and oracle lookups, but
+ since I cannot test any of those, I have not disturbed their existing code.
+
+ 2. A hit in the callout cache for a specific address caused a log line with no
+ reason for rejecting RCPT. Now it says "Previous (cached) callout
+ verification failure".
+
+ 3. There was an off-by-one bug in the queryprogram router. An over-long
+ return line was truncated at 256 instead of 255 characters, thereby
+ overflowing its buffer with the terminating zero. As well as fixing this, I
+ have increased the buffer size to 1024 (and made a note to document this).
+
+ 4. If an interrupt, such as the USR1 signal that is send by exiwhat, arrives
+ when Exim is waiting for an SMTP response from a remote server, Exim
+ restarts its select() call on the socket, thereby resetting its timeout.
+ This is not a problem when such interrupts are rare. Somebody set up a cron
+ job to run exiwhat every 2 minutes, which is less than the normal select()
+ timeout (5 or 10 minutes). This meant that the select() timeout never
+ kicked in because it was always reset. I have fixed this by comparing the
+ time when an interrupt arrives with the time at the start of the first call
+ to select(). If more time than the timeout has elapsed, the interrupt is
+ treated as a timeout.
+
+ 5. Some internal re-factoring in preparation for the addition of Sieve
+ extensions (by MH). In particular, the "personal" test is moved to a
+ separate function, and given an option for scanning Cc: and Bcc: (which is
+ not set for Exim filters).
+
+ 6. When Exim created an email address using the login of the caller as the
+ local part (e.g. when creating a From: or Sender: header line), it was not
+ quoting the local part when it contained special characters such as @.
+
+ 7. Installed new OpenBSD configuration files.
+
+ 8. Reworded some messages for syntax errors in "and" and "or" conditions to
+ try to make them clearer.
+
+ 9. Callout options, other than the timeout value, were being ignored when
+ verifying sender addresses in header lines. For example, when using
+
+ verify = header_sender/callout=no_cache
+
+ the cache was (incorrectly) being used.
+
+10. Added a missing instance of ${EXE} to the exim_install script; this affects
+ only the Cygwin environment.
+
+11. When return_path_on_delivery was set as a log selector, if different remote
+ addresses in the same message used different return paths and parallel
+ remote delivery occurred, the wrong values would sometimes be logged.
+ (Whenever a remote delivery process finished, the return path value from
+ the most recently started remote delivery process was logged.)
+
+12. RFC 3848 specifies standard names for the "with" phrase in Received: header
+ lines when AUTH and/or TLS are in use. This is the "received protocol"
+ field. Exim used to use "asmtp" for authenticated SMTP, without any
+ indication (in the protocol name) for TLS use. Now it follows the RFC and
+ uses "esmtpa" if the connection is authenticated, "esmtps" if it is
+ encrypted, and "esmtpsa" if it is both encrypted and authenticated. These
+ names appear in log lines as well as in Received: header lines.
+
+13. Installed MH's patches for Sieve to add the "copy" and "vacation"
+ extensions, and comparison tests, and to fix some bugs.
+
+14. Changes to the "personal" filter test:
+
+ (1) The test was buggy in that it was just doing the equivalent of
+ "contains" tests on header lines. For example, if a user's address was
+ anne@some.where, the "personal" test would incorrectly be true for
+
+ To: susanne@some.where
+
+ This test is now done by extracting each address from the header in turn,
+ and checking the entire address. Other tests that are part of "personal"
+ are now done using regular expressions (for example, to check local parts
+ of addresses in From: header lines).
+
+ (2) The list of non-personal local parts in From: addresses has been
+ extended to include "listserv", "majordomo", "*-request", and "owner-*",
+ taken from the Sieve specification recommendations.
+
+ (3) If the message contains any header line starting with "List-" it is
+ treated as non-personal.
+
+ (4) The test for "circular" in the Subject: header line has been removed
+ because it now seems ill-conceived.
+
+15. Minor typos in src/EDITME comments corrected.
+
+16. Installed latest exipick from John Jetmore.
+
+17. If headers_add on a router specified a text string that was too long for
+ string_sprintf() - that is, longer than 8192 bytes - Exim panicked. The use
+ of string_sprintf() is now avoided.
+
+18. $message_body_size was not set (it was always zero) when running the DATA
+ ACL and the local_scan() function.
+
+19. For the "mail" command in an Exim filter, no default was being set for
+ the once_repeat time, causing a random time value to be used if "once" was
+ specified. (If the value happened to be <= 0, no repeat happened.) The
+ default is now 0s, meaning "never repeat". The "vacation" command was OK
+ (its default is 7d). It's somewhat surprising nobody ever noticed this bug
+ (I found it when inspecting the code).
+
+20. There is now an overall timeout for performing a callout verification. It
+ defaults to 4 times the callout timeout, which applies to individual SMTP
+ commands during the callout. The overall timeout applies when there is more
+ than one host that can be tried. The timeout is checked before trying the
+ next host. This prevents very long delays if there are a large number of
+ hosts and all are timing out (e.g. when the network connections are timing
+ out). The value of the overall timeout can be changed by specifying an
+ additional sub-option for "callout", called "maxwait". For example:
+
+ verify = sender/callout=5s,maxwait=20s
+
+21. Add O_APPEND to the open() call for maildirsize files (Exim already seeks
+ to the end before writing, but this should make it even safer).
+
+22. Exim was forgetting that it had advertised PIPELINING for the second and
+ subsequent messages on an SMTP connection. It was also not resetting its
+ memory on STARTTLS and an internal HELO.
+
+23. When Exim logs an SMTP synchronization error within a session, it now
+ records whether PIPELINING has been advertised or not.
+
+24. Added 3 instances of "(long int)" casts to time_t variables that were being
+ formatted using %ld, because on OpenBSD (and perhaps others), time_t is int
+ rather than long int.
+
+25. Installed the latest Cygwin configuration files from the Cygwin maintainer.
+
+26. Added the never_mail option to autoreply.
+
+
+Exim version 4.41
+-----------------
+
+ 1. A reorganization of the code in order to implement 4.40/8 caused a daemon
+ crash if the getsockname() call failed; this can happen if a connection is
+ closed very soon after it is established. The problem was simply in the
+ order in which certain operations were done, causing Exim to try to write
+ to the SMTP stream before it had set up the file descriptor. The bug has
+ been fixed by making things happen in the correct order.
+
+
+Exim version 4.40
+-----------------
+
+ 1. If "drop" was used in a DATA ACL, the SMTP output buffer was not flushed
+ before the connection was closed, thus losing the rejection response.
+
+ 2. Commented out the definition of SOCKLEN_T in os.h-SunOS5. It is needed for
+ some early Solaris releases, but causes trouble in current releases where
+ socklen_t is defined.
+
+ 3. When std{in,out,err} are closed, re-open them to /dev/null so that they
+ always exist.
+
+ 4. Minor refactoring of os.c-Linux to avoid compiler warning when IPv6 is not
+ configured.
+
+ 5. Refactoring in expand.c to improve memory usage. Pre-allocate a block so
+ that releasing the top of it at the end releases what was used for sub-
+ expansions (unless the block got too big). However, discard this block if
+ the first thing is a variable or header, so that we can use its block when
+ it is dynamic (useful for very large $message_headers, for example).
+
+ 6. Lookups now cache *every* query, not just the most recent. A new, separate
+ store pool is used for this. It can be recovered when all lookup caches are
+ flushed. Lookups now release memory at the end of their result strings.
+ This has involved some general refactoring of the lookup sources.
+
+ 7. Some code has been added to the store_xxx() functions to reduce the amount
+ of flapping under certain conditions.
+
+ 8. log_incoming_interface used to affect only the <= reception log lines. Now
+ it causes the local interface and port to be added to several more SMTP log
+ lines, for example "SMTP connection from", and rejection lines.
+
+ 9. The Sieve author supplied some patches for the doc/README.SIEVE file.
+
+10. Added a conditional definition of _BSD_SOCKLEN_T to os.h-Darwin.
+
+11. If $host_data was set by virtue of a hosts lookup in an ACL, its value
+ could be overwritten at the end of the current message (or the start of a
+ new message if it was set in a HELO ACL). The value is now preserved for
+ the duration of the SMTP connection.
+
+12. If a transport had a headers_rewrite setting, and a matching header line
+ contained an unqualified address, that address was qualified, even if it
+ did not match any rewriting rules. The underlying bug was that the values
+ of the flags that permit the existence of unqualified sender and recipient
+ addresses in header lines (set by {sender,recipient}_unqualified_hosts for
+ non-local messages, and by -bnq for local messages) were not being
+ preserved with the message after it was received.
+
+13. When Exim was logging an SMTP synchronization error, it could sometimes log
+ "next input=" as part of the text comprising the host identity instead of
+ the correct text. The code was using the same buffer for two different
+ strings. However, depending on which order the printing function evaluated
+ its arguments, the bug did not always show up. Under Linux, for example, my
+ test suite worked just fine.
+
+14. Exigrep contained a use of Perl's "our" scoping after change 4.31/70. This
+ doesn't work with some older versions of Perl. It has been changed to "my",
+ which in any case is probably the better facility to use.
+
+15. A really picky compiler found some instances of statements for creating
+ error messages that either had too many or two few arguments for the format
+ string.
+
+16. The size of the buffer for calls to the DNS resolver has been increased
+ from 1024 to 2048. A larger buffer is needed when performing PTR lookups
+ for addresses that have a lot of PTR records. This alleviates a problem; it
+ does not fully solve it.
+
+17. A dnsdb lookup for PTR records that receives more data than will fit in the
+ buffer now truncates the list and logs the incident, which is the same
+ action as happens when Exim is looking up a host name and its aliases.
+ Previously in this situation something unpredictable would happen;
+ sometimes it was "internal error: store_reset failed".
+
+18. If a server dropped the connection unexpectedly when an Exim client was
+ using GnuTLS and trying to read a response, the client delivery process
+ crashed while trying to generate an error log message.
+
+19. If a "warn" verb in an ACL added multiple headers to a message in a single
+ string, for example:
+
+ warn message = H1: something\nH2: something
+
+ the text was added as a single header line from Exim's point of view
+ though it ended up OK in the delivered message. However, searching for the
+ second and subsequent header lines using $h_h2: did not work. This has been
+ fixed. Similarly, if a system filter added multiple headers in this way,
+ the routers could not see them.
+
+20. Expanded the error message when iplsearch is called with an invalid key to
+ suggest using net-iplsearch in a host list.
+
+21. When running tests using -bh, any delays imposed by "delay" modifiers in
+ ACLs are no longer actually imposed (and a message to that effect is
+ output).
+
+22. If a "gecos" field in a passwd entry contained escaped characters, in
+ particular, if it contained a \" sequence, Exim got it wrong when building
+ a From: or a Sender: header from that name. A second bug also caused
+ incorrect handling when an unquoted " was present following a character
+ that needed quoting.
+
+23. "{crypt}" as a password encryption mechanism for a "crypteq" expansion item
+ was not being matched caselessly.
+
+24. Arranged for all hyphens in the exim.8 source to be escaped with
+ backslashes.
+
+25. Change 16 of 4.32, which reversed 71 or 4.31 didn't quite do the job
+ properly. Recipient callout cache records were still being keyed to include
+ the sender, even when use_sender was set false. This led to far more
+ callouts that were necessary. The sender is no longer included in the key
+ when use_sender is false.
+
+26. Added "control = submission" modifier to ACLs.
+
+27. Added the ${base62d: operator to decode base 62 numbers.
+
+28. dnsdb lookups can now access SRV records.
+
+29. CONFIGURE_OWNER can be set at build time to define an alternative owner for
+ the configuration file.
+
+30. The debug message "delivering xxxxxx-xxxxxx-xx" is now output in verbose
+ (-v) mode. This makes the output for a verbose queue run more intelligible.
+
+31. Added a use_postmaster feature to recipient callouts.
+
+32. Added the $body_zerocount variable, containing the number of binary zero
+ bytes in the message body.
+
+33. The time of last modification of the "new" subdirectory is now used as the
+ "mailbox time last read" when there is a quota error for a maildir
+ delivery.
+
+34. Added string comparison operators lt, lti, le, lei, gt, gti, ge, gei.
+
+35. Added +ignore_unknown as a special item in host lists.
+
+36. Code for decoding IPv6 addresses in host lists is now included, even if
+ IPv6 support is not being compiled. This fixes a bug in which an IPv6
+ address was recognized as an IP address, but was then not correctly decoded
+ into binary, causing unexpected and incorrect effects when compared with
+ another IP address.
+
+
+Exim version 4.34
+-----------------
+
+ 1. Very minor rewording of debugging text in manualroute to say "list of
+ hosts" instead of "hostlist".
+
+ 2. If verify=header_syntax was set, and a header line with an unqualified
+ address (no domain) and a large number of spaces between the end of the
+ name and the colon was received, the reception process suffered a buffer
+ overflow, and (when I tested it) crashed. This was caused by some obsolete
+ code that should have been removed. The fix is to remove it!
+
+ 3. When running in the test harness, delay a bit after writing a bounce
+ message to get a bit more predictability in the log output.
+
+ 4. Added a call to search_tidyup() just before forking a reception process. In
+ theory, someone could use a lookup in the expansion of smtp_accept_max_
+ per_host which, without the tidyup, could leave open a database connection.
+
+ 5. Added the variables $recipient_data and $sender_data which get set from a
+ lookup success in an ACL "recipients" or "senders" condition, or a router
+ "senders" option, similar to $domain_data and $local_part_data.
+
+ 6. Moved the writing of debug_print from before to after the "senders" test
+ for routers.
+
+ 7. Change 4.31/66 (moving the time when the Received: is generated) caused
+ problems for message scanning, either using a data ACL, or using
+ local_scan() because the Received: header was not generated till after they
+ were called (in order to set the time as the time of reception completion).
+ I have revised the way this works. The header is now generated after the
+ body is received, but before the ACL or local_scan() are called. After they
+ are run, the timestamp in the header is updated.
+
+
+Exim version 4.33
+-----------------
+
+ 1. Change 4.24/6 introduced a bug because the SIGALRM handler was disabled
+ before starting a queue runner without re-exec. This happened only when
+ deliver_drop_privilege was set or when the Exim user was set to root. The
+ effect of the bug was that timeouts during subsequent deliveries caused
+ crashes instead of being properly handled. The handler is now left at its
+ default (and expected) setting.
+
+ 2. The other case in which a daemon avoids a re-exec is to deliver an incoming
+ message, again when deliver_drop_privilege is set or Exim is run as root.
+ The bug described in (1) was not present in this case, but the tidying up
+ of the other signals was missing. I have made the two cases consistent.
+
+ 3. The ignore_target_hosts setting on a manualroute router was being ignored
+ for hosts that were looked up using the /MX notation.
+
+ 4. Added /ignore=<ip list> feature to @mx_any, @mx_primary, and @mx_secondary
+ in domain lists.
+
+ 5. Change 4.31/55 was buggy, and broke when there was a rewriting rule that
+ operated on the sender address. After changing the $sender_address to <>
+ for the sender address verify, Exim was re-instated it as the original
+ (before rewriting) address, but remembering that it had rewritten it, so it
+ wasn't rewriting it again. This bug also had the effect of breaking the
+ sender address verification caching when the sender address was rewritten.
+
+ 6. The ignore_target_hosts option was being ignored by the ipliteral router.
+ This has been changed so that if the ip literal address matches
+ ignore_target_hosts, the router declines.
+
+ 7. Added expansion conditions match_domain, match_address, and match_local_
+ part (NOT match_host).
+
+ 8. The placeholder for the Received: header didn't have a length field set.
+
+ 9. Added code to Exim itself and to exim_lock to test for a specific race
+ condition that could lead to file corruption when using MBX delivery. The
+ issue is with the lockfile that is created in /tmp. If this file is removed
+ after a process has opened it but before that process has acquired a lock,
+ there is the potential for a second process to recreate the file and also
+ acquire a lock. This could lead to two Exim processes writing to the file
+ at the same time. The added code performs the same test as UW imapd; it
+ checks after acquiring the lock that its file descriptor still refers to
+ the same named file.
+
+10. The buffer for building added header lines was of fixed size, 8192 bytes.
+ It is now parameterized by HEADER_ADD_BUFFER_SIZE and this can be adjusted
+ when Exim is built.
+
+11. Added the smtp_active_hostname option. If used, this will typically be made
+ to depend on the incoming interface address. Because $interface_address is
+ not set up until the daemon has forked a reception process, error responses
+ that can happen earlier (such as "too many connections") no longer contain
+ a host name.
+
+12. If an expansion in a condition on a "warn" statement fails because a lookup
+ defers, the "warn" statement is abandoned, and the next ACL statement is
+ processed. Previously this caused the whole ACL to be aborted.
+
+13. Added the iplsearch lookup type.
+
+14. Added ident_timeout as a log selector.
+
+15. Added tls_certificate_verified as a log selector.
+
+16. Added a global option tls_require_ciphers (compare the smtp transport
+ option of the same name). This controls incoming TLS connections.
+
+17. I finally figured out how to make tls_require_ciphers do a similar thing
+ in GNUtls to what it does in OpenSSL, that is, set up an appropriate list
+ before starting the TLS session.
+
+18. Tabs are now shown as \t in -bP output.
+
+19. If the log selector return_path_on_delivery was set, Exim crashed when
+ bouncing a message because it had too many Received: header lines.
+
+20. If two routers both had headers_remove settings, and the first one included
+ a superfluous trailing colon, the final name in the first list and the
+ first name in the second list were incorrectly joined into one item (with a
+ colon in the middle).
+
+
+Exim version 4.32
+-----------------
+
+ 1. Added -C and -D options to the exinext utility, mainly to make it easier
+ to include in the automated testing, but these could be helpful when
+ multiple configurations are in use.
+
+ 2. The exinext utility was not formatting the output nicely when there was
+ an alternate port involved in the retry record key, nor when there was a
+ message id as well (for retries that were specific to a specific message
+ and a specific host). It was also confused by IPv6 addresses, because of
+ the additional colons they contain. I have fixed the IPv4 problem, and
+ patched it up to do a reasonable job for IPv6.
+
+ 3. When there is an error after a MAIL, RCPT, or DATA SMTP command during
+ delivery, the log line now contains "pipelined" if PIPELINING was used.
+
+ 4. An SMTP transport process used to panic and die if the bind() call to set
+ an explicit outgoing interface failed. This has been changed; it is now
+ treated in the same way as a connect() failure.
+
+ 5. A reference to $sender_host_name in the part of a conditional expansion
+ that was being skipped was still causing a DNS lookup. This no longer
+ occurs.
+
+ 6. The def: expansion condition was not recognizing references to header lines
+ that used bh_ and bheader_.
+
+ 7. Added the _cache feature to named lists.
+
+ 8. The code for checking quota_filecount in the appendfile transport was
+ allowing one more file than it should have been.
+
+ 9. For compatibility with Sendmail, the command line option
+
+ -prval:sval
+
+ is equivalent to
+
+ -oMr rval -oMs sval
+
+ and sets the incoming protocol and host name (for trusted callers). The
+ host name and its colon can be omitted when only the protocol is to be set.
+ Note the Exim already has two private options, -pd and -ps, that refer to
+ embedded Perl. It is therefore impossible to set a protocol value of "d" or
+ "s", but I don't think that's a major issue.
+
+10. A number of refactoring changes to the code, none of which should affect
+ Exim's behaviour:
+
+ (a) The number of logging options was getting close to filling up the
+ 32-bit word that was used as a bit map. I have split them into two classes:
+ those that are passed in the argument to log_write(), and those that are
+ only ever tested independently outside of that function. These are now in
+ separate 32-bit words, so there is plenty of room for expansion again.
+ There is no change in the user interface or the logging behaviour.
+
+ (b) When building, for example, log lines, the code previously used a
+ macro that called string_cat() twice, in order to add two strings. This is
+ not really sufficiently general. Furthermore, there was one instance where
+ it was actually wrong because one of the argument was used twice, and in
+ one call a function was used. (As it happened, calling the function twice
+ did not affect the overall behaviour.) The macro has been replaced by a
+ function that can join an arbitrary number of extra strings onto a growing
+ string.
+
+ (c) The code for expansion conditions now uses a table and a binary chop
+ instead of a serial search (which was left over from when there were very
+ few conditions). Also, it now recognizes conditions like "pam" even when
+ the relevant support is not compiled in: a suitably worded error message is
+ given if an attempt is made to use such a condition.
+
+11. Added ${time_interval:xxxxx}.
+
+12. A bug was causing one of the ddress fields not to be passed back correctly
+ from remote delivery subprocesses. The field in question was not being
+ subsequently used, so this caused to problems in practice.
+
+13. Added new log selectors queue_time and deliver_time.
+
+14. Might have fixed a bug in maildirsizefile handling that threw up
+ "unexpected character" debug warnings, and recalculated the data
+ unnecessarily. In any case, I expanded the warning message to give more
+ information.
+
+15. Added the message "Restricted characters in address" to the statements in
+ the default ACL that block characters like @ and % in local parts.
+
+16. Change 71 for release 4.31 proved to be much less benign that I imagined.
+ Three changes have been made:
+
+ (a) There was a serious bug; a negative response to MAIL caused the whole
+ recipient domain to be cached as invalid, thereby blocking all messages
+ to all local parts at the same domain, from all senders. This bug has
+ been fixed. The domain is no longer cached after a negative response to
+ MAIL if the sender used is not empty.
+
+ (b) The default behaviour of using MAIL FROM:<> for recipient callouts has
+ been restored.
+
+ (c) A new callout option, "use_sender" has been added for people who want
+ the modified behaviour.
+
+
+Exim version 4.31
+-----------------
+
+ 1. Removed "EXTRALIBS=-lwrap" from OS/Makefile-Unixware7 on the advice of
+ Larry Rosenman.
+
+ 2. Removed "LIBS = -lresolv" from OS/Makefile-Darwin as it is not needed, and
+ indeed breaks things for older releases.
+
+ 3. Added additional logging to the case where there is a problem reading data
+ from a filter that is running in a subprocess using a pipe, in order to
+ try to track down a specific problem.
+
+ 4. Testing facility fudge: when running in the test harness and attempting
+ to connect to 10.x.x.x (expecting a connection timeout) I'm now sometimes
+ getting "No route to host". Convert this to a timeout.
+
+ 5. Define ICONV_ARG2_TYPE as "char **" for Unixware7 to avoid compiler
+ warning.
+
+ 6. Some OS don't have socklen_t but use size_t instead. This affects the
+ fifth argument of getsockopt() amongst other things. This is now
+ configurable by a macro called SOCKLEN_T which defaults to socklen_t, but
+ can be set for individual OS. I have set it for SunOS5, OSF1, and
+ Unixware7. Current versions of SunOS5 (aka Solaris) do have socklen_t, but
+ some earlier ones do not.
+
+ 7. Change 4.30/15 was not doing the test caselessly.
+
+ 8. The standard form for an IPv6 address literal was being rejected by address
+ parsing in, for example, MAIL and RCPT commands. An example of this kind of
+ address is [IPv6:2002:c1ed:8229:10:202:2dff:fe07:a42a]. Exim now accepts
+ this, as well as the form without the "IPv6" on the front (but only when
+ address literals are enabled, of course).
+
+ 9. Added some casts to avoid compiler warnings in OS/os.c-Linux.
+
+10. Exim crashed if a message with an empty sender address specified by -f
+ encountered a router with an errors_to setting. This could be provoked only
+ by a command such as
+
+ exim -f "" ...
+
+ where an empty string was supplied; "<>" did not hit this bug.
+
+11. Installed PCRE release 4.5.
+
+12. If EHLO/HELO was rejected by an ACL, the value of $sender_helo_name
+ remained set. It is now erased.
+
+13. exiqgrep wasn't working on MacOS X because it didn't correctly compute
+ times from message ids (which are base 36 rather than the normal 62).
+
+14. "Expected" SMTP protocol errors that can arise when PIPELINING is in use
+ were being counted as actual protocol errors, and logged if the log
+ selector +smtp_protocol_error was set. One cannot be perfect in this test,
+ but now, if PIPELINING has been advertised, RCPT following a rejected MAIL,
+ and DATA following a set of rejected RCPTs do not count as protocol errors.
+ In other words, Exim assumes they were pipelined, though this may not
+ actually be the case. Of course, in all cases the client gets an
+ appropriate error code.
+
+15. If a lookup fails in an ACL condition, a message about the failure may
+ be available; it is used if testing the ACL cannot continue, because most
+ such messages specify what the cause of the deferral is. However, some
+ messages (e.g. "MYSQL: no data found") do not cause a defer. There was bug
+ that caused an old message to be retained and used if a later statement
+ caused a defer, replacing the real cause of the deferral.
+
+16. If an IP address had so many PTR records that the DNS lookup buffer
+ was not large enough to hold them, Exim could crash while trying to process
+ the truncated data. It now detects and logs this case.
+
+17. Further to 4.21/58, another change has been made: if (and only if) the
+ first line of a message (the first header line) ends with CRLF, a bare LF
+ in a subsequent header line has a space inserted after it, so as not to
+ terminate the header.
+
+18. Refactoring: tidied an ugly bit of code in appendfile that copied data
+ unnecessarily, used atoi() instead of strtol(), and didn't check the
+ termination when getting file sizes from file names by regex.
+
+19. Completely re-implemented the support for maildirsize files, in the light
+ of a number of problems with the previous contributed implementation
+ (4.30/29). In particular:
+
+ . If the quota is zero, the maildirsize file is maintained, but no quota is
+ imposed.
+
+ . If the maildir directory does not exist, it is created before any attempt
+ to write a maildirsize file.
+
+ . The quota value in the file is just a cache; if the quota is changed in
+ the transport, the new value overrides.
+
+ . A regular expression is available for excluding directories from the
+ count.
+
+20. The autoreply transport checks the characters in options that define the
+ message's headers; it allows continued headers, but it was checking with
+ isspace() after an embedded newline instead of explicitly looking for a
+ space or a tab.
+
+21. If all the "regular" hosts to which an address was routed had passed their
+ expiry times, and had not reached their retry times, the address was
+ bounced, even if fallback hosts were defined. Now Exim should go on to try
+ the fallback hosts.
+
+22. Increased buffer sizes in the callout code from 1024 to 4096 to match the
+ equivalent code in the SMTP transport. Some hosts send humungous responses
+ to HELO/EHLO, more than 1024 it seems.
+
+23. Refactoring: code in filter.c used (void *) for "any old type" but this
+ gives compiler warnings in some environments. I've now done it "properly",
+ using a union.
+
+24. The replacement for inet_ntoa() that is used with gcc on IRIX systems
+ (because of problems with the built-in one) was declared to return uschar *
+ instead of char *, causing compiler failure.
+
+25. Fixed a file descriptor leak when processing alias/forward files.
+
+26. Fixed a minor format string issue in dbfn.c.
+
+27. Typo in exim.c: ("dmbnz" for "dbmnz").
+
+28. If a filter file refered to $h_xxx or $message_headers, and the headers
+ contained RFC 2047 "words", Exim's memory could, under certain conditions,
+ become corrupted.
+
+29. When a sender address is verified, it is cached, to save repeating the test
+ when there is more than one recipient in a message. However, when the
+ verification involves a callout, it is possible for different callout
+ options to be set for different recipients. It is too complicated to keep
+ track of this in the cache, so now Exim always runs a verification when a
+ callout is required, relying on the callout cache for the optimization.
+ The overhead is duplication of the address routing, but this should not be
+ too great.
+
+30. Fixed a bug in callout caching. If a RCPT command caused the sender address
+ to be verified with callout=postmaster, and the main callout worked but the
+ postmaster check failed, the verification correctly failed. However, if a
+ subsequent RCPT command asked for sender verification *without* the
+ postmaster check, incorrect caching caused this verification also to fail,
+ incorrectly.
+
+31. Exim caches DNS lookup failures so as to avoid multiple timeouts; however,
+ it was not caching the DNS options (qualify_single, search_parents) that
+ were used when the lookup failed. A subsequent lookup with different
+ options therefore always gave the same answer, though there were cases
+ where it should not have. (Example: a "domains = !$mx_any" option on a
+ dnslookup router: the "domains" option is always processed without any
+ widening, but the router might have qualify_single set.) Now Exim uses the
+ cached value only when the same options are set.
+
+32. Added John Jetmore's "exipick" utility to the distribution.
+
+33. GnuTLS: When an attempt to start a TLS session fails for any reason other
+ than a timeout (e.g. a certificate is required, and is not provided), an
+ Exim server now closes the connection immediately. Previously it waited for
+ the client to close - but if the client is SSL, it seems that they each
+ wait for each other, leading to a delay before one of them times out.
+
+34: GnuTLS: Updated the code to use the new GnuTLS 1.0.0 API. I have not
+ maintained 0.8.x compatibility because I don't think many are using it, and
+ it is clearly obsolete.
+
+35. Added TLS support for CRLs: a tls_crl global option and one for the smtp
+ transport.
+
+36. OpenSSL: $tls_certificate_verified was being set to 1 even if the
+ client certificate was expired. A simple patch fixes this, though I don't
+ understand the full logic of why the verify callback is called multiple
+ times.
+
+37. OpenSSL: a patch from Robert Roselius: "Enable client-bug workaround.
+ Versions of OpenSSL as of 0.9.6d include a 'CBC countermeasure' feature,
+ which causes problems with some clients (such as the Certicom SSL Plus
+ library used by Eudora). This option, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS,
+ disables the coutermeasure allowing Eudora to connect."
+
+38. Exim was not checking that a write() to a log file succeeded. This could
+ lead to Bad Things if a log got too big, in particular if it hit a file
+ size limit. Exim now panics and dies if it cannot write to a log file, just
+ as it does if it cannot open a log file.
+
+39. Modified OS/Makefile-Linux so that it now contains
+
+ CFLAGS=-O -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
+
+ The two -D definitions ensure that Exim is compiled with large file
+ support, which makes it possible to handle log files that are bigger than
+ 2^31.
+
+40. Fixed a subtle caching bug: if (in an ACL or a set of routers, for
+ instance) a domain was checked against a named list that involved a lookup,
+ causing $domain_data to be set, then another domain was checked against the
+ same list, then the first domain was re-checked, the value of $domain_data
+ after the final check could be wrong. In particular, if the second check
+ failed, it could be set empty. This bug probably also applied to
+ $localpart_data.
+
+41. The strip_trailing_dot option was not being applied to the address given
+ with the -f command-line option.
+
+42. The code for reading a message's header from the spool was incrementing
+ $received_count, but never initializing it. This meant that the value was
+ incorrect (doubled) while delivering a message in the same process in which
+ it was received. In the most common configuration of Exim, this never
+ happens - a fresh exec is done - but it can happen when
+ deliver_drop_privilege is set.
+
+43. When Exim logs an SMTP synchronization error - client data sent too soon -
+ it now includes up to 150 characters of the unexpected data in the log
+ line.
+
+44. The exim_dbmbuild utility uses fixed size buffers for reading input lines
+ and building data strings. The size of both of these buffers was 10 000
+ bytes - far larger than anybody would *ever* want, thought I. Needless to
+ say, somebody hit the limit. I have increased the maximum line length to
+ 20 000 and the maximum data length of concatenated lines to 100 000. I have
+ also fixed two bugs, because there was no checking on these buffers. Tsk,
+ tsk. Now exim_dbmbuild gives a message and exits with an error code if a
+ buffer is too small.
+
+45. The exim_dbmbuild utility did not support quoted keys, as Exim does in
+ lsearch lookups. Now it does.
+
+46. When parsing a route_list item in a manualroute router, a fixed-length
+ buffer was used for the list of hosts. I made this 1024 bytes long,
+ thinking that nobody would ever have a list of hosts that long. Wrong.
+ Somebody had a whole pile of complicated expansion conditions, and the
+ string was silently truncated, leading to an expansion error. It turns out
+ that it is easier to change to an unlimited length (owing to other changes
+ that have happened since this code was originally written) than to build
+ structure for giving a limitation error. The length of the item that
+ expands into the list of hosts is now unlimited.
+
+47. The lsearch lookup could not handle data where the length of text line was
+ more than 4095 characters. Such lines were truncated, leading to shortened
+ data being returned. It should now handle lines of any length.
+
+48. Minor wording revision: "cannot test xxx in yyy ACL" becomes "cannot test
+ xxx condition in yyy ACL" (e.g. "cannot test domains condition in DATA
+ ACL").
+
+49. Cosmetic tidy to scripts like exicyclog that are generated by globally
+ replacing strings such as BIN_DIRECTORY in a source file: the replacement
+ no longer happens in comment lines. A list of replacements is now placed
+ at the head of all of the source files, except those whose only change is
+ to replace PERL_COMMAND in the very first #! line.
+
+50. Replaced the slow insertion sort in queue.c, for sorting the list of
+ messages on the queue, with a bottom-up merge sort, using code contributed
+ by Michael Haardt. This should make operations like -bp somewhat faster on
+ large queues. It won't affect queue runners, except when queue_run_in_order
+ is set.
+
+51. Installed eximstats 1.31 in the distribution.
+
+52. Added support for SRV lookups to the dnslookup router.
+
+53. If an ACL referred to $message_body or $message_body_end, the value was not
+ reset for any messages that followed in the same SMTP session.
+
+54. The store-handling optimization for building very long strings was not
+ differentiating between the different store pools. I don't think this
+ actually made any difference in practice, but I've tidied it.
+
+55. While running the routers to verify a sender address, $sender_address
+ was still set to the sender address. This is wrong, because when routing to
+ send a bounce to the sender, it would be empty. Therefore, I have changed
+ it so that, while verifying a sender address, $sender_address is set to <>.
+ (There is no change to what happens when verifying a recipient address.)
+
+56. After finding MX (or SRV) records, Exim was doing a DNS lookup for the
+ target A or AAAA records (if not already returned) without resetting the
+ qualify_single or search_parents options of the DNS resolver. These are
+ inappropriate in this case because the targets of MX and SRV records must
+ be FQDNs. A broken DNS record could cause trouble if it happened to have a
+ target that, when qualified, matched something in the local domain. These
+ two options are now turned off when doing these lookups.
+
+57. It seems that at least some releases of Reiserfs (which does not have the
+ concept of a fixed number of inodes) returns zero and not -1 for the
+ number of available inodes. This interacted badly with check_spool_inodes,
+ which assumed that -1 was the "no such thing" setting. What I have done is
+ to check that the total number of inodes is greater than zero before doing
+ the test of how many are available.
+
+58. When a "warn" ACL statement has a log_message modifier, the message is
+ remembered, and not repeated. This is to avoid a lot of repetition when a
+ message has many recipients that cause the same warning to be written.
+ Howewer, Exim was preserving the list of already written lines for an
+ entire SMTP session, which doesn't seem right. The memory is now reset if a
+ new message is started.
+
+59. The "rewrite" debugging flag was not showing the result of rewriting in the
+ debugging output unless log_rewrite was also set.
+
+60. Avoid a compiler warning on 64-bit systems in dsearch.c by avoiding the use
+ of (int)(handle) when we know that handle contains (void *)(-1).
+
+61. The Exim daemon panic-logs an error return when it closes the incoming
+ connection. However "connection reset by peer" seems to be common, and
+ isn't really an error worthy of noting specially, so that particular error
+ is no long logged.
+
+62. When Exim is trying to find all the local interfaces, it used to panic and
+ die if the ioctl to get the interface flags failed. However, it seems that
+ on at least one OS (Solaris 9) it is possible to have an interface that is
+ included in the list of interfaces, but for which you get a failure error
+ for this call. This happens when the interface is not "plumbed" into a
+ protocol (i.e. neither IPv4 nor IPv6). I've changed the code so that a
+ failure of the "get flags" call assumes that the interface is down.
+
+63. Added a ${eval10: operator, which assumes all numbers are decimal. This
+ makes life easier for people who are doing arithmetic on fields extracted
+ from dates, where you often get leading zeros that should not be
+ interpreted as octal.
+
+64. Added qualify_domain to the redirect router, to override the global
+ setting.
+
+65. If a pathologically long header line contained very many addresses (the
+ report of this problem mentioned 10 000) and each of them was rewritten,
+ Exim could use up a very large amount of memory. (It kept on making new
+ copies of the header line as it rewrote, and never released the old ones.)
+ At the expense of a bit more processing, the header rewriting function has
+ been changed so that it no longer eats memory in this way.
+
+66. The generation of the Received: header has been moved from the time that a
+ message starts to be received, to the time that it finishes. The timestamp
+ in the Received: header should now be very close to that of the <= log
+ line. There are two side-effects of this change:
+
+ (a) If a message is rejected by a DATA or non-SMTP ACL or local_scan(), the
+ logged header lines no longer include the local Received: line, because
+ it has not yet been created. The same applies to a copy of the message
+ that is returned to a non-SMTP sender when a message is rejected.
+
+ (b) When a filter file is tested using -bf, no additional Received: header
+ is added to the test message. After some thought, I decided that this
+ is a bug fix.
+
+ This change does not affect the value of $received_for. It is still set
+ after address rewriting, but before local_scan() is called.
+
+67. Installed the latest Cygwin-specific files from the Cygwin maintainer.
+
+68. GnuTLS: If an empty file is specified for tls_verify_certificates, GnuTLS
+ gave an unhelpful panic error message, and a defer error. I have managed to
+ change this behaviour so that it now rejects any supplied certificate,
+ which seems right, as the list of acceptable certificates is empty.
+
+69. OpenSSL: If an empty file is specified for tls_verify_certificates, OpenSSL
+ gave an unhelpful defer error. I have not managed to make this reject any
+ supplied certificates, but the error message it gives is "no certificate
+ supplied", which is not helpful.
+
+70. exigrep's output now also includes lines that are not associated with any
+ message, but which match the given pattern. Implemented by a patch from
+ Martin Sluka, which also tidied up the Perl a bit.
+
+71. Recipient callout verification, like sender verification, was using <> in
+ the MAIL FROM command. This isn't really the right thing, since the actual
+ sender may affect whether the remote host accepts the recipient or not. I
+ have changed it to use the actual sender in the callout; this means that
+ the cache record is now keyed on a recipient/sender pair, not just the
+ recipient address. There doesn't seem to be a real danger of callout loops,
+ since a callout by the remote host to check the sender would use <>.
+ [SEE ABOVE: changed after hitting problems.]
+
+72. Exim treats illegal SMTP error codes that do not begin with 4 or 5 as
+ temporary errors. However, in the case of such a code being given after
+ the end of a data transmission (i.e. after ".") Exim was failing to write
+ a retry record for the message. (Yes, there was some broken host that was
+ actually sending 8xx at this point.)
+
+73. An unknown lookup type in a host list could cause Exim to panic-die when
+ the list was checked. (An example that provoked this was putting <; in the
+ middle of a list instead of at the start.) If this happened during a DATA
+ ACL check, a -D file could be left lying around. This kind of configuration
+ error no longer causes Exim to die; instead it causes a defer errror. The
+ incident is still logged to the main and panic logs.
+
+74. Buglet left over from Exim 3 conversion. The message "too many messages
+ in one connection" was written to the rejectlog but not the mainlog, except
+ when address rewriting (yes!) was being logged.
+
+75. Added write_rejectlog option.
+
+76. When a system filter was run not as root (that is, when system_filter_user
+ was set), the values of the $n variables were not being returned to the
+ main process; thus, they were not subsequently available in the $sn
+ variables.
+
+77. Added +return_path_on_delivery log selector.
+
+78. A connection timeout was being treated differently from recipients deferred
+ when testing hosts_max_try with a message that was older than the host's
+ retry timeout. (The host should not be counted, thus allowing all hosts to
+ be tried at least once before bouncing.) This may have been the cause of an
+ occasionally reported bug whereby a message would remain on the queue
+ longer than the retry timeout, but would be bounced if a delivery was
+ forced. I say "may" because I never totally pinned down the problem;
+ setting up timeout/retry tests is difficult. See also the next item.
+
+79. The ultimate address timeout was not being applied to errors that involved
+ a combination of host plus message (for example, a timeout on a MAIL
+ command). When an address resolved to a number of possible hosts, and they
+ were not all tried for each delivery (e.g. because of hosts_max_try), a
+ message could remain on the queue longer than the retry timeout.
+
+80. Sieve bug: "stop" inside "elsif" was broken. Applied a patch from Michael
+ Haardt.
+
+81. Fixed an obscure SMTP outgoing bug which required at least the following
+ conditions: (a) there was another message waiting for the same server;
+ (b) the server returned 5xx to all RCPT commands in the first message so
+ that the message was not completed; (c) the server dropped the connection
+ or gave a negative response to the RSET that Exim sends to abort the
+ transaction. The observed case was a dropped connection after DATA that had
+ been sent in pipelining mode. That is, the server had advertised PIPELINING
+ but was not implementing it correctly. The effect of the bug was incorrect
+ behaviour, such as trying another host, and this could lead to a crash.
+
+
+Exim version 4.30
+-----------------
+
+ 1. The 3rd arguments to getsockname(), getpeername(), and accept() in exim.c
+ and daemon.c were passed as pointers to ints; they should have been
+ pointers to socklen_t variables (which are typically unsigned ints).
+
+ 2. Some signed/unsigned type warnings in the os.c file for Linux have been
+ fixed.
+
+ 3. Fixed a really odd bug that affected only the testing scheme; patching a
+ certain fixed string in the binary changed the value of another string that
+ happened to be identical to the end of the original first string.
+
+ 4. When gethostbyname() (or equivalent) is passed an IP address as a "host
+ name", it returns that address as the IP address. On some operating
+ systems (e.g. Solaris), it also passes back the IP address string as the
+ "host name". However, on others (e.g. Linux), it passes back an empty
+ string. Exim wasn't checking for this, and was changing the host name to an
+ empty string, assuming it had been canonicized.
+
+ 5. Although rare, it is permitted to have more than one PTR record for a given
+ IP address. I thought that gethostbyaddr() or getipnodebyaddr() always gave
+ all the names associated with an address, because they do in Solaris.
+ However, it seems that they do not in Linux for data that comes from the
+ DNS. If an address in /etc/hosts has multiple names, they _are_ all given.
+ I found this out when I moved to a new Linux workstation and tried to run
+ the Exim test suite.
+
+ To get round this problem I have changed the code so that it now does its
+ own call to the DNS to look up PTR records when searching for a host name.
+ If nothing can be found in the DNS, it tries gethostbyaddr(), so that
+ addresses that are only in /etc/hosts are still found.
+
+ This behaviour is, however, controlled by an option called host_lookup_
+ order, which defaults to "bydns:byaddr". If people want to use the other
+ order, or indeed, just use one or the other means of lookup, they can
+ specify it in this variable.
+
+ 6. If a PTR record yields an empty name, Exim treats it as non-existent. In
+ some operating systems, this comes back from gethostbyaddr() as an empty
+ string, and this is what Exim used to test for. However, it seems that in
+ other systems, "." is yielded. Exim now tests for this case too.
+
+ 7. The values of check_spool_space and check_log_space are now held internally
+ as a number of kilobytes instead of an absolute number of bytes. If a
+ numbers is specified without 'K' or 'M', it is rounded up to the nearest
+ kilobyte. This means that much larger values can be stored.
+
+ 8. Exim monitor: an attempt to get the action menu when not actually pointing
+ at a message produces an empty menu entitled "No message selected". This
+ works on Solaris (OpenWindows). However, XFree86 does not like a menu with
+ no entries in it ("Shell widget menu has zero width and/or height"). So I
+ have added a single, blank menu entry in this case.
+
+ 9. Added ${quote_local_part.
+
+10. MIME decoding is now applied to the contents of Subject: header lines when
+ they are logged.
+
+11. Now that a reference to $sender_host_address automatically causes a reverse
+ lookup to occur if necessary (4.13/18), there is no need to arrange for a
+ host lookup before query-style lookups in lists that might use this
+ variable. This has therefore been abolished, and the "net-" prefix is no
+ longer necessary for query-style lookups.
+
+12. The Makefile for SCO_SV contained a setting of LDFLAGS. This appears to
+ have been a typo for LFLAGS, so it has been changed.
+
+13. The install script calls Exim with "-C /dev/null" in order to find the
+ version number. If ALT_CONFIG_PREFIX was set, this caused an error message
+ to be output. Howeve, since Exim outputs its version number before the
+ error, it didn't break the script. It just looked ugly. I fixed this by
+ always allowing "-C /dev/null" if the caller is root.
+
+14. Ignore overlarge ACL variable number when reading spool file - insurance
+ against a later release with more variables having written the file.
+
+15. The standard form for an IPv6 address literal was being rejected by EHLO.
+ Example: [IPv6:2002:c1ed:8229:10:202:2dff:fe07:a42a]. Exim now accepts
+ this, as well as the form without the "IPv6" on the front.
+
+16. Added CHOWN_COMMAND=/usr/sbin/chown and LIBS=-lresolv to the
+ OS/Makefile-Darwin file.
+
+17. Fixed typo in lookups/ldap.c: D_LOOKUP should be D_lookup. This applied
+ only to LDAP libraries that do not have LDAP_OPT_DEREF.
+
+18. After change 4.21/52, "%ld" was used to format the contents of the $inode
+ variable. However, some OS use ints for inodes. I've added cast to long int
+ to get rid of the compiler warning.
+
+19. I had forgotten to lock out "/../" in configuration file names when
+ ALT_CONFIG_PREFIX was set.
+
+20. Routers used for verification do not need to specify transports. However,
+ if such a router generated a host list, and callout was configured, Exim
+ crashed, because it could not find a port number from the (non-existent)
+ transport. It now assumes port 25 in this circumstance.
+
+21. Added the -t option to exigrep.
+
+22. If LOOKUP_LSEARCH is defined, all three linear search methods (lsearch,
+ wildlsearch, nwildlsearch) are compiled. LOOKUP_WILDLSEARCH and LOOKUP_
+ NWILDLSEARCH are now obsolete, but retained for compatibility. If either of
+ them is set, LOOKUP_LSEARCH is forced.
+
+23. "exim -bV" now outputs a list of lookups that are included in the binary.
+
+24. Added sender and host information to the "rejected by local_scan()" log
+ line; previously there was no indication of these.
+
+25. Added .include_if_exists.
+
+26. Change 3.952/11 added an explicit directory sync on top of a file sync for
+ Linux. It turns out that not all file systems support this. Apparently some
+ versions of NFS do not. (It's rare to put Exim's spool on NFS, but people
+ do it.) To cope with this, the error EINVAL, which means that sync-ing is
+ not supported on the file descriptor, is now ignored when Exim is trying to
+ sync a directory. This applies only to Linux.
+
+27. Added -DBIND_8_COMPAT to the CLFAGS setting for Darwin.
+
+28. In Darwin (MacOS X), the PAM headers are in /usr/include/pam and not in
+ /usr/include/security. There's now a flag in OS/os.h-Darwin to cope with
+ this.
+
+29. Added support for maildirsize files from supplied patch (modified a bit).
+
+30. The use of :fail: followed by an empty string could lead Exim to respond to
+ sender verification failures with (e.g.):
+
+ 550 Verification failed for <xxx>
+ 550 Sender verify failed
+
+ where the first response line was missing the '-' that indicates it is not
+ the final line of the response.
+
+31. The loop for finding the name of the user that called Exim had a hardwired
+ limit of 10; it now uses the value of finduser_retries, which is used for
+ all other user lookups.
+
+32. Added $received_count variable, available in data and not_smtp ACLs, and at
+ delivery time.
+
+33. Exim was neglecting to zero errno before one call of strtol() when
+ expanding a string and expecting an integer value. On some systems this
+ resulted in spurious "integer overflow" errors. Also, it was casting the
+ result into an int without checking.
+
+34. Testing for a connection timeout using "timeout_connect" in the retry rules
+ did not work. The code looks as if it has *never* worked, though it appears
+ to have been documented since at least releast 1.62. I have made it work.
+
+35. The "timeout_DNS" error in retry rules, also documented since at least
+ 1.62, also never worked. As it isn't clear exactly what this means, and
+ clearly it isn't a major issue, I have abolished the feature by treating it
+ as "timeout", and writing a warning to the main and panic logs.
+
+36. The display of retry rules for -brt wasn't always showing the error code
+ correctly.
+
+37. Added new error conditions to retry rules: timeout_A, timeout_MX,
+ timeout_connect_A, timeout_connect_MX.
+
+38. Rewriting the envelope sender at SMTP time did not allow it to be rewritten
+ to the empty sender.
+
+39. The daemon was not analysing the content of -oX till after it had closed
+ stderr and disconnected from the controlling terminal. This meant that any
+ syntax errors were only noted on the panic log, and the return code from
+ the command was 0. By re-arranging the code a little, I've made the
+ decoding happen first, so such errors now appear on stderr, and the return
+ code is 1. However, the actual setting up of the sockets still happens in
+ the disconnected process, so errors there are still only recorded on the
+ panic log.
+
+40. A daemon listener on a wildcard IPv6 socket that also accepts IPv4
+ connections (as happens on some IP stacks) was logged at start up time as
+ just listening for IPv6. It now logs "IPv6 with IPv4". This differentiates
+ it from "IPv6 and IPv4", which means that two separate sockets are being
+ used.
+
+41. The debug output for gethostbyname2() or getipnodebyname() failures now
+ says whether AF_INET or AF_INET6 was passed as an argument.
+
+42. Exiwhat output was messed up when time zones were included in log
+ timestamps.
+
+43. Exiwhat now gives more information about the daemon's listening ports,
+ and whether -tls-on-connect was used.
+
+44. The "port" option of the smtp transport is now expanded.
+
+45. A "message" modifier in a "warn" statement in a non-message ACL was being
+ silently ignored. Now an error message is written to the main and panic
+ logs.
+
+46. There's a new ACL modifier called "logwrite" which writes to a log file
+ as soon as it is encountered.
+
+47. Added $local_user_uid and $local_user_gid at routing time.
+
+48. Exim crashed when trying to verify a sender address that was being
+ rewritten to "<>".
+
+49. Exim was recognizing only a space character after ".include". It now also
+ recognizes a tab character.
+
+50. Fixed several bugs in the Perl script that creates the exim.8 man page by
+ extracting the relevant information from the specification. The man page no
+ longer contains scrambled data for the -d option, and I've added a section
+ at the front about calling Exim under different names.
+
+51. Added "extra_headers" argument to the "mail" command in filter files.
+
+52. Redirecting mail to an unqualified address in a Sieve filter caused Exim to
+ crash.
+
+53. Installed eximstats 1.29.
+
+54. Added transport_filter_timeout as a generic transport option.
+
+55. Exim no longer adds an empty Bcc: header to messages that have no To: or
+ Cc: header lines. This was required by RFC 822, but it not required by RFC
+ 2822.
+
+56. Exim used to add From:, Date:, and Message-Id: header lines to any
+ incoming messages that did not have them. Now it does so only if the
+ message originates locally, that is, if there is no associated remote host
+ address. When Resent- header lines are present, this applies to the Resent-
+ lines rather than the non-Resent- lines.
+
+57. Drop incoming SMTP connection after too many syntax or protocol errors. The
+ limit is controlled by smtp_max_synprot_errors, defaulting to 3.
+
+58. Messages for configuration errors now include the name of the main
+ configuration file - useful now that there may be more than one file in a
+ list (.included file names were always shown).
+
+59. Change 4.21/82 (run initgroups() when starting the daemon) causes problems
+ for those rare installations that do not start the daemon as root or run it
+ setuid root. I've cut out the call to initgroups() if the daemon is not
+ root at that time.
+
+60. The Exim user and group can now be bound into the binary as text strings
+ that are looked up at the start of Exim's processing.
+
+61. Applied a small patch for the Interbase code, supplied by Ard Biesheuvel.
+
+62. Added $mailstore_basename variable.
+
+63. Installed patch to sieve.c from Michael Haardt.
+
+64. When Exim failed to open the panic log after failing to open the main log,
+ the original message it was trying to log was written to stderr and debug
+ output, but if they were not available (the usual case in production), it
+ was lost. Now it is written to syslog before the two lines that record the
+ failures to open the logs.
+
+65. Users' Exim filters run in subprocesses under the user's uid. It is
+ possible for a "deliver" command or an alias in a "personal" command to
+ provoke an address rewrite. If logging of address rewriting is configured,
+ this fails because the process is not running as root or exim. There may be
+ a better way of dealing with this, but for the moment (because 4.30 needs
+ to be released), I have disabled address rewrite logging when running a
+ filter in a non-root, non-exim process.
+
+
+Exim version 4.24
+-----------------
+
+ 1. The buildconfig auxiliary program wasn't quoting the value set for
+ HEADERS_CHARSET. This caused a compilation error complaining that 'ISO' was
+ not defined. This bug was masked in 4.22 by the effect that was fixed in
+ change 4.23/1.
+
+ 2. Some messages that were rejected after a message id was allocated were
+ shown as "incomplete" by exigrep. It no longer does this for messages that
+ are rejected by local_scan() or the DATA or non-SMTP ACLs.
+
+ 3. If a Message-ID: header used a domain literal in the ID, and Exim did not
+ have allow_domain_literals set, the ID did not get logged in the <= line.
+ Domain literals are now always recognized in Message-ID: header lines.
+
+ 4. The first argument for a ${extract expansion item is the key name or field
+ number. Leading and trailing spaces in this item were not being ignored,
+ causing some misleading effects.
+
+ 5. When deliver_drop_privilege was set, single queue runner processes started
+ manually (i.e. by the command "exim -q") or by the daemon (which uses the
+ same command in the process it spins off) were not dropping privilege.
+
+ 6. When the daemon running as "exim" started a queue runner, it always
+ re-executed Exim in the spun-off process. This is a waste of effort when
+ deliver_drop_privilege is set. The new process now just calls the
+ queue-runner function directly.
+
+
+Exim version 4.23
+-----------------
+
+ 1. Typo in the src/EDITME file: it referred to HEADERS_DECODE_TO instead of
+ HEADERS_CHARSET.
+
+ 2. Change 4.21/73 introduced a bug. The pid file path set by -oP was being
+ ignored. Though the use of -oP was forcing the writing of a pid file, it
+ was always written to the default place.
+
+ 3. If the message "no IP address found for host xxxx" is generated during
+ incoming verification, it is now followed by identification of the incoming
+ connection (so you can more easily find what provoked it).
+
+ 4. Bug fix for Sieve filters: "stop" inside a block was not working properly.
+
+ 5. Added some features to "harden" Exim a bit more against certain attacks:
+
+ (a) There is now a build-time option called FIXED_NEVER_USERS that can
+ be put in Local/Makefile. This is like the never_users runtime option,
+ but it cannot be overridden. The default setting is "root".
+
+ (b) 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.
+
+ (c) If ALT_CONFIG_ROOT_ONLY is defined in Local/Makefile, root privilege
+ is retained for -C and -D only if the caller of Exim is root. Without
+ it, the exim user may also use -C and -D and retain privilege.
+
+ (d) If DISABLE_D_OPTION is defined in Local/Makefile, the use of the -D
+ command line option is disabled.
+
+ 6. Macro names set by the -D option must start with an upper case letter, just
+ like macro names defined in the configuration file.
+
+ 7. Added "dereference=" facility to LDAP.
+
+ 8. Two instances of the typo "uknown" in the source files are fixed.
+
+ 9. If a PERL_COMMAND setting in Local/Makefile was not at the start of a line,
+ the Configure-Makefile script screwed up while processing it.
+
+10. Incorporated PCRE 4.4.
+
+11. The SMTP synchronization check was not operating right at the start of an
+ SMTP session. For example, it could not catch a HELO sent before the client
+ waited for the greeting. There is now a check for outstanding input at the
+ point when the greeting is written. Because of the duplex, asynchronous
+ nature of TCP/IP, it cannot be perfect - the incorrect input may be on its
+ way, but not yet received, when the check is performed.
+
+12. Added tcp_nodelay to make it possible to turn of the setting of TCP_NODELAY
+ on TCP/IP sockets, because this apparently causes some broken clients to
+ timeout.
+
+13. Installed revised OS/Makefile-CYGWIN and OS/os.c-cygwin (the .h file was
+ unchanged) from the Cygwin maintainer.
+
+14. The code for -bV that shows what is in the binary showed "mbx" when maildir
+ was supported instead of testing for mbx. Effectively a typo.
+
+15. The spa authenticator server code was not checking that the input it
+ received was valid base64.
+
+16. The debug output line for the "set" modifier in ACLs was not showing the
+ name of the variable that was being set.
+
+17. Code tidy: the variable type "vtype_string" was never used. Removed it.
+
+18. Previously, a reference to $sender_host_name did not cause a DNS reverse
+ lookup on its own. Something else was needed to trigger the lookup. For
+ example, a match in host_lookup or the need for a host name in a host list.
+ Now, if $sender_host_name is referenced and the host name has not yet been
+ looked up, a lookup is performed. If the lookup fails, the variable remains
+ empty, and $host_lookup_failed is set to "1".
+
+19. Added "eqi" as a case-independent comparison operator.
+
+20. The saslauthd authentication condition could segfault if neither service
+ nor realm was specified.
+
+21. If an overflowing value such as "2048M" was set for message_size_limit, the
+ error message that was logged was misleading, and incoming SMTP
+ connections were dropped. The message is now more accurate, and temporary
+ errors are given to SMTP connections.
+
+22. In some error situations (such as 21 above) Exim rejects all SMTP commands
+ (except RSET) with a 421 error, until QUIT is received. However, it was
+ failing to send a response to QUIT.
+
+23. The HELO ACL was being run before the code for helo_try_verify_hosts,
+ which made it impossible to use "verify = helo" in the HELO ACL. The HELO
+ ACL is now run after the helo_try_verify_hosts code.
+
+24. "{MD5}" and "{SHA1}" are now recognized as equivalent to "{md5"} and
+ "{sha1}" in the "crypteq" expansion condition (in fact the comparison is
+ case-independent, so other case variants are also recognized). Apparently
+ some systems use these upper case variants.
+
+25. If more than two messages were waiting for the same host, and a transport
+ filter was specified for the transport, Exim sent two messages over the
+ same TCP/IP connection, and then failed with "socket operation on non-
+ socket" when it tried to send the third.
+
+26. Added Exim::debug_write and Exim::log_write for embedded Perl use.
+
+27. The extern definition of crypt16() in expand.c was not being excluded when
+ the OS had its own crypt16() function.
+
+28. Added bounce_return_body as a new option, and bounce_return_size_limit
+ as a preferred synonym for return_size_limit, both as an option and as an
+ expansion variable.
+
+29. Added LIBS=-liconv to OS/Makefile-OSF1.
+
+30. Changed the default configuration ACL to relax the local part checking rule
+ for addresses that are not in any local domains. For these addresses,
+ slashes and pipe symbols are allowed within local parts, but the sequence
+ /../ is explicitly forbidden.
+
+31. SPA server authentication was not clearing the challenge buffer before
+ using it.
+
+32. log_message in a "warn" ACL statement was writing to the reject log as
+ well as to the main log, which contradicts the documentation and doesn't
+ seem right (because no rejection is happening). So I have stopped it.
+
+33. Added Ard Biesheuvel's lookup code for accessing an Interbase database.
+ However, I am unable to do any testing of this.
+
+34. Fixed an infelicity in the appendfile transport. When checking directories
+ for a mailbox, to see if any needed to be created, it was accidentally
+ using path names with one or more superfluous leading slashes; tracing
+ would show up entries such as stat("///home/ph10", 0xFFBEEA48).
+
+35. If log_message is set on a "discard" verb in a MAIL or RCPT ACL, its
+ contents are added to the log line that is written for every discarded
+ recipient. (Previously a log_message setting was ignored.)
+
+36. The ${quote: operator now quotes the string if it is empty.
+
+37. The install script runs exim in order to find its version number. If for
+ some reason other than non-existence or emptiness, which it checks, it
+ could not run './exim', it was installing it with an empty version number,
+ i.e. as "exim-". This error state is now caught, and the installation is
+ aborted.
+
+38. An argument was missing from the function that creates an error message
+ when Exim fails to connect to the socket for saslauthd authentication.
+ This could cause Exim to crash, or give a corrupted message.
+
+39. Added isip, isip4, and isip6 to ${if conditions.
+
+40. The ACL variables $acl_xx are now saved with the message, and can be
+ accessed later in routers, transports, and filters.
+
+41. The new lookup type nwildlsearch is like wildlsearch, except that the key
+ strings in the file are not string-expanded.
+
+42. If a MAIL command specified a SIZE value that was too large to fit into an
+ int variable, the check against message_size_limit failed. Such values are
+ now forced to INT_MAX, which is around 2Gb for a 32-bit variable. Maybe one
+ day this will have to be increased, but I don't think I want to be around
+ when emails are that large.
+
+
+
+Exim version 4.22
+-----------------
+
+ 1. Removed HAVE_ICONV=yes from OS/Makefile-FreeBSD, since it seems that
+ iconv() is not standard in FreeBSD.
+
+ 2. Change 4.21/17 was buggy and could cause stack overwriting on a system with
+ IPv6 enabled. The observed symptom was a segmentation fault on return from
+ the function os_common_find_running_interfaces() in src/os.c.
+
+ 3. In the check_special_case() function in daemon.c I had used "errno" as an
+ argument name, which causes warnings on some systems. This was basically a
+ typo, since it was named "eno" in the comments!
+
+ 4. The code that waits for the clock to tick (at a resolution of some fraction
+ of a second) so as to ensure message-id uniqueness was always waiting for
+ at least one whole tick, when it could have waited for less. [This is
+ almost certainly not relevant at current processor speeds, where it is
+ unlikely to ever wait at all. But we try to future-proof.]
+
+ 5. The function that sleeps for a time interval that includes fractions of a
+ second contained a race. It did not block SIGALRM between setting the
+ timer, and suspending (a couple of lines later). If the interval was short
+ and the sigsuspend() was delayed until after it had expired, the suspension
+ never ended. On busy systems this could lead to processes getting stuck for
+ ever.
+
+ 6. Some uncommon configurations may cause a lookup to happen in a queue runner
+ process, before it forks any delivery processes. The open lookup caching
+ mechanism meant that the open file or database connection was passed into
+ the delivery process. The problem was that delivery processes always tidy
+ up cached lookup data. This could cause a problem for the next delivery
+ process started by the queue runner, because the external queue runner
+ process does not know about the closure. So the next delivery process
+ still has data in the lookup cache. In the case of a file lookup, there was
+ no problem because closing a file descriptor in a subprocess doesn't affect
+ the parent. However, if the lookup was caching a connection to a database,
+ the connection was closed, and the second delivery process was likely to
+ see errors such as "PGSQL: query failed: server closed the connection
+ unexpectedly". The problem has been fixed by closing all cached lookups
+ in a queue runner before running a delivery process.
+
+ 7. Compiler warning on Linux for the second argument of iconv(), which doesn't
+ seem to have the "const" qualifier which it has on other OS. I've
+ parameterised it.
+
+ 8. Change 4.21/2 was too strict. It is only if there are two authenticators
+ *of the same type* (client or server) with the same public name that an
+ error should be diagnosed.
+
+ 9. When Exim looked up a host name for an IP address, but failed to find the
+ original IP address when looking up the host name (a safety check), it
+ output the message "<ip address> does not match any IP for NULL", which was
+ confusing, to say the least. The bug was that the host name should have
+ appeared instead of "NULL".
+
+10. Since release 3.03, if Exim is called by a uid other than root or the Exim
+ user that is built into the binary, and the -C or -D options is used, root
+ privilege is dropped before the configuration file is read. In addition,
+ logging is switched to stderr instead of the normal log files. If the
+ configuration then re-defines the Exim user, the unprivileged environment
+ is probably not what is expected, so Exim logs a panic warning message (but
+ proceeds).
+
+ However, if deliver_drop_privilege is set, the unprivileged state may well
+ be exactly what is intended, so the warning has been cut out in that case,
+ and Exim is allowed to try to write to its normal log files.
+
+
+Exim version 4.21
+-----------------
+
+ 1. smtp_return_error_details was not giving details for temporary sender
+ or receiver verification errors.
+
+ 2. Diagnose a configuration error if two authenticators have the same public
+ name.
+
+ 3. Exim used not to create the message log file for a message until the first
+ delivery attempt. This could be confusing when incoming messages were held
+ for policy or load reasons. The message log file is now created at the time
+ the message is received, and an initial "Received" line is written to it.
+
+ 4. The automatically generated man page for command line options had a minor
+ bug that caused no ill effects; however, a more serious problem was that
+ the procedure for building the man page automatically didn't always
+ operate. Consequently, release 4.20 contains an out-of-date version. This
+ shouldn't happen again.
+
+ 5. When building Exim with embedded Perl support, the script that builds the
+ Makefile was calling 'perl' to find its compile-time parameters, ignoring
+ any setting of PERL_COMMAND in Local/Makefile. This is now fixed.
+
+ 6. The freeze_tell option was not being used for messages that were frozen on
+ arrival, either by an ACL or by local_scan().
+
+ 7. Added the smtp_incomplete_transaction log selector.
+
+ 8. After STARTTLS, Exim was not forgetting that it had advertised AUTH, so it
+ was accepting AUTH without a new EHLO.
+
+ 9. Added tls_remember_esmtp to cope with YAEB. This allows AUTH and other
+ ESMTP extensions after STARTTLS without a new EHLO, in contravention of the
+ RFC.
+
+10. Logging of TCP/IP connections (when configured) now happens in the main
+ daemon process instead of the child process, so that the TCP/IP connection
+ count is more accurate (but it can never be perfect).
+
+11. The use of "drop" in a nested ACL was not being handled correctly in the
+ outer ACL. Now, if condition failure induced by the nested "drop" causes
+ the outer ACL verb to deny access ("accept" or "discard" after "endpass",
+ or "require"), the connection is dropped.
+
+12. Similarly, "discard" in a nested ACL wasn't being handled. A nested ACL
+ that yield "discard" can now be used with an "accept" or a "discard" verb,
+ but an error is generated for any others (because I can't see a useful way
+ to define what should happen).
+
+13. When an ACL is read dynamically from a file (or anywhere else), the lines
+ are now processed in the same way as lines in the Exim configuration file.
+ In particular, continuation lines are supported.
+
+14. Added the "dnslists = a.b.c!=n.n.n.n" feature.
+
+15. Added -ti meaning -t -i.
+
+16. Check for letters, digits, hyphens, and dots in the names of dnslist
+ domains, and warn by logging if others are found.
+
+17. At least on BSD, alignment is not guarenteed for the array of ifreq's
+ returned from GIFCONF when Exim is trying to find the list of interfaces on
+ a host. The code in os.c has been modified to copy each ifreq to an aligned
+ structure in all cases.
+
+ Also, in some cases, the returned ifreq's were being copied to a 'struct
+ ifreq' on the stack, which was subsequently passed to host_ntoa(). That
+ means the last couple of bytes of an IPv6 address could be chopped if the
+ ifreq contained only a normal sockaddr (14 bytes storage).
+
+18. Named domain lists were not supported in the hosts_treat_as_local option.
+ An entry such as +xxxx was not recognized, and was treated as a literal
+ domain name.
+
+19. Ensure that header lines added by a DATA ACL are included in the reject log
+ if the ACL subsequently rejects the message.
+
+20. Upgrade the cramtest.pl utility script to use Digest::MD5 instead of just
+ MD5 (which is deprecated).
+
+21. When testing a filter file using -bf, Exim was writing a message when it
+ took the sender from a "From " line in the message, but it was not doing so
+ when it took $return_path from a Return-Path: header line. It now does.
+
+22. If the contents of a "message" modifier for a "warn" ACL verb do not begin
+ with a valid header line field name (a series of printing characters
+ terminated by a colon, Exim now inserts X-ACL-Warn: at the beginning.
+
+23. Changed "disc" in the source to "disk" to conform to the documentation and
+ the book and for uniformity.
+
+24. Ignore Sendmail's -Ooption=value command line item.
+
+25. When execve() failed while trying to run a command in a pipe transport,
+ Exim was returning EX_UNAVAILBLE (69) from the subprocess. However, this
+ could be confused with a return value of 69 from the command itself. This
+ has been changed to 127, the value the shell returns if it is asked to run
+ a non-existent command. The wording for the related log line suggests a
+ non-existent command as the problem.
+
+26. If received_header_text expands to an empty string, do not add a Received:
+ header line to the message. (Well, it adds a token one on the spool, but
+ marks it "old" so that it doesn't get used or transmitted.)
+
+27. Installed eximstats 1.28 (addition of -nt option).
+
+28. There was no check for failure on the call to getsockname() in the daemon
+ code. This can fail if there is a shortage of resources on the system, with
+ ENOMEM, for example. A temporary error is now given on failure.
+
+29. Contrary to the C standard, it seems that in some environments, the
+ equivalent of setlocale(LC_ALL, "C") is not obeyed at the start of a C
+ program. Exim now does this explicitly; it affects the formatting of
+ timestamps using strftime().
+
+30. If exiqsumm was given junk data, it threw up some uninitialized variable
+ complaints. I've now initialized all the variables, to avoid this.
+
+32. Header lines added by a system filter were not being "seen" during
+ transport-time rewrites.
+
+33. The info_callback() function passed to OpenSSL is set up with type void
+ (*)(SSL *, int, int), as described somewhere. However, when calling the
+ function (actually a macro) that sets it up, the type void(*)() is
+ expected. I've put in a cast to prevent warnings from picky compilers.
+
+34. If a DNS black list lookup found a CNAME record, but there were no A
+ records associated with the domain it pointed at, Exim crashed.
+
+35. If a DNS black list lookup returned more than one A record, Exim ignored
+ all but the first. It now scans all returned addresses if a particular IP
+ value is being sought. In this situation, the contents of the
+ $dnslist_value variable are a list of all the addresses, separated by a
+ comma and a space.
+
+36. Tightened up the rules for host name lookups using reverse DNS. Exim used
+ to accept a host name and all its aliases if the forward lookup for any of
+ them yielded the IP address of the incoming connection. Now it accepts only
+ those names whose forward lookup yields the correct IP address. Any other
+ names are discarded. This closes a loophole whereby a rogue DNS
+ administrator could create reverse DNS records to break through a
+ wildcarded host restriction in an ACL.
+
+37. If a user filter or a system filter that ran in a subprocess used any of
+ the numerical variables ($1, $2 etc), or $thisaddress, in a pipe command,
+ the wrong values were passed to the pipe command ($thisaddress had the
+ value of $0, $0 had the value of $1, etc). This bug was introduced by
+ change 4.11/101, and not discovered because I wrote an inadequate test. :-(
+
+38. Improved the line breaking for long SMTP error messages from ACLs.
+ Previously, if there was no break point between 40 and 75 characters, Exim
+ left the rest of the message alone. Two changes have been made: (a) I've
+ reduced the minimum length to 35 characters; (b) if it can't find a break
+ point between 35 and 75 characters, it looks ahead and uses the first one
+ that it finds. This may give the occasional overlong line, but at least the
+ remaining text gets split now.
+
+39. Change 82 of 4.11 was unimaginative. It assumed the limit on the number of
+ file descriptors might be low, and that setting 1000 would always raise it.
+ It turns out that in some environments, the limit is already over 1000 and
+ that lowering it causes trouble. So now Exim takes care not to decrease it.
+
+40. When delivering a message, the value of $return_path is set to $sender_
+ address at the start of routing (routers may change the value). By an
+ oversight, this default was not being set up when an address was tested by
+ -bt or -bv, which affected the outcome if any router or filter referred to
+ $return_path.
+
+41. The idea of the "warn" ACL verb is that it adds a header or writes to the
+ log only when "message" or "log_message" are set. However, if one of the
+ conditions was an address verification, or a call to a nested ACL, the
+ messages generated by the underlying test were being passed through. This
+ no longer happens. The underlying message is available in $acl_verify_
+ message for both "message" and "log_message" expansions, so it can be
+ passed through if needed.
+
+42. Added RFC 2047 interpretation of header lines for $h_ expansions, with a
+ new expansion $bh_ to give the encoded byte string without charset
+ translation. Translation happens only if iconv() is available; HAVE_ICONV
+ indicates this at build time. HEADERS_CHARSET gives the charset to
+ translate to; headers_charset can change it in the configuration, and
+ "headers charset" can change it in an individual filter file.
+
+43. Now that we have a default RFC 2047 charset (see above), the code in Exim
+ that creates RFC 2047 encoded "words" labels them as that charset instead
+ of always using iso-8859-1. The cases are (i) the explicit ${rfc2047:
+ expansion operator; (ii) when Exim creates a From: line for a local
+ message; (iii) when a header line is rewritten to include a "phrase" part.
+
+44. Nasty bug in exiqsumm: the regex to skip already-delivered addresses was
+ buggy, causing it to skip the first lines of messages whose message ID
+ ended in 'D'. This would not have bitten before Exim release 4.14, because
+ message IDs were unlikely to end in 'D' before then. The effect was to have
+ incorrect size information for certain domains.
+
+45. #include "config.h" was missing at the start of the crypt16.c module. This
+ caused trouble on Tru64 (aka OSF1) systems, because HAVE_CRYPT16 was not
+ noticed.
+
+46. If there was a timeout during a "random" callout check, Exim treated it as
+ a failure of the random address, and carried on sending RSET and the real
+ address. If the delay was just some slowness somewhere, the response to the
+ original RCPT would be taken as a response to RSET and so on, causing
+ mayhem of various kinds.
+
+47. Change 50 for 4.20 was a heap of junk. I don't know what I was thinking
+ when I implemented it. It didn't allow for the fact that some option values
+ may legitimatetly be negative (e.g. size_addition), and it didn't even do
+ the right test for positive values.
+
+48. Domain names in DNS records are case-independent. Exim always looks them up
+ in lower case. Some resolvers return domain names in exactly the case they
+ appear in the zone file, that is, they may contain uppercase letters. Not
+ all resolvers do this - some return always lower case. Exim was treating a
+ change of case by a resolver as a change of domain, similar to a widening
+ of a domain abbreviation. This triggered its re-routing code and so it was
+ trying to route what was effectively the same domain again. This normally
+ caused routing to fail (because the router wouldn't handle the domain
+ twice). Now Exim checks for this case specially, and just changes the
+ casing of the domain that it ultimately uses when it transmits the message
+ envelope.
+
+49. Added Sieve (RFC 3028) support, courtesy of Michael Haardt's contributed
+ module.
+
+50. If a filter generated a file delivery with a non-absolute name (possible if
+ no home directory exists for the router), the forbid_file option was not
+ forbidding it.
+
+51. Added '&' feature to dnslists, to provide bit mask matching in addition to
+ the existing equality matching.
+
+52. Exim was using ints instead of ino_t variables in some places where it was
+ dealing with inode numbers.
+
+53. If TMPDIR is defined in Local/Makefile (default in src/EDITME is
+ TMPDIR="/tmp"), Exim checks for the presence of an environment variable
+ called TMPDIR, and if it finds it is different, it changes its value.
+
+54. The smtp_printf() function is now made available to local_scan() so
+ additional output lines can be written before returning. There is also an
+ smtp_fflush() function to enable the detection of a dropped connection.
+ The variables smtp_input and smtp_batched_input are exported to
+ local_scan().
+
+55. Changed the default runtime configuration: the message "Unknown user"
+ has been removed from the ACL, and instead placed on the localuser router,
+ using the cannot_route_message feature. This means that any verification
+ failures that generate their own messages won't get overridden. Similarly,
+ the "Unrouteable address" message that was in the ACL for unverifiable
+ relay addresses has also been removed.
+
+56. Added hosts_avoid_esmtp to the smtp transport.
+
+57. The exicyclog script was not checking for the esoteric option
+ CONFIGURE_FILE_USE_EUID in the Local/Makefile. It now does this, but it
+ will work only if exicyclog is run under the appropriate euid.
+
+58. Following a discussion on the list, the rules by which Exim recognises line
+ endings on incoming messages have been changed. The -dropcr and drop_cr
+ options are now no-ops, retained only for backwards compatibility. The
+ following line terminators are recognized: LF CRLF CR. However, special
+ processing applies to CR:
+
+ (i) The sequence CR . CR does *not* terminate an incoming SMTP message,
+ nor a local message in the state where . is a terminator.
+
+ (ii) If a bare CR is encountered in a header line, an extra space is added
+ after the line terminator so as not to end the header. The reasoning
+ behind this is that bare CRs in header lines are most likely either
+ to be mistakes, or people trying to play silly games.
+
+59. The size of a message, as listed by "-bp" or in the Exim monitor window,
+ was being incorrectly given as 18 bytes larger than it should have been.
+ This is a VOB (very old bug).
+
+60. This may never have affected anything current, but just in case it has:
+ When the local host is found other than at the start of a list of hosts,
+ the local host, those with the same MX, and any that follow, are discarded.
+ When the list in question was part of a longer list of hosts, the following
+ hosts (not currently being processed) were also being discarded. This no
+ longer happens. I'm not sure if this situation could ever has previously
+ arisen.
+
+61. Added the "/MX" feature to lists of hosts in the manualroute and query
+ program routers.
+
+62. Whenever Exim generates a new message, it now adds an Auto-Submitted:
+ header. This is something that is recommended in a new Internet Draft, and
+ is something that is documented as being done by Sendmail. There are two
+ possible values. For messages generated by the autoreply transport, Exim
+ adds:
+
+ Auto-Submitted: auto-replied
+
+ whereas for all other generated messages (e.g. bounces) it adds
+
+ Auto-Submitted: auto-generated
+
+63. The "personal" condition in filters now includes a test for the
+ Auto-Submitted: header. If it contains the string "auto-" the message it
+ not considered personal.
+
+64. Added rcpt_include_affixes as a generic transport option.
+
+65. Added queue_only_override (default true).
+
+66. Added the syslog_duplication option.
+
+67. If what should have been the first header line of a message consisted of
+ a space followed by a colon, Exim was mis-interpreting it as a header line.
+ It isn't of course - it is syntactically invalid and should therefore be
+ treated as the start of the message body. The misbehaviour could have
+ caused a number of strange effects, including loss of data in subsequent
+ header lines, and spool format errors.
+
+68. Formerly, the AUTH parameter on a MAIL command was trusted only if the
+ client host had authenticated. This control can now be exercised by an ACL
+ for more flexibility.
+
+69. By default, callouts do not happen when testing with -bh. There is now a
+ variant, -bhc, which does actually run the callout code, including
+ consulting and updating the callout cache.
+
+70. Added support for saslauthd authentication, courtesy of Alexander
+ Sabourenkov.
+
+71. If statvfs() failed on the spool or log directories while checking their
+ size for availability, Exim confusingly gave the error "space shortage".
+ Furthermore, in debugging mode it crashed with a floating point exception.
+ These checks are done if check_{spool,log}_{space,inodes} are set, and when
+ an SMTP message arrives with SIZE= on the MAIL command. As this is a really
+ serious problem, Exim now writes to the main and panic logs when this
+ happens, with details of the failure. It then refuses to accept the
+ incoming message, giving the message "spool directory problem" or "log
+ directory problem" with a 421 code for SMTP messages.
+
+72. When Exim is about to re-exec itself, it ensures that the file descriptors
+ 0, 1, and 2 exist, because some OS complain for execs without them (see
+ ChangeLog 4.05/30). If necessary, Exim opens /dev/null to use for these
+ descriptors. However, the code omitted to check that the open succeeded,
+ causing mysterious errors if for some reason the permissions on /dev/null
+ got screwed. Now Exim writes a message to the main and panic logs, and
+ bombs out if it can't open /dev/null.
+
+73. Re-vamped the way daemon_smtp_port, local_interfaces, and -oX work and
+ interact so that it is all more flexible. It is supposed to remain
+ backwards compatible. Also added extra_local_interfaces.
+
+74. Invalid data sent to a SPA (NTLM) server authenticator could cause the code
+ to bomb out with an assertion failure - to the client this appears as a
+ connection drop. This problem occurs in the part of the code that was taken
+ from the Samba project. Fortunately, the assertion is in a very simple
+ function, so I have fixed this by reproducing the function inline in the
+ one place where it is called, and arranging for authentication to fail
+ instead of killing the process with assert().
+
+75. The SPA client code was not working when the server requested OEM rather
+ than Unicode encoding.
+
+76. Added code to make require_files with a specific uid setting more usable in
+ the case where statting the file as root fails - usually a non-root-mounted
+ NFS file system. When this happens and the failure is EACCES, Exim now
+ forks a subprocess and does the per-uid checking as the relevant uid.
+
+77. Added process_log_path.
+
+78. If log_file_path was not explicitly set, a setting of check_log_space or
+ check_log_inodes was ignored.
+
+79. If a space check for the spool or log partitions fails, the incident is now
+ logged. Of course, in the latter case the data may get lost...
+
+80. Added the %p formatting code to string_format() so that it can be used to
+ print addresses in debug_print(). Adjusted all the address printing in the
+ debugging in store.c to use %p rather than %d.
+
+81. There was a concern that a line of code in smtp_in.c could overflow a
+ buffer if a HELO/EHLO command was given followed by 500 or so spaces. As
+ initially expressed, the concern was not well-founded, because trailing
+ spaces are removed early. However, if the trailing spaces were followed by
+ a NULL, they did not get removed, so the overflow was possible. Two fixes
+ were applied:
+
+ (a) I re-wrote the offending code in a cleaner fashion.
+ (b) If an incoming SMTP command contains a NULL character, it is rejected
+ as invalid.
+
+82. When Exim changes uid/gid to the Exim user at daemon start time, it now
+ runs initgroups(), so that if the Exim user is in any additional groups,
+ they will be used during message reception.
+
+
+Exim version 4.20
+-----------------
+
+The change log for 4.20 and earlier releases has been archived.
+
+****
diff --git a/doc/doc-txt/ChangeLog.0 b/doc/doc-txt/ChangeLog.0
new file mode 100644
index 000000000..a2377907c
--- /dev/null
+++ b/doc/doc-txt/ChangeLog.0
@@ -0,0 +1,2862 @@
+$Cambridge: exim/doc/doc-txt/ChangeLog.0,v 1.1 2004/10/07 15:04:35 ph10 Exp $
+
+Change log file for Exim from version 3.951 to 4.20
+---------------------------------------------------
+
+
+Exim version 4.20
+-----------------
+
+ 1. If data for an authentication interaction was just the string "=",
+ indicating an empty string, Exim was not setting up the numerical variable
+ correctly. In some situations, this could cause a crash - in others, it
+ might have passed unnoticed.
+
+ 2. Changed signal(SIGTERM, command_sigterm_handler) in smtp_in.c to use
+ os_non_restarting_signal() for tidiness; in practice this doesn't actually
+ matter because the handler terminates the process.
+
+ 3. Refactoring:
+
+ (a) In some (but not all) places where Exim applies timers using alarm(),
+ it was resetting the SIGALRM handler afterwards, but sometimes to
+ SIG_IGN and sometimes to SIG_DFL. In other words, it was a mess. In
+ fact, this reset is not necessary, because after alarm(0) there is no
+ possibility of receiving a SIGLARM signal. So I've just removed them
+ all.
+
+ (b) The daemon.c module had its own SIGALRM handler, which was unnecessary.
+ I changed it to use the handler that is used (almost) everywhere else.
+
+ (c) Almost all uses of SIGALRM use the same handler, but it was being set
+ by signal() all over the place. Now it is set at the start, and it
+ resets itself every time it is called, so it remains enabled
+ throughout. The few places that use a different handler reset to the
+ "standard" one afterwards.
+
+ (d) The setting of the SIGTERM handler while reading SMTP commands was done
+ somwhat untidily. I have re-arranged the code.
+
+ 4. If the building process was interrupted during the MakeLinks script, a
+ subsequent run of 'make' gave misleading errors. I've made it a bit more
+ robust against this case. If there appears to be a half-made set of links,
+ an error message suggests that the user should remove the build directory
+ and start again.
+
+ 5. For compatibility with other MTAs, -f "" is now accepted as synonymous with
+ -f "<>".
+
+ 6. Upgraded to PCRE 4.1.
+
+ 7. If a domain list contained @mx_any, or @mx_secondary, and the DNS contained
+ secondary MX records for a domain, but all the other MX (higher priority)
+ records pointed to non-existent hosts, Exim was behaving as if the domain
+ did not match the list item. This has been fixed.
+
+ 8. Upgraded eximstats to 1.27.
+
+ 9. It was reported that change 4.14/46(b) caused problems on some systems with
+ older libraries. There is now an option that can be set in Local/Makefile
+ (or in a operating system Makefile):
+
+ IPV6_USE_INET_PTON=yes
+
+ If this is done, Exim reverts to using inet_pton() to convert a textual
+ IPv6 address for actual use, instead of getaddrinfo(), as it did in
+ versions before 4.14. Of course, this means that the additional
+ functionality of getaddrinfo() - recognizing scoped addresses - is lost.
+
+10. Update for PostgreSQL to match 4.14/14: after an insert, delete, or update
+ command, the result is the number of rows affected.
+
+11. If smtp_banner expanded to an empty string, no greeting line was sent, thus
+ causing the client to time out. An empty 220 response is now sent.
+
+12. An empty argument was logged as a null string by the "arguments" log
+ selector. Now empty strings and arguments that contain whitespace are
+ surrounded by quotes.
+
+13. The "arguments" log selector now also logs the current working directory
+ when Exim is called.
+
+14. Added a couple more debugging calls to tls-openssl.
+
+15. Changed the name of the global variable ldap_version because some LDAP
+ library uses the same name, which causes a clash. It's now called
+ eldap_version. While I was at it, I changed the other two global variables,
+ ldap_default_servers and ldap_dn.
+
+16. If an address that is verified in an ACL is redirected to a single address,
+ Exim verifies the child (this is not new). However, the value of $address_
+ data that was being returned was the value from the parent. It is now the
+ value from the child.
+
+17. Re-arranged the code for rda_is_filter() to make it easier to add other
+ filter types in future.
+
+18. Removed the filter test function from filter.c and put it into its own
+ source file, again to make things easier for multiple filter types.
+
+19. To help those people who are maintaining a patch for dynamically loaded
+ local_scan() functions, I have added
+
+ #define LOCAL_SCAN_ABI_VERSION_MAJOR 1
+ #define LOCAL_SCAN_ABI_VERSION_MINOR 0
+
+ to the local_scan.h file.
+
+20. The variables $tls_certificate_verified, $tls_cipher, and $tls_peerdn now
+ exist even when Exim is not compiled with TLS support.
+
+21. If an empty user name was sent by a client for a LOGIN authentication, it
+ was not put into $1; instead, the password ended up in $1 (instead of in
+ $2).
+
+22. When creating a temporary file in the appendfile transport for a per-file
+ delivery not in maildir or mailstore format (that is, in the old Smail
+ format - I wonder if anyone uses this?), Exim was opening the file without
+ O_EXCL, which is a bit unsafe.
+
+23. The output from the ${stat: expansion operator was being formatted using %d
+ which expects an integer; in many (most) systems size_t is off_t, which
+ is actually a long or even a longlong, and in some cases this caused
+ incorrect data to be output. The formatting is now done using %ld, with the
+ values all explicitly cast to (long).
+
+24. Callout caching was failing to cache a negative response to a "random"
+ address check.
+
+25. If a daemon was started with -qsomething and not -bd, and deliver_drop_
+ privilege was set, and a pid file was specified with -oP, and the pid file
+ did not previously exist, it was created with owner exim instead of owner
+ root.
+
+26. verify=sender was not being allowed in a non-SMTP ACL.
+
+27. Under some error conditions, the socket used for ident calls could be left
+ open.
+
+28. Added acl_smtp_helo, because some people seem to want it.
+
+29. For hosts that match helo_verify_hosts, the error given when a MAIL command
+ is received without HELO or EHLO has been changed from 550 to 503 (which
+ means "bad sequence of commands").
+
+30. Installed PCRE 4.2.
+
+31. The quota_size_regex option for the appendfile transport was broken in that
+ a terminating zero was omitted from the string that was extracted for the
+ size. If it happened that digits followed in the memory to which it was
+ copied, an incorrect (too large) size was then used.
+
+32. Change 4.14/32 (iv) introduced a bug in the case when the "phrase" part of
+ a rewritten address did *not* contain any special characters. The
+ generated address was mangled.
+
+33. Several items of refactoring from Michael Haardt:
+
+ . Introduction of "const" in a number of places
+ . Use memcpy() instead of strncpy() in string_cat()
+ . Add HAVE_ICONV to Linux file, for external users (Exim doesn't use it)
+ [Later: From 4.21, Exim *does* use it.]
+ . Preparation for adding additional types of filter file
+
+34. Changed (incompatibly, but hopefully not so it affects anyone) the
+ appendfile transport in the case when it is called directly as a result of
+ a .forward or a filter file requesting a delivery to a file. Previously,
+ any settings of "file" or "directory" were ignored in this case. Now they
+ are used. The path received from the router is in $address_file (as
+ before) and can therefore be included in the expansion.
+
+35. If a "save" command in a filter specifies a non-absolute path, the value of
+ $home/ is pre-pended. This no longer happens if $home is unset or is an
+ empty string. It is expected that the transport will complete the path (see
+ 34 above). If there is an error before the path is complete, the local part
+ is logged as "save xxxx".
+
+36. If multiple "to file" deliveries are routed to the same transport, no
+ batching ever takes place, whatever the value of batch_max.
+
+37. If an address was redirected to an unqualified local part preceded by a
+ backslash, Exim was qualifying it with the qualify_domain, instead of with
+ the incoming domain.
+
+38. Minor rewording: header lines can be added by MAIL as well as RCPT: the
+ debug line mentioned only RCPT.
+
+39. DESTDIR is the more common variable that ROOT for use when installing
+ software under a different root filing system. The Exim install script now
+ recognizes DESTDIR first; if it is not set, ROOT is used.
+
+40. If DESTDIR is set when installing Exim, it no longer prepends its value to
+ the path of the system aliases file that appears in the default
+ configuration (when a default configuration is installed). If an aliases
+ file is actually created, its name *does* use the prefix.
+
+41. If an item in log_file_path was an empty string, Exim wrote the log to the
+ log directory in the spool directory. Now it takes notice of the
+ setting of LOG_FILE_PATH in Local/Makefile, and uses the first non-empty,
+ non-"syslog" item from that list. If there are none, it uses the ultimate
+ default of the spool directory.
+
+42. If there is a Reply-to: header line, but it is empty, $reply_address now
+ contains the From: address instead of being empty.
+
+43. Added -no-cpp-precomp to CFLAGS in OS/Makefile-Darwin. Without this, the
+ compiler provides a string for __DATE__ that does not conform to the
+ specification in the C standard. The option disables precompiled headers,
+ which should not have any bad effects, as pre-compiled headers are
+ supposedly just a performance enhancement at compile time.
+
+44. Refactoring: as there is now a flag that specifies whether or not a home
+ directory that is passed with an address is already expanded, we no longer
+ need the \N...\N fudge for home directories extracted from the password
+ data.
+
+45. Fixed an infelicity introduced by 4.14/71: The defaulting of the prefix,
+ suffix, and check string stuff in appendfile was happening when no
+ directory was supplied. Now it happens if no directory is supplied AND
+ maildir has not been specified.
+
+46. If expansion of the serverpassword in a spa authenticator or expansion of
+ server_condition in a plaintext authenticator is forced to fail,
+ authentication now fails (previously it gave a temporary error, which is
+ what happens for other expansion failures). This brings these
+ authenticators into line with cram_md5, where expansion of server_secret
+ has always behaved like this.
+
+46. Added new syslog facilities (courtesy Oliver Gorwits):
+
+ (i) SYSLOG_LOGS_PID and LONG_SYSLOG_LINES in src/EDITME.
+ (ii) syslog_facility and syslog_processname main options.
+
+47. Callout was using only the hosts from the router, ignoring the transport.
+ This has been changed. If (a) the router does not set up hosts (e.g. it's
+ an accept router) or (b) the smtp transport that is routed to has
+ hosts_override set, then the transport's hosts are used for callout
+ checking.
+
+48. When named lists were nested, and an inner list was resolved by a lookup
+ that saved data for, e.g. $domain_data, the data was associated with just
+ the outer list, though both were cached, so if a subsequent test was done
+ for the inner list, there was no domain data. Example:
+ domainlist A = lsearch;/a/b
+ domainlist B = lsearch;/c/d
+ domainlist C = +A : +B
+ A test on +C that matched, followed by a test on +A or +B would provoke
+ this bug. Now the data is saved with both the inner and the outer lists.
+
+49. When the log selector +address_rewrite is turned on, the log lines now
+ show where the rewritten address came from (which header line, envelope
+ field, or an SMTP command).
+
+50. If an integer or fixed point configuration value is too big to fit in
+ a 32-bit int, Exim now writes an error to the panic log and dies.
+
+51. Unknown SMTP commands are now assumed to be ones that need synchronization;
+ this means that a packet that contains more than one of them will cause the
+ connection to be dropped as soon as the first one is encountered.
+
+52. The "control" feature of ACLs was not permitted for the MAIL ACL (an
+ oversight). It now is allowed.
+
+53. Added the "discard" verb to ACLs.
+
+54. Fixed a theoretical bug observed by reading the code: if local_scan()
+ changed the number of recipients, output from the received_recipients log
+ selector would be incorrect.
+
+55. Added HAVE_ICONV to the os.h files for Linux, Solaris, HP-UX. This is for
+ use in the forthcoming Sieve addition to Exim.
+
+56. The behaviour of -t in the presence of Resent- headers has been changed,
+ for compability with Sendmail and other MTAs. Previously, Exim gave an
+ error, because it is not clear from RFC 2822 how this might be handled. It
+ turns out that MUAs don't seem to follow what RFC 2822 says, and any MUA
+ that uses -t with Resent- ensures that there is only one set of Resent-
+ header lines (usually by renaming others to X-Resent-xxx). So now Exim will
+ take recipients from all the Resent- header lines instead of the usual
+ ones.
+
+
+Exim version 4.14
+-----------------
+
+ 1. Found another case where SIGCHLD is being ignored (a child process for
+ handling a filter file) and so the wait() doesn't find the subprocess. This
+ came to light as a result of extra logging introduced as part of the
+ 4.12/14 fix. Now Exim is careful to set SIGCHLD handling to its default
+ (i.e. to be noticed) for this particular subprocess. (It already has this
+ code for other cases where it uses subprocesses.)
+
+ 2. If ${run appeared in part of a conditional item that was being skipped, the
+ actual running of the command was not being skipped.
+
+ 3. A bit of code tidying (refactoring): there were two functions that built
+ strings containing a host name and ident value for logging. There is now
+ only one. It is called in some additional places where previously just the
+ host name and address were given, so the wording of some log lines has
+ changed slightly.
+
+ 4. Added support for Unix domain socket connection to PostgreSQL.
+
+ 5. The number of unknown SMTP commands that Exim will accept before dropping
+ a connection can now be changed by smtp_max_unknown_commands. The default
+ value is 3. Previously, a fixed value of 5 was used. The final command is
+ now included in the log line.
+
+ 6. The standard place for chown and chgrp in Linux is /bin, not /usr/bin, as
+ assumed by the exicyclog script. I've implemented a "look for it" feature
+ that makes exicyclog look in /bin, /usr/bin, /usr/sbin, and /usr/etc for
+ the commands chown, chgrp, mv, and rm if configured, and turned on this
+ feature for Linux. This should cope with old Linuxes that use /usr/bin.
+
+ 7. Implemented .ifdef etc.
+
+ 8. Installed signal handlers for SIGSEGV, SIGILL, SIGFPE, and SIGBUS while
+ running local_scan(), so that crashes therein get caught. A temporary error
+ response is sent for an SMTP message, and the spool is cleaned up.
+ Previously, a -D file was left lying around if there was a crash in
+ local_scan().
+
+ 9. The ${quote: operator has been changed so that it turns newline and
+ carriage return characters into \n and \r, respectively.
+
+10. Added support for crypt16().
+
+11. Some restrictions on the use of "verify" in ACLs were too restrictive, and
+ have been relaxed. In particular, "verify = sender" is now permitted in the
+ ACL for the MAIL command, as well as those for RCPT and DATA.
+
+12. If local_scan() sets up recipient or errors_to addresses that are
+ unqualified (local parts without a domain) Exim now qualifies them using
+ the qualify_recipient domain.
+
+13. White space at the start of continuation lines in -be input was not being
+ ignored.
+
+14. Previously, if a MySQL query was issued that did not request any data (an
+ insert, update, or delete command), Exim gave a lookup error and deferred.
+ This case is now recognized, and the result of the lookup is now the number
+ of rows affected.
+
+15. A configuration error is given if tls_try_verify_hosts is set and
+ tls_verify_certificates is not set. (Exim already did this for
+ tls_verify_hosts.)
+
+16. Exim was trying to create a non-existent hints database even when it was
+ just opening it for reading. It called the creating function with the
+ O_RDONLY and O_CREAT flags. This works with many DB libraries, but it
+ not with DB 1.85, where a subsequent attempt to use the database gave the
+ error "Inappropriate file type or format". Exim now creates hints databases
+ only when it wants to open them for writing.
+
+17. If an ACL condition test set a default "message" value without a
+ "log_message" value, and there were no overriding messages in the ACL
+ itself, no message was logged. The user message is now logged.
+
+18. If callout made a connection, but it was dropped before the initial
+ welcome response was received, Exim logged "response to initial connection
+ was" with no further text. It now logs that the connection was dropped.
+ The wording of the logging for callout defers has been slightly changed so
+ as to reduce duplication.
+
+19. When multiple messages were sent using TLS over one connection, the
+ additional required EHLO that follows STARTTLS was being counted as a
+ nonmail command, and thus causing a problem if there were a lot of
+ messages. Similarly, a new AUTH that followed STARTTLS was being counted.
+ It is now possible to run with smtp_accept_max_nonmail set to zero in these
+ and other "normal" circumstances.
+
+20. During verify=sender, global rewriting rules are applied to the sender
+ address, and if it changes, $sender_address becomes the rewritten version.
+ Unfortunately, it was not getting updated until after the routers had been
+ run, so that if a router referred to $sender_address while verifying a
+ sender, the unrewritten value was used.
+
+21. The "random address" callout test was being done after the other tests.
+ This is silly, because if the host accepts all local parts, there isn't any
+ point in doing the other, more specific, tests. I changed things around so
+ that the "random" test (if configured) is done first.
+
+22. Expanded the wording for callout failures when MAIL FROM:<> or RCPT TO the
+ a postmaster address are rejected. Also include these words when a
+ rejection happens because of caching (when there isn't an actual SMTP
+ command/result to reflect).
+
+23. A new router condition called "address_test" (default true) can be used to
+ skip routers when testing addresses using -bt (compare no_verify). This can
+ be a convenience when your first router sends stuff to an external scanner.
+
+24. Testing for deliver_queue_load_max was happening inside the delivery
+ sub-process, when it could have happened outside, in the queue runner (thus
+ saving one process). This was a hangover from Exim 3, where there were
+ other load tests to be done. The code has been tidied.
+
+25. Code tidy: the driver_info generic structure contained a field that
+ might, on 64-bit systems, not have been compatible with the fields in the
+ structures of which it is supposed to be a subset. It turns out that this
+ field and another are not actually used generically, so removing them from
+ the structure solves the problem.
+
+26. Added server_advertise_condition to authenticators.
+
+27. The exim_checkaccess utility wasn't sending a HELO command; this matters
+ now that it's possible to have an ACL that checks HELO/EHLO.
+
+27. Added the ldap_version option to force a specific LDAP version.
+
+28. Renamed the variable verify_address in exim.c as verify_address_mode,
+ because it had the same name as the verify_address() function, which was
+ confusing.
+
+29. Added authenticated_sender to the smtp transport.
+
+30. When the skip_syntax_errors option is applied to a filter file, it covers
+ all filtering errors, some of which may not be strictly "syntax" (for
+ example, failure to open a log file). The wording of the message has been
+ changed to use "error" instead of "syntax error", to reduce confusion. Also
+ the subject of the message sent by syntax_errors_to is now "error(s) in
+ forwarding or filtering" instead of "syntax error(s) in address expansion".
+
+31. Added -restore-times to the exim_lock utility.
+
+32. Changes to the handling of the "phrase" parts of email addresses:
+
+ (i) Re-organized the code to use a supplied instead of an implied buffer,
+ and a length instead of expecting a terminated string.
+
+ (ii) Changed from using the macro mac_isprint() to an explicit test for
+ ASCII non-printing characters, because the macro pays attention to
+ print_topbitchars, which is not correct here.
+
+ (iii) If a rewritten address contained a "phrase" (whether or not the "w"
+ flag was present on the rewrite rule), but the actual address was
+ unqualified (had no domain) and was expected to be qualified by the
+ "Q" flag, Exim screwed up and created an illegal address.
+
+ (iv) When a header address is rewritten by a rule that includes the "w"
+ flag, the parts of the address outside <> are now encoded according
+ to RFC 2047 if necessary (assuming ISO-8859-1 encoding).
+
+33. Added the ${rfc2047 and ${from_utf8 expansion operators.
+
+34. The file names used for maildir deliveries have been changed, to accomodate
+ operating systems that may re-use a PID within one second. The file name
+ now include the microsecond time fraction, and the delivery process does
+ not exit until the clock is at least one microsecond after the time used in
+ the file name. The code copes with the clock going backwards (it waits
+ till time catches up).
+
+35. The rules for creating message ids have been changed to allow for the fact
+ that a PID may be re-used within one second. As part of this change, the
+ range of localhost_number has been reduced to 0-16 for most systems, and
+ 0-10 for those with case-insensitive file systems (Cygwin, Darwin).
+
+36. Code tidy: there was a local count of non-TCP/IP messages that duplicated
+ the global receive_messagecount (used for accept_queue_per_connection).
+
+37. verify = header_syntax was allowing unqualified addresses in all cases. Now
+ it allows them only for locally generated messages and from hosts that
+ match sender_unqualified_hosts or recipient_unqualified_hosts,
+ respectively.
+
+38. If PAM was called with an empty first string, it called the data function
+ to get the user name, thereby getting the second string by mistake. If this
+ was also null (empty passwords are permitted), there was an infinite loop.
+ An empty user name is not now passed to PAM; authentication is forcibly
+ failed instead. Also, if the end of the list of strings is reached, an
+ empty string is passed back just once; a subequent call for data provokes
+ an error response.
+
+39. If a reverse DNS lookup yields an empty string, treat it as if the lookup
+ failed. (Apparently such records have been seen. Sigh.)
+
+40. Added the -bnq command line option to suppress automatic qualification of
+ addresses in locally submitted messages.
+
+41. Header texts supplied by options to the autoreply transport may now contain
+ newlines that are followed by whitespace. (This was allowed from a filter,
+ but not from the transport.)
+
+42. Patch for < > problems in eximstats 1.23.
+
+43. Re-arranged the code to make it easier in future to add additional filter
+ types.
+
+44. Added support for changing the connection timeout in LDAP; this is
+ something that's available in Netscape SDK 4.1. Exim uses the given value
+ if LDAP_X_OPT_CONNECT_TIMEOUT is defined.
+
+45. When Exim was setting a daemon listener on multiple interfaces, including
+ listening on "all IPv6" and "all IPv4" interfaces, it was binding all the
+ sockets, and then calling listen() for each of them. On some IP stacks, a
+ listen for "all IPv4" fails after listening for "all IPv6" because a single
+ socket catches both kinds of call. Exim coped with this, but it turns out
+ that on a USAGI-patched Linux, this logic doesn't work unless the "listen",
+ as well as the "bind" has been done for the IPv6 socket first. The order of
+ the functions has now been changed. Instead of "bind, bind ... listen,
+ listen..." it now does "bind, listen, bind, listen, ...". Also, the failure
+ happens in the bind() rather than in the listen(), so there are now two
+ checks, which hopefully will handle all kinds of IP stack.
+
+46. IPv6 addresses have "scopes", and a host with multiple interfaces can, in
+ principle, have the same link-local addresses on different interfaces.
+ Thus, they need to be distinguished, and a convention of using a percent
+ sign followed by something (often the interface name) is being used, for
+ example: 3ffe:2101:12:1:a00:20ff:fe86:a061%eth0. Two changes have been made
+ to accommodate this:
+
+ (a) A percent sign followed by an arbitrary string is allowed at the end of
+ an IPv6 address.
+
+ (b) Exim calls getaddrinfo() instead of inet_pton() to convert a textual
+ IPv6 address for actual use. This function recognizes the percent
+ convention in some operating systems.
+
+47. Additional debugging inserted for the case of forced failure when expanding
+ an item in a list.
+
+48. A new debugging selector +expand has been added. This is not included in
+ the default set of selectors. It requests detailed debugging information
+ for string expansions.
+
+49. Failure to open the main log results in a panic-die, but the original line
+ that was being logged could be lost. It is now output to stderr if there is
+ a stderr file.
+
+50. When Exim starts, it checks for the existence of its spool directory, and
+ creates it if necessary. Unfortunately, it was doing this after the code
+ for logging arguments. Thus, if the spool did not exist, trouble ensued.
+
+51. The log line for an ACL warning after a sender verify callout failure was
+ not showing the details, unlike the log line for a deny. They are now shown
+ in a similar way.
+
+52. For reasons lost in the mists of time, when a pipe transport was run, the
+ environment variable MESSAGE_ID was set to the message ID preceded by 'E'
+ (the form used in Message-ID: header lines). The 'E' has been removed.
+
+53. Updated the QNX configuration files for QNX 6.2.0.
+
+54. The "*@" type partial matching for single-key lookups was broken in
+ releases after 4.10. Exim looked for *@xxx but, if that failed, it wasn't
+ going on to look for "*".
+
+55. Included eximstats 1.25 in the source tree.
+
+56. Changed log wording from "Authentication failed" to "<name> authenticator
+ failed", where <name> is the name of the authenticator.
+
+57. gcc 3.2.2 warned about a selection of places where string casts were
+ needed.
+
+58. Exim monitor: the use of one_time redirection could cause addresses to be
+ displayed with incorrect "parent" addresses after the one_time
+ re-arrangement had taken place. They should be shown with no parents,
+ because the parentage has been removed.
+
+59. Arranged to keep independent timestamps for postmaster and random checks in
+ callouts, and not to do unnecessary tests for postmaster when testing
+ individual addresses.
+
+60. Incorporated PCRE release 4.0.
+
+61. Added ${hex2b64: operator.
+
+62. Added $tod_zulu.
+
+63. Added ${strlen: operator.
+
+64. Added ${stat: operator.
+
+65. When Exim is receiving multiple messages on a single connection, and
+ spinning off delivery processess, it sets the SIGCHLD signal handling to
+ SIG_IGN, because it doesn't want to wait for these processes. However,
+ because on some OS this didn't work, it also has a paranoid call to
+ waitpid() in the loop to reap any children that have finished. Some
+ versions of Linux now complain (to the system log) about this "illogical"
+ call to waitpid(). I have therefore put it inside a conditional
+ compilation, and arranged for it to be omitted for Linux.
+
+66. Added settable variables $acl_c0 - $acl_c9 and $acl_m0 - $acl_m9 for use
+ during ACL processing.
+
+67. Added "defer" command to system filter.
+
+68. X options such as -bg or -geometry that were added to an eximon command
+ were being lost as a result of a bug introduced by 4.12/6.
+
+69. The "more" and "unseen" generic router options can now be expanded strings.
+
+70. The "once_repeat" option in the autoreply tranport is now an expanded
+ string.
+
+71. If maildir_format is set on an appendfile transport that is referenced from
+ an file_transport setting in a redirect router, it forces maildir delivery,
+ even if the path given in the filter does not end with '/'.
+
+72. Fixed three bugs in ${readsocket:
+ (i) If the operation failed, and a failure string was given, "}}" was
+ erroroneously added to it.
+ (ii) If the operation succeeded, but a failure string was present, "}" was
+ added to the expanded data.
+ (iii) The alarm for the timeout was set with signal() instead of with
+ os_non_restarting_signal(), which meant that it only worked on those
+ OS whose default is not to restart an interrupted system call.
+
+73. A complete host name (no wildcards) in a host list causes a forward lookup
+ for the IP address. If this failed, Exim was behaving as if the host didn't
+ match the list, instead of giving an error (as it does when a reverse
+ lookup fails).
+
+74. If router_home_directory was passed on as a home directory for a local
+ transport, it was being re-expanded in the transport. This has been changed
+ so that the expanded value is passed from the router to the transport, and
+ no re-expansion takes place.
+
+75. When a redirect router generated a pipe, file, or autoreply, the values of
+ $domain_data and $localpart_data were not being propagated to the
+ transport.
+
+76. The macros MESSAGE_ID_LENGTH and SPOOL_DATA_START_OFFSET are now defined in
+ local_scan.h so that they are available to local_scan() functions.
+
+77. Changes to the SMTP PIPELINING support:
+
+ (1) Exim used always to accept pipelined commands, even when it hadn't
+ advertised PIPELINING (i.e. when EHLO had not been received). Now it
+ objects unless PIPELINING has been advertised.
+
+ (2) Advertising PIPELINING to specific hosts can be disabled via the new
+ option pipelining_advertise_hosts.
+
+78. The acl_smtp_connect ACL was not being run for -bs input when no IP address
+ was supplied via -oMa.
+
+79. A "mail" command in a filter could cause a crash if the list of recipients
+ for the "to:" line was excessively long - this showed up in a reply to
+ a message with a ridiculously long Reply_to: header line.
+
+80. Added allow_utf8_domains.
+
+81. Added $rh_ and $rheader for "raw" header expansion.
+
+82. Added smtp_accept_max_nonmail_hosts.
+
+83. Extended ${stat (see 64 above) to add smode=symbolic mode.
+
+84. Added default logging for host and IP lookup failures, with a log selector
+ called host_lookup_failed to turn it off.
+
+85. Added header_maxsize and header_line_maxsize.
+
+86. If a RCPT ACL made use of "verify = sender" without callout, followed by
+ another use with callout, and the callout failed, the caching was broken
+ such that for a subsequent RCPT command, the first callout failed
+ incorrectly. The caching of sender verification has been fixed so that it
+ now remembers that the routing succeeded even when the callout fails.
+
+87. Added errno and strerror(errno) to the log line for a failure to lock the
+ -D file when receiving a message.
+
+88. If router with check_local_user set up a local delivery, and no user was
+ specified on the transport, and errors_to on the router specified an
+ address whose verification also invoked check_local_user, the wrong uid/gid
+ was used for the transport. It used the uid/gid of the errors_to address
+ instead of the uid/gid of the original local part.
+
+89. If log_file_path=:syslog was set, to use the default log path and also
+ syslog, and check_log_space was also set, Exim was confused, and refused to
+ accept messages, giving the error "cannot find slash in ".
+
+90. If a router stripped a prefix or a suffix from a local part, and then
+ routed that address to an smtp or lmtp transport, the address that was
+ sent in the RCPT command did not have the affixes stripped.
+
+91. For BSMTP delivery by appendfile or pipe, the address given in the RCPT
+ command did not preserve the case of the envelope address, as it is
+ supposed to.
+
+
+Exim version 4.13
+-----------------
+
+There was no 4.13. I accidentally put out a fixed version of 4.12 (a typo was
+discovered very soon after release) that verified itself as 4.13. This too was
+hastily fixed, but it seems best not to use the number, to avoid confusion.
+
+
+Exim version 4.12
+-----------------
+
+ 1. Update to change 4.11/82: for the max number of processes, set
+ RLIM_INFINITY if it is defined.
+
+ 2. An expansion ${run{xxx}} where xxx was a successful command that produced
+ no output caused Exim to crash.
+
+ 3. Some artificial delays of 1 second existed when running in the test
+ harness, to ensure repeatability of debugging output. Now that we have
+ the millisleep() function, these can be shorter.
+
+ 4. Change 4.11/30 below overlooked the case when an address gets a 4xx
+ response from a server. Because this isn't a host problem, the host does
+ not get delayed, and it gets tried every time the address is OK'd for
+ routing, with the same reponse. However, if hosts_max_try is set, because
+ not all the hosts were tried, the address does not time out. I've changed
+ things so that if there is a 4xx response to a RCPT command, the host in
+ question does not count towards hosts_max_try if the message is older than
+ the host's maximum retry time. This means that other hosts are always tried
+ in this circumstance; if the address gets 4xx errors from all of them, it
+ will eventually time out.
+
+ 5. If a retry rule for a host had no actual retry times specified, it could
+ cause a crash when checking the ultimate address timeout. (Very old bug,
+ spotted in passing, so probably never bothered anybody.)
+
+ 6. Change 135 below broke the following scripts when a list of configuration
+ files was given: exicyclog, exim_checkaccess, eximon, exinext, and exiwhat.
+ In practice, if exim_path was not specified in the configuration file (a
+ common case), things would probably work OK. However, the use of
+ CONFIGURE_FILE_USE_NODE definitely did not work. These scripts have now
+ been updated to fix this problem. They now search for the configuration
+ file in the same way Exim itself does: for each name in the list, the
+ "noded" file is tried first, then the unsuffixed file.
+
+ 7. If a WARN verb in an ACL did not specify an explicit "message" modifier,
+ and was triggered by a failing sender or recipient verification, the
+ response that would have been sent as an SMTP message for a DENY verb was
+ incorrectly being added to the message's headers.
+
+ 8. I screwed up change 4.11/155. For lookup types whose names were prefixes of
+ other lookup types (e.g. nis and nisplus, dbm and dbmnz), the new search
+ function didn't do the correct comparison, meaning that the wrong lookup
+ type could be found.
+
+ 9. Solaris seems to be one of the LDAPs that doesn't have the lud_scheme
+ member of the LDAPURLDesc structure. Since the check that is made on it
+ is only to double check that a path is given for ldapi, I've just removed
+ the test in the Solaris case.
+
+10. The modified TextPop.c source in the Exim monitor had declarations of errno
+ and sys_nerr which never were actually referenced. The second of these
+ caused trouble on Darwin, so I've removed both of them. Why were they
+ there? Who knows? This is ancient X code...
+
+11. The DEFER ACL verb crashed if no "message" modifier was set.
+
+12. The check on incoming messages that gives the error "too many non-mail
+ commands" was too strict. In the case of Exim sending to Exim, when the
+ client has queued messages for the server and is using TLS, it will close
+ and re-initialize TLS between messages (because the client has to hand the
+ SMTP connection to a new process). STARTTLS was being counted as a non-mail
+ command, and therefore could cause the limit to be hit. The revised code
+ now allows for one RSET, one HELO or EHLO, and one STARTTLS between each
+ message without counting them as non-mail commands. (One RSET was
+ previously allowed - I *had* spotted that case.)
+
+13. Some log lines for rejections by ACL were putting ident values in
+ parentheses instead of using U= after H=. (There are some other lines that
+ do use parens, typically when the host name appears without H= within a
+ message. This whole area could perhaps do with tidying up.)
+
+14. When processing a redirection file happens in a subprocess (typically so
+ that a .forward file is processed as the user), Exim was assuming that a
+ call to wait() would always reap the subprocess, and it was failing to
+ check the result. In theory, a signal of some sort occurring at the wrong
+ time could break this assumption - the process was then left unreaped, and
+ could possibly be picked up later during deliveries, thus confusing that
+ code ("processes got out of step"). This is conjecture - I haven't got a
+ definite test of this. However, I have fixed the code to repeat the wait
+ after a signal.
+
+15. When Exim was waiting for a remote delivery subprocess, and the waitpid()
+ call found a process that was not in the list of remote delivery processes,
+ Exim gave up waiting for remote processes. It is probably better just to
+ ignore the unexpected process (though, of course, write to the main and
+ panic logs) and to wait for another process, and so that is what now
+ happens. If the error situation is caused by failed waiting logic for
+ routing or local delivery processes, this approach will minimize bad
+ behaviour, I hope.
+
+
+Exim version 4.11
+-----------------
+
+ 1. Ignore trailing spaces after numbers in expansion comparisons such as
+ ${if > { 5 } { 4 } ... (leading spaces were already ignored).
+
+ 2. Two variables, $warnmsg_delay, and $warnmsg_recipients, had got left with
+ their old Exim 3 names, when I meant to change to "warn_message", along
+ with the warn_message_file option. They have now been changed. The old
+ names remain as synonyms, but will be undocumented in due course.
+
+ 3. The message "This message was created automatically by mail delivery
+ software (Exim)." still confuses people. If they are sufficiently Internet-
+ ignorant, they think the message has come from exim.org. At first, I
+ changed thw wording to "This message was created automatically by mail
+ delivery software (Exim) running on a mail server handling mail for <the
+ qualify domain>." in the hope that that might be better. However, in
+ testing that still proved confusing on servers handling multiple domains.
+ The message has now reverted to the original, simple wording: "This message
+ was created automatically by mail delivery software."
+
+ 4. It has been discovered that, under Linux, when a process and its children
+ are being traced by "strace -f", the children are stolen from the parent
+ while they are being traced. A call to waitpid(-1,&x,NOHANG), which Exim
+ uses to test for the completion of "any of my children" in a non-blocking
+ manner, returns as if there are no children in existence. Exim used treat
+ this as a serious unexpected error state. What it does now is to use
+ kill(pid,0) to check explicitly for the continued existence of any of its
+ children. If it finds any, it assumes it is being traced, and proceeds as
+ if the return from waitpid() had been "none of your children have finished
+ yet". If it can't find any children, it gives the error as before.
+
+ 5. When Exim creates hints databases and their lock files as root, it needs to
+ change their ownership to exim. In Exim 3, the function to open a hints
+ database wasn't called as root very often, and the check "are we running as
+ root?" would usually fail. However, because Exim 4 eschews the use of
+ seteuid(), it runs all its routing as root, and this always calls the hints
+ database opening function. It wasn't noticing when it was actually creating
+ the database, and so it was running chmod() on all the files in the db
+ directory every time. This does no harm, of course, but wastes resources.
+ Exim now detects when the database was already in existence by opening
+ without O_CREAT at first. If this succeeds, it doesn't do the root test.
+
+ 6. The line in MakeLinks that creates a link for direct.c had been
+ accidentally left in (cf 4.03/6).
+
+ 7. The value of $0 in the replacement in a rewriting rule was being corrupted,
+ leading to incorrect results or error diagnostics.
+
+ 8. Added support for ldapi:// URLs to the LDAP lookups (OpenLDAP only). Also,
+ re-organized the code to use ldap_initialize() with OpenLDAP in all cases
+ (it seems to be preferred).
+
+ 9. With OpenLDAP 2.0.25, ldaps:// doesn't seem to work unless the LDAP
+ protocol level is set to 3. This is now standard in the Exim code, as v3
+ has been around for 5 years now. Testing ldaps:// is now included in the
+ Exim test suite. Although earlier versions claimed to support it, I rather
+ suspect that it never worked.
+
+10. Inserted some checking of the syntax of the IP address given as the first
+ argument to the exim_checkaccess utility. This gives a better error
+ message, especially in the case when somebody gets the arguments in the
+ wrong order.
+
+11. Improved the panic log entry if an unsupported format type is passed to
+ string_vformat() (now gives the whole format string, not just the little
+ bit that's wrong).
+
+12. Ever since its early days, Exim has checked the syntax of non-SMTP
+ addresses according to RFC [2]822 rules, rather than the stricter RFC
+ [2]821 rules that it uses for SMTP. This allows for a wider set of
+ characters in domains. This has now caused a problem, because I forgot
+ about it when making some changes to the format of spool files (see
+ 3.953/44, 4.03/10, and 4.04/1). I can't believe that anybody actually makes
+ use of this feature (which isn't documented), so I have removed it. All
+ domains must now conform to RFC [2]821 rules. A non-SMTP message with a
+ domain that would previously have been accepted will now be bounced.
+
+13. If widening a domain in a dnslookup router made it syntactically invalid,
+ the error message quoted the original domains instead of the widened
+ domain.
+
+14. During a queue run initiated by -R or -S (or by -i when the use of message
+ logs is disabled), if Exim encountered a message with certain
+ characteristics (including text for $local_scan_data, and the setting of
+ the "manually thawed" flag), this data was not correctly reset for
+ subsequent messages. So if they didn't have those settings themselves,
+ strange things could occur.
+
+15. With the "percent hack" enabled for percenthack.domain, if a message had
+ two addresses such as X%some.domain@percenthack.domain and X@some.domain,
+ Exim was not recognizing the duplication, and was making two deliveries
+ instead of one.
+
+16. The output from verification (for -bv and VRFY) used to list a child
+ address when verification was applied to children (this happens, for
+ example, for aliases that generate just a single child). Now it lists only
+ the original address.
+
+17. Changes 34 and 35 of 4.10 did not wholly solve problems with widened
+ domains. The following bug still existed:
+
+ . A recipient address was abbreviated (e.g. one component).
+ . A dnslookup router caused it to be widened.
+ . The new domain was a local domain.
+ . The address was redirected to itself.
+
+ At this point, Exim thought it was a duplicate, and discarded it.
+
+ This whole thing turned out to be a large can of worms, so I have reworked
+ the address widening code. This should get rid of all these problems.
+ Widening now appears similar to redirection, with the unwidened address
+ becoming a proper parent address. As part of this, there has been some
+ general re-organization of the way addresses are handled.
+
+18. When a filter generated only "unseen" deliveries, the normal delivery that
+ happened subsequently lost any value of address_data that was previously
+ set. The handling of values like that that are propagated from parents to
+ children has been reworked.
+
+19. Added smtp_return_error_details and the check_postmaster option for address
+ verification callouts.
+
+20. Long SMTP responses (from ACL messages or wherever) are now automatically
+ split up into multi-line responses if possible. The split happens at an
+ occurrence of ": " if present after 40 characters. Otherwise it happens at
+ the last space before 75 characters. Existing newlines in the message are
+ taken into account.
+
+21. When verify = header_sender is set, a different error message is now given
+ if a syntax is detected, as opposed to failure to verify.
+
+22. Extended the general mechanism for ${quote_lookuptype:...} expansions by
+ allowing for an option to be given after the lookup name, for example
+ ${quote_ldap_dn:...}. Unrecognized options cause errors.
+
+23. Re-worked the quote_ldap expansion items to provide two different kinds of
+ quoting, since the requirements of filter strings and DNs are different.
+ Sigh. Arranged for the DN given in the USER= setting to be de-URL-quoted
+ because not all libraries do it themselves.
+
+24. The handling of responses from LDAP searches wasn't right. It was detecting
+ situations of the form "ldap_result failed internally or couldn't provide
+ you with a message" but not "the server has reported a problem with your
+ search". This has now been tidied up (thanks, Brian). Problems of the
+ latter kind are now handled as follows:
+
+ (1) For LDAP_SIZELIMIT_EXCEEDED, the truncated list of results is
+ returned. This is what happened before.
+
+ (2) For a small set of errors that, in effect, mean "that object does
+ not, or cannot, exist in the database", the lookup fails. This is
+ also as before.
+
+ (3) For other problems, the lookup defers, giving the LDAP error.
+
+25. Added $ldap_dn to hold the DN of the last entry retrieved in the most
+ recent LDAP lookup.
+
+26. Exim was not checking for the LDAP_INVALID_CREDENTIALS error when
+ ldap_bind() failed during an ldapauth call. With (at least) OpenLDAP2, the
+ connection to the server doesn't happen until ldap_bind(), so failures to
+ connect were being treated as authentication failures, and given hard
+ errors. Now, all errors other than LDAP_INVALID_CREDENTIALS are treated the
+ same way for all calls to ldap_bind(), whether ldaputh or otherwise. They
+ lead to temporary errors - if there are more servers, they will be tried.
+
+27. If there was a reference to a non-existent named list, for example, a
+ setting such as "senders = +something", but no lists of that type were
+ actually defined, Exim misbehaved. For an address list, it treated the name
+ as a domain list. For a domain list, it just didn't match. Now it gives a
+ panic error about a non-existent named list (as it always did if there were
+ named lists of the appropriate type). The error now tells you what type of
+ list it thought it was looking for.
+
+28. When -bt or -bv is used by a non-admin user, and there is some kind of
+ DEFER (e.g. database unreachable), details of the failure are no longer
+ given, because they may include private data such as the password for an
+ LDAP lookup.
+
+29. The logic for using a remote host name as a key for looking up retry rules
+ in preference to the domain of the email address was broken. It wouldn't
+ find such retry rules.
+
+30. There were some problems with the action of hosts_max_try in the smtp
+ transport where there were indeed more hosts available than the limit.
+
+ (a) Exim used to time out an address out if all the hosts that were tried
+ were past their retry limits, ignoring the state of any hosts that were
+ not tried because the hosts_max_try limit was reached. Now it won't
+ time out an address unless all its hosts are actually considered and
+ are past their retry limits.
+
+ (b) Hosts that are past their retry limits are no longer counted for
+ hosts_max_try. This means that when some hosts are in this state, a
+ greater number of hosts are tried than before, but this is the only way
+ to ensure that all hosts are considered before timing out an address.
+
+ (c) When the hosts_max_try limit is reached, Exim now looks down the host
+ list to see if there is a subsequent host with a different MX. If there
+ is, that host is used next, and the current host is not counted. More
+ details in NewStuff.
+
+31. The source for spa authentication (taken from the Samba project) used the
+ type "int16". This has caused compilation problems in some systems that
+ happen to have a different definition of it. (Naughty, naughty, non-
+ standard.) I've renamed all the defined types by adding "x" on the end.
+
+32. When a delivery that used authentication was run with -v (which an
+ unprivileged user can use) it included the authentication data when it
+ showed the SMTP transaction. Such data is now replaced by asterisks in any
+ reflection of the SMTP commands. This also applies if the command is logged
+ as a result of an error response.
+
+33. Some little problems in queue runs:
+
+ (a) The reading end of the synchronising pipe was being left open in the
+ delivery subprocess. This caused no harm, but used up a file
+ descriptor till that series of deliveries was done.
+
+ (b) If the load level got high enough to abandon a queue run, the
+ synchronizing pipe was accidentally not closed. Normally, this wouldn't
+ matter, because the queue runner process would finish any way, but...
+
+ (c) If split_spool_directory was set without queue_run_in_order, the code
+ for abandoning a queue run because of too high load didn't stop
+ cleanly. Instead, it went on to look at the remaining subdirectories.
+ Each one would then notice the high load, and abort. Not only was this
+ a waste of time, but because of (b) above, it used up one file
+ descriptor per subdirectory. With up to 62 subdirectories, this could
+ hit the limit of file descriptors if it was as low as 64 (which it
+ sometimes is).
+
+34. Added SYSTEM_ALIASES_FILE to the build-time configuration, and the ability
+ to set ROOT= when installing. Removed installation instructions for the
+ info version of the overview document, because that document no longer
+ exists for Exim 4.
+
+35. Added a total line to exiqsumm.
+
+36. convert4r4 can now handle "optional" for single-key lookups in aliasfile
+ directors.
+
+37. Change 4.03/25 (making convert4r4 double colons in require_files lists) was
+ incomplete. It worked for routers, but not for directors.
+
+38. After verify=recipient in an ACL, the value of $address_data is the last
+ value that was set while routing the address.
+
+39. Included eximstats 1.22.
+
+40. If a delivery of another message over an existing SMTP connection yields
+ DEFER, we do NOT set up retry data for the host. This covers the case when
+ there are delays in routing the addresses in the second message that are so
+ long that the server times out. This is alleviated by not routing addresses
+ that previously had routing defers when handling an existing connection,
+ but even so, this case may occur (e.g. if a previously happily routed
+ address starts giving routing defers). If the host is genuinely down,
+ another non-continued message delivery will notice it soon enough.
+
+41. Added quota_directory to appendfile.
+
+42. Changed the order of processing configuration input lines. Previously, it
+ was comment, .include, continuation, macro expansion, comment again (in
+ case a macro turned a logical line into a comment). This meant that macros
+ could not be used in .include lines. The order is now macro, comment,
+ .include, continuation. That is, macro expansion is done on physical lines,
+ not on logical lines.
+
+43. Improved the error message if an option-setting line in the configuration
+ does not start with a letter. (It used to say 'option "" unknown'.)
+
+44. Allow -D to set a macro to the empty string. Previously it would have
+ moved on to the next commandline item. This seems pointless. Either -DXX or
+ -DXX= sets an empty string.
+
+45. Changed OS/Makefile-FreeBSD thus:
+
+ EXIWHAT_MULTIKILL_CMD='killall -m'
+ EXIWHAT_MULTIKILL_ARG='^exim($$|-[0-9.]+-[0-9]+$$)'
+
+ This is because, with the Exim standard installation using a symbolic link,
+ the name of the running program is not "exim" but (e.g.) "exim-4.10-1".
+
+46. An Exim server now accepts AUTH or STARTTLS commands only if their
+ availability has been advertised in response to EHLO.
+
+47. A few source changes to avoid warnings from very picky compilers that don't
+ complain about unset variables when the only setting is by passing the
+ address to another function.
+
+48. Added -d+pid to force the adding of the pid to all debug lines. Default it
+ on when the daemon is run with any debugging turned on. (Pids are still
+ automatically added when multiple deliveries are run in parallel.)
+
+49. Included Matt Hubbard's exiqgrep utility.
+
+50. Give error for two routers, transports, or authenticators with the same
+ name. (It already caught duplicate ACLs.)
+
+51. If a host has more than MAX_INTERFACES interfaces (common for hosts with a
+ slew of virtual interfaces), and Exim had to find the list of local
+ interfaces, it ran off the end of the list that the ioctl returned. I had
+ assumed the length would be set to correspond to the amount of data
+ returned - but in at least one OS it is set to the actual number of
+ interfaces, even if they don't all fit in the buffer.
+
+52. Nit-picking changes to store.c. It was assuming the length of the
+ storeblock structure would be a multiple of the alignment, which is almost
+ certainly "always" true. However, just in case it might not be it is now
+ rounded up. For some long-forgotten reason, Exim was getting blocks of
+ store of the size (8192 - alignment), which seems strange. I've changed it
+ to plain 8192.
+
+53. Added functions to compute SHA-1 digests, added the ${sha1: expansion
+ operator, added support for {sha1} to crypteq.
+
+54. When local_scan() times out, include the message size in the log line.
+
+55. If a pipe transport had no command specified, and the address also had
+ no command associated with it, the transport process crashed. Now it defers
+ with a suitable message.
+
+56. An Exim server output mangled junk if it received a HELP command on an
+ TLS-encrypted session.
+
+57. The output from -bV (and at the start of debugging) now lists the optional
+ items included in the binary (which routers, etc). The debugging output now
+ includes the name of the configuration file at its start.
+
+58. Added support for GnuTLS as an alternative to OpenSSL.
+
+59. Give a configuration error if tls_verify_hosts is set, but tls_verify_
+ certificates is not set. It doesn't make sense to require some hosts to
+ verify if there's nothing to verify against.
+
+60. A pipe transport may now have temp_errors = * to specify that all errors
+ are to be treated as temporary.
+
+61. The lmtp transport can now handle delivery to Unix domain sockets.
+
+62. Added support for flock() to appendfile, for those operating situations
+ that need it. Not all OS support flock().
+
+63. It seems that host lists obtained from MX records often turn out to have
+ duplicate IP addresses, especially for large sites with many MXs and many
+ hosts. Exim now removes duplicate IP addresses. (Previously, it removed
+ only duplicate names.)
+
+64. If ${readfile was inside a substring that was not part of the final
+ expansion value (because its condition wasn't met), Exim still tried to
+ read the file. This made an "exists" test for the file useless.
+
+65. Added ${readsocket to the expansion facilities.
+
+66. It is now possible to set errors_to to the empty string in routers.
+
+67. Added disable_logging as a generic transport and a generic router option.
+
+68. Applied Stefan Traby's patch to support threaded Perl. As I don't have a
+ threaded Perl, I can't test that this fixed the problem, but it doesn't
+ appear to break the non-threaded case.
+
+69. For SPA (NTLM) client authentication, the options are now expanded.
+
+70. Added support for SPA server authentication, courtesy of Tom Kistner.
+
+71. Latest versions of TCPwrappers use the macro HAVE_IPV6 inside the tcpd.h
+ header, it appears, and this clashes with Exim's use of that macro.
+ Renaming it for Exim is an incompatible change, so instead I've just
+ arranged that HAVE_IPV6 is undefined while including the tcpd.h header.
+
+72. Mac OS 10.2 (Darwin) has IP option support that looks like the later
+ versions of glibc, but without the __GLIBC__ macro setting. I've added a
+ new macro called DARWIN_IP_OPTIONS, and tidied up the code in smtp_in.c to
+ simplify the handling of the three different ways of doing this.
+
+73. If no "subject" keyword is given for a "vacation" command in a filter, the
+ subject now defaults to "On vacation".
+
+74. Exim now counts the number of "non-mail" commands in an SMTP session, and
+ drops the connection if there are too many. The new option
+ smtp_accept_max_nonmail option defines "too many". This catches some DoS
+ attempts and things like repeated failing AUTHs.
+
+75. Installed configuration files for OpenUNIX.
+
+76. When a TLS session was started over a TCP/IP connection for LMTP, Exim was
+ sending EHLO instead of LHLO after the encrypted channel was established.
+
+77. When an address that was being verified routed to an smtp transport whose
+ protocol was set to LMTP, the SMTP callout used EHLO instead of LHLO.
+
+78. Installed eximstats 1.23 in the distribution.
+
+79. Installed a new set of Cygwin-specific files from Pierre Humblet.
+
+80. Added caching for callout verification.
+
+81. Added datestamped logs and $tod_logfile.
+
+82. When Exim starts up with root privilege, set a high limit (1000) for the
+ number of files that can be open and the number of processes that can be
+ created (on systems where this is possible), in case Exim is called from a
+ restricted environment.
+
+83. Minor bugfix in appendfile: when renaming failed for a file whose name was
+ extended with a tag, the untagged name was shown in the error message.
+
+84. If Exim's retry configuration was changed so as to bounce a certain
+ delivery failure immediately, for example to bounce quota errors:
+
+ * quota
+
+ and there were messages on the queue that had previously been deferred
+ because of this error, Exim crashed when trying to deliver them in a queue
+ run. Now it will make one more delivery attempt and bounce on failure.
+
+85. Fixed an obscure problem that arose when (a) an address was redirected
+ to itself, AND (b) the message was not delivered at the first attempt, AND
+ (c) the pattern of redirection was changed at the next delivery attempt.
+ When an address is redirected to the same address, Exim labels the new
+ address as "2nd generation", and so on, in order to distinguish these
+ homonym addresses from each other. Previously, it recorded the delivery of
+ a homonym address as a delivery of the appropriate generation. This does
+ not work if the generation numbers change at the next delivery attempt. The
+ symptoms can be either duplicated deliveries, or missing deliveries,
+ depending on the configuration.
+
+ A real-life example is a configuration that takes "unseen" copies of
+ messages at certain times only, because an "unseen" router in effect does a
+ redirection to a modified address (the unseen delivery) and to the original
+ address (for normal delivery). Thus the normal delivery can be either the
+ 1st or 2nd generation, depending on whether or not the unseen router is
+ triggered at the time of delivery.
+
+ The fix is not to record a delivery to a homonym address as such, but
+ instead to record a delivery to the original address by the final
+ transport. If the same address is subsequently routed to the same transport
+ (whichever generation it now is), the delivery is discarded because it has
+ already happened. Homonym addresses that are themselves redirected are now
+ never recorded as "done", but non-homonym addresses are unaffected, so they
+ are marked when all their children are complete (as before), thus saving
+ an unnecessary subsequent expansion.
+
+ The fix causes more routing processing to be done when homonyms are in use
+ and a message is not delivered at the first attempt, but this is not
+ expected to be very common, and the extra processing isn't all that much.
+
+86. Make sure Exim doesn't overrun the buffer if an oversize packet is received
+ from a nameserver.
+
+87. Added argument-expanding versions of hash, length, nhash, and substr
+ expansions.
+
+88. The API for Berkeley DB changed at release 4.1. Exim now supports this
+ release.
+
+89. When a host was looked up using gethostbyname() (or the more recent
+ getipnodebyname() on IPv6 systems), Exim was not inspecting the error code
+ on failure. Thus, any failure was treated as "host not found". Exim now
+ checks for temporary errors, so the behaviour of "byname" and "bydns"
+ lookups in this respect should be the same. However, on some OS it has been
+ observed that getipnodebyname() gives HOST_NOT_FOUND for names for which a
+ DNS lookup gives TRY_AGAIN. See also change 125 below.
+
+90. Minor rewording of ACL error for attemted header check after RCPT.
+
+91. When USE_GDBM was set, exim_dbmbuild wasn't working properly (still assumed
+ NDBM compatibilify interface); similarly in dbmdb lookups when ownership
+ was being tested.
+
+92. If a Reply-To: header contained newlines and was used to generate
+ recipients for an autoreply, the log line for the autoreply "delivery" had
+ unwanted newlines. Such newlines are now turned into spaces.
+
+93. When a redirect router that has the "file" option set discovers that the
+ file does not exist (the ENOENT error), it tries to stat() the parent
+ directory, as a check against unmounted NFS directories. If the parent
+ can't be statted, delivery is deferred. However, it seems wrong to do this
+ check if ignore_enotdir is set, because that option tells Exim to ignore
+ the error "something on the path is not a directory" (the ENOTDIR error).
+ In fact, it seems that some operating systems give ENOENT where others give
+ ENOTDIR, so this is a confusing area.
+
+94. When the rejectlog was cycled, an existing Exim process was not noticing,
+ and was therefore not opening a new file.
+
+95. If expansion of an address_data setting was forced to fail, and debugging
+ was enabled, a debugging statement tried to print an undefined value
+ instead of the string that was being expanded. This could cause a crash.
+
+96. When Berkeley DB version 3 or higher is in use, a callback function is now
+ set up to log DB error messages that are passed back.
+
+97. The conditions in the Makefile for rebuilding the exim_dbmbuild utility
+ were wrong, leading to failures to rebuild when it should have done.
+
+98. Added -no_chown and -no_symlink options to the exim_install script. Also
+ arranged for the environment variable INSTALL_ARG to be passed over
+ from "make install".
+
+99. Exim sets the IPV6_V6ONLY option on IPv6 listening sockets on operating
+ systems that support it. The call to setsockopt() to do this had SOL_SOCKET
+ instead of IPPROTO_IPV6 as its second argument (and so wouldn't work).
+
+100. When a frozen message was timed out by timeout_frozen_after, the system
+ filter was incorrectly being run for the message before it was thrown
+ away.
+
+101. If a filter used $thisaddress in an argument to a pipe command, its value
+ was not inserted where expected, because the expansion of a pipe command
+ does not happen till transport time, and $thisaddress was not being saved.
+ It is now saved (along with $1, $2, etc, which were already being saved),
+ and reinstated at transport time.
+
+102. Added host grouping for randomizing to manualroute and smtp. A host list
+ that is randomized by manualroute is never re-randomized by smtp. Two
+ host lists that are randomized by manualroute are now treated as "the
+ same" when checking for possible multiple deliveries in one SMTP
+ transaction (this was always true for MX'd host lists).
+
+103. Added "randomize" and "no_randomize" options to manualroute.
+
+104. Added ${hmac expansion item.
+
+105. When compiling with gcc, make use of its facility for checking printf-like
+ function calls (debug_printf and smtp_printf). This would have found the
+ problem in 95 above. It actually found a number of missing casts to (int)
+ in debug lines, and one spurious additional argument.
+
+106. Created an ACKNOWLEDGEMENTS file, which I will endeavour to update in
+ future.
+
+107. Minor modification to Makefile: when a command that starts off "cd xxx;"
+ is followed by another command (on the next line), put the first one in
+ parentheses so that if a "clever" make program amalgamates them, the
+ change of directory is turned off when it should be.
+
+108. If log_timezone is set true, the timestamps in log files now include the
+ timezone offset. A new variable $tod_zone contains the offset. The exigrep
+ utility has been updated to handle timestamps with offsets. The eximstats
+ version included with this release (1.23) has been patched to handle
+ timestamps with offsets. There is also a new -utc option that specifies
+ the timestamps are in UTC. The Exim monitor has been modified so that it
+ omits the zone offset from its display.
+
+109. If the expansion of an errors_to option is forced to fail, the option is
+ ignored.
+
+110. Added $load_average.
+
+111. Added router_home_directory generic router option.
+
+112. Exim crashed on an attempt to check senders or sender domains in an ACL
+ other than after RCPT or DATA. It's now a temporary error.
+
+113. \r was omitted before \n in the SMTP failure response for EHLO/HELO
+ argument checking.
+
+114. On receiving EHLO or HELO, Exim was resetting its state before checking
+ the validity of the command. However, RFC 2821 says that the state should
+ not be changed if an invalid EHLO/HELO is received, so Exim has been
+ changed to conform. This applies mainly when there is more than one
+ EHLO/HELO command in a session.
+
+115. When an Exim root process wrote to a log file, and the log file did not
+ already exist, Exim used to create it as root, and then change its
+ ownership to exim:exim. This could lead to a race condition if several
+ processes were trying to log things at the same time; this happens
+ especially when the exiwhat utility is used. I've changed things so that,
+ if an Exim root process needs to create a log file, it does so in a
+ subprocess that is running as exim:exim.
+
+116. When running filter tests (-bf and -bF) Exim now changes the current
+ directory to "/" so that any assumptions about a particular current
+ directory are false.
+
+117. The appendfile transport was doing the quota_threshold check before
+ actually writing the message. However, the act of writing the message
+ could make it longer by the addition of prefix, suffix, or additional
+ headers. This meant that quota warning could be missed if the basic length
+ of a message kept the mailbox below the threshold, but the transport
+ additions took it over. The warning threshold check is now done after
+ writing the message, when an accurate size is known.
+
+118. If all verifications for verify = header_sender deferred, the log was
+ "temporarily rejected after DATA", without saying why. Now it adds "all
+ attempts to verify a sender in a header line deferred".
+
+119. Added message_id_header_domain option.
+
+120. Ignore message_id_header_text forced expansion failure.
+
+121. Typos: "uknown" in acl.c; missing NULL initialized in drtables.c.
+
+122. When return_size_limit was set greater than zero but smaller than an Exim
+ transport buffer size (so that only one buffer would be written), a
+ message that was longer than the limit could be omitted from the bounce
+ entirely under some circumstances. In other cases, the final buffer full
+ before truncation could be omitted.
+
+123. The inode variables in log.c were of type int with -1 for unset; they
+ have been changed to ino_t with 0 for unset.
+
+124. There are two Makefiles for NetBSD (for different object formats). They
+ were originally supplied in a format where one .included the other. The
+ problem with this has finally surfaced: when processing the Makefile to
+ build config.h, the inclusion isn't seen. The easy way out has been taken:
+ there are now two fully independent files. At the same time, HAVE_IPV6 has
+ been added to both of them.
+
+125. Changed the default way of finding an IP address in both the manualroute
+ and queryprogram routers. Exim now does a DNS lookup; if that yields
+ HOST_NOT_FOUND, it tries calling getipnodebyname() (or gethostbyname()).
+ See also change 89 above.
+
+126. Fixed a race bug in the loop that waits for a delivery subprocess to
+ complete. After reading all the data from, and then closing, the pipe, it
+ assumed that a call to waitpid() for the known pid would always return
+ status for that process. An unfortunately timed signal (e.g. SIGUSR1 from
+ exiwhat) could cause waitpid() to return -1/EINTR instead. The effect of
+ this was to remain in the loop and call FD_SET() with an argument of -1.
+ On Solaris it caused a crash; on other systems it might have looped.
+
+127. If an ACL that was read from a file was used in more than one message in a
+ single SMTP transaction, Exim could crash or misbehave in arbitrary ways.
+ The problem was that the ACL was remembered in memory that was thrown away
+ at the end of the first message. In fixing this, I've done a bit of
+ refactoring of the way memory allocation works, to provide a non-malloc
+ allocator for small blocks of data that must be kept for the life of the
+ process. There's a new function store_get_perm() and I've reintroduced a
+ second storage pool (previously dropped on the 3->4 conversion). A number
+ of instances of malloc calls for small amounts of memory have been changed
+ to use this instead. It might be a tad more efficient. Then again, it
+ might not...
+
+128. A similar problem to 127: memory corruption could occur for multiple
+ messages in one SMTP connection if the data from DNS black list lookups
+ was being used in log or user messages, e.g. references to $dnslists_text.
+
+129. Blanks lines and comments are now ignored in ACLs that are read from
+ files.
+
+130. Two instances of missing \n in debug output.
+
+131. The new debugging tag +timestamp causes a timestamp to be added to each
+ debug output line.
+
+132. Some debug information is written in multiple calls to debug_printf(),
+ with a newline only on the last one. When debugging multiple simultaneous
+ processes, the pid was added to each debug text, and for this reason, a
+ newline was always forced. Now Exim buffers up debug output until the
+ newline is reached, which makes things look much tidier. Also, if there
+ are internal newlines and prefix data such as a pid or timestamp are being
+ added, the prefix is inserted at the internal newlines.
+
+133. When running in the test harness, arrange to overwrite all memory that
+ is released or freed, so that bugs are more easily found. This picked up
+ the following bug:
+
+134. Expansion error messages were left in released store, so could have been
+ overwritten - but in fact most are used immediately, before this happened.
+
+135. A list of configuration files can be given; the first one that exists is
+ used.
+
+136. Moved the code that ensures that newly-created hints databases and their
+ lockfiles are owned by exim:exim so that it runs before the test for
+ successful opening, because a case was reported where the file itself was
+ created, but the DBM library returned an opening error.
+
+137. If an address is redirected to just one child address, verification
+ continues with the child address. However, if verification of the child
+ failed because of (for example) a :fail: redirection, the error message
+ did not get passed back as it would have been had the original address
+ failed. The error information is now passed back for both fail and defer
+ responses.
+
+138. Added $rcpt_defer_count and $rcpt_fail_count.
+
+139. Added "rejected_header" log selector.
+
+140. Added the cannot_route_message generic router option.
+
+141. Change 87 above introduced a bug in the expansion of substrings when the
+ offset was greater than the length of the string, for example
+ ${substr_1:}. Exim crashed instead of returning an empty string.
+
+142. Added extra features to ACLs: the "drop" and "defer" verbs, and the
+ "delay" and "control" modifiers (the latter with "freeze" and
+ "queue_only").
+
+143. If Exim failed to create a log file, it used to try to create the superior
+ directories only if the logs were being written in the spool directory.
+ Now it tries in all cases, but always from a process running as the exim
+ user.
+
+144. Added $authentication_failed.
+
+145. Added $host_data for use in ACLs.
+
+146. Added new ACLs for non-SMTP messages, SMTP connection, MAIL, and STARTTLS.
+
+147. Added a number of new features to the local_scan() API:
+ Access to debug_printf() and the local_scan debug selector
+ Direct access to the message_id variable
+ LOCAL_SCAN_REJECT_NOLOGHDR and LOCAL_SCAN_TEMPREJECT_NOLOGHDR
+ Access to store_get_perm() and store_pool (see 127 above)
+ Access to expand_string_message
+ Option settings in the main configuration file
+ LOCAL_SCAN_ACCEPT_FREEZE and LOCAL_SCAN_ACCEPT_QUEUE
+ LOG_PANIC to write to the panic log
+ Access to host_checking
+ Supporting functions lss_match_xxx() for matching lists
+
+148. Minor security problem involving pid_file_path (admin user could get root)
+ has been fixed.
+
+149. When an ACL contained a sender_domains condition with a reference to a
+ named domain list, the result of the check was not being cached (an
+ oversight).
+
+150. Allowed for quoted keys in lsearch lookups; this makes it possible to have
+ whitespace and colons in keys.
+
+151. Added wildlsearch lookup.
+
+152. Yet another new set of configuration files for Cygwin from Pierre Humblet.
+
+153. Ensure that log_file_path contains at most one instance of %s and one
+ instance of %D and no other % characters.
+
+154. Added $tls_certificate_verified.
+
+155. Now that the list of lookup types has got so long (and more are in
+ prospect) arrange to search it by binary chop instead of linear search.
+
+156. Added passwd lookup.
+
+157. Added simple arithmetic in expansion strings.
+
+158. Added the ability to vary what is appended for partial lookups.
+
+159. Made base 64 encode/decode functions available to local_scan.
+
+
+Exim version 4.10
+-----------------
+
+ 1. Added HAVE_SA_LEN=YES to the OS/Makefile-Darwin file, because it needs it
+ (unsurprising, as it's based on FreeBSD).
+
+ 2. Removed the HTML versions of the PCRE and pcretest documentation from the
+ distribution tarbundle, and instead included them in the HTML tarbundle,
+ linked to the overall index file.
+
+ 3. The code for computing load averages was broken in 64-bit Solaris.
+
+ 4. Make the default ACL refuse local parts that start with a dot.
+
+ 5. LDAP binds with an empty password are considered anonymous regardless of
+ the username and will succeed in most configurations. Exim has been changed
+ so that the LDAP authentication (the ${if ldapauth... condition) always
+ fails when an empty password is used.
+
+ 6. Remove quoting from rbl_domains when used in an ACL by the convert4r4
+ script.
+
+ 7. A lookup entry in a list that had spaces after the lookup type, e.g.
+ "lsearch; /etc/relaydomains" was including the space as part of the file
+ name.
+
+ 8. Give an error if EXIM_USER or EXIM_GROUP contains control characters (it
+ happened when somebody had CRLF terminations in Local/Makefile, which
+ messed up the "unknown user" error message).
+
+ 9. Ensure recipient address appears in log line for internal pipe problems
+ during redirection.
+
+10. Tidies to code for calls to fork(): (a) 3 typos of "<=" that should have
+ been "<" (but would have no actual effect). (b) 2 cases of fork() failures
+ not being logged: during -M for multiple messages, and for auto-delivery
+ of incoming messages.
+
+11. A reference to any header line that contains addresses (e.g. $h_to:) caused
+ a crash if the header was empty. Change 46 for 4.05 introduced this bug.
+
+12. If a system filter file was defined as a non-absolute path, but system_
+ filter_user was undefined, Exim's behaviour was undefined. It could, for
+ example, discard all deliveries, thinking the system filter had overridden
+ them all. Delivery is now deferred, with a message written to the panic
+ log.
+
+13. If a redirection file (or system filter file when system_filter_user was
+ set) was defined as a non-absolute path containing no slash characters,
+ Exim crashed.
+
+14. Added $rcpt_count, containing the number of RCPT commands received during
+ an SMTP transaction. This differs from $recipients_count when some of the
+ RCPTs are rejected.
+
+15. Added $pid, containing the pid of the current process.
+
+16. Fixed uninitialized variable warning in eximstats for relayed messages when
+ there was no sending host name (logged as H=[n.n.n.n]). There's no change
+ of output.
+
+17. The exiqusumm script failed horribly if it encountered a message that had
+ been on the queue for 100 days or more.
+
+18. Added the message_logs option for suppressing the writing of message logs.
+
+19. Allow local_scan() to change the errors_to setting on recipient addresses.
+ (This was made trivially possible because of change 10 in 4.03.)
+
+20. Convert4r4 changed: if forbid_pipe is set on a forwardfile director, also
+ set forbid_filter_run on the generated redirect router.
+
+21. In the Makefile, $(INCLUDE) was preceding the -I. item that refers to
+ Exim's own include files. This caused a conflict with an external library
+ that also happened to have a config.h file. Exim saw the wrong file, and
+ chaos ensued. I've moved the -I. item in the relevant lines so that it
+ comes before $(INCLUDE).
+
+22. Added $acl_verify_message to contain any existing user message when
+ expanding the "message" modifier in an ACL.
+
+23. Changed the default argument for egrep when called in exiwhat to find
+ Exim processes. It is now ' exim( |$$|-)' instead of ' exim( |$$)' so that
+ it works on OS where the true file name appears.
+
+24. In the plaintext authenticator, server_prompts was not being expanded, as
+ documented. It now is.
+
+25. The exinext script was outputting in an incorrect format for routing
+ delays. It said "deliver" when it should have said "route", and the layout
+ of the text was screwed up. In fact, "deliver" is not the right word
+ anyway. I've changed it to "transport". Also removed redundant code for
+ "directing" delays, because these can't occur in Exim 4.
+
+26. Fixed some problems concerned with retrying address errors in remote
+ deliveries:
+
+ (a) I'd overlooked temporary address errors, and assumed that all the
+ retry items would be for host errors, and therefore on the first
+ address when multiple RCPTs were involved. Consequently, no retry
+ record was written for second and subsequent addresses if they
+ received a 4xx error. Thus, these addresses wouldn't be delayed
+ after such a delivery failure.
+
+ (b) A temporary address error causes a routing delay; when the address
+ is eventually tried again, and routing succeeds, the retry record is
+ flagged for deletion. If the address gets another temporary error,
+ the retry record got updated, and then deleted. Thus, temporary
+ address errors were not being delayed and would be tried on every
+ queue run.
+
+27. A minor code tidy for the CRAM-MD5 authenticator.
+
+28. Some OS have a command to select processes by the name of the command they
+ are running, and send a signal to them. Linux and FreeBSD have "killall";
+ Solaris has "pkill" (it also has "killall", but that does something
+ disastrously different). Using such a command makes "exiwhat" more
+ efficient, and reduces the chances of it trying to signal a non-existent
+ process. There are now two build-time parameters, EXIWHAT_MULTIKILL_CMD and
+ EXIWHAT_MULTIKILL_ARG, which can be set to enable this feature to be used.
+ They are defined in the OS-specific files for Linux, FreeBSD, and Solaris.
+ See OS/Makefile-Default for more details.
+
+29. As part of tidying up for 28, changed the name of the build-time parameter
+ EXIWHAT_KILL_ARG to EXIWHAT_KILL_SIGNAL so that its name makes more sense
+ when used in both kinds of exiwhat processing.
+
+30. By default, the daemon doesn't write a pid file if -bd is not used (i.e. if
+ only -q is used). The -oP didn't override this - it was ignored. It now
+ overrides the default and causes a pid file to be written.
+
+31. The values of $local_part, $domain, etc. were not being set during the
+ expansion of shadow_condition in a local transport.
+
+32. The convert4r4 script failed when macros that had continuation lines were
+ present in the Exim 3 configuration file. It inserted junk lines into the
+ output and gave uninitialized variable errors.
+
+33. The convert4r4 script discards (with a comment) a setting of "rewrite" on
+ a smartuser director that has no setting of new_address when it turns it
+ into an "accept" router.
+
+34. When an alias generated an address with a single-component domain, and
+ routing that domain caused it to be widened, Exim remembered only that it
+ had delivered to the widened domain. If any other addresses were deferred,
+ so that another delivery attempt happened later, Exim re-delivered to the
+ widened address, because it checked only the original address. When this
+ kind of widening happens, Exim now checks for previous delivery.
+
+35. A delivery was silently discarded under the following specific
+ circumstances:
+ . The original address is x@a.b.c, where a.b.c is the local host;
+ . a.b.c is recognized as a local domain, and the address is redirected
+ to x@a;
+ . a is not recognized as a local domain, causing the address to be
+ processed by a dnslookup router;
+ . the router widens the address to a.b.c, routes it, and discovers it
+ is the local host.
+ Exim realized that because the domain had been widened, it might have
+ become a local domain, so it arranged to re-route from scratch, using the
+ new domain. However, because the original address was the same address,
+ it thought it had already dealt with it.
+
+36. A space at the start of an LDAP query in an expansion (after the opening
+ curly) was provoking a syntax error.
+
+37. A syntax error in the data of an ldapauth expansion caused the condition to
+ be false without an LDAP query even being tried. Now it causes the
+ expansion to fail.
+
+38. Ensure that an incomplete config.h is removed when the buildconfig program
+ gives an error. Otherwise, if the error is a non-existent Exim user, and
+ the admin fixes this by creating the user (and not modifying any files),
+ Exim will try to use the broken config.h next time.
+
+39. A call with an argument of the form "-D=xxxx" (i.e. omitting the macro
+ name) caused Exim to loop. It now reports an error.
+
+40. If an ACL tested an address for being in a named domain list (e.g.
+ +relay_domains) and then called for recipient verification, and the
+ recipient was rewritten, the cache for remembering matching domain lists
+ was not being cleared after the rewrite, leading to potential routing (and
+ therefore verification) errors. Furthermore, the rewritten address would
+ (incorrectly) have been used for any subsequent address checking within
+ the ACL.
+
+41. If an address such as a%b@c was processed using the "percent hack" and then
+ transmitted over SMTP, Exim was sending "RCPT TO:<a%b@c>" instead of
+ "RCPT TO:<a@b>".
+
+42. A revised Makefile-CYGWIN file from Pierre Humblet.
+
+43. If local_scan() rejected a -bS message, it wasn't handling the error in the
+ way -bS errors should be handled.
+
+
+Exim version 4.05
+-----------------
+
+ 1. In the log display in Eximon, put the insert point (caret) at the start of
+ the last line instead of at the end, because this stops unwanted horizontal
+ scrolling when certain X libraries are used.
+
+ 2. A malformed spool file with an incorrect number of recipients (which
+ should never occur, of course) could cause eximon (and probably exim) to
+ crash.
+
+ 3. Updated Cygwin Makefile and os.h (minor tweaks).
+
+ 4. Setting allow_domain_literals=true was not allowing domain literal
+ addresses in the -f command line option.
+
+ 5. Added debugging output for removing and adding header lines at transport
+ time.
+
+ 6. On systems where SA_NOCLDWAIT is defined, changed from using signal(
+ SIGCHLD, SIG_DFL) to using sigaction(), with flags explicitly set zero, to
+ ensure that SA_NOCLDWAIT is definitely off. This fixes a bug in AIX where
+ subprocesses were disappearing without being turned into zombies for Exim
+ to reap. There was a previous report of the error "remote delivery process
+ count got out of step" on a Linux box that was never resolved. It is
+ possible that this change fixes that too.
+
+ 7. Other applications that support IPv6 have been coded to choose IPv6
+ addresses in preference to IPv4 addresses where possible. This is
+ encouraged, in order to speed up the use of IPv6. Exim has now been changed
+ to do likewise when it looks up IP addresses from host names. This applies
+ both to hosts that have more than one IP address, and to MX records with
+ equal preference values when the hosts they point to have both IPv4 and
+ IPv6 addresses. Within one preference value, Exim will try all the IPv6
+ addresses before any IPv4 addresses, even when some of the IPv4 addresses
+ belong to hosts that also have IPv6 addresses.
+
+ 8. When Exim sent HELO after EHLO was rejected, or when it sent a second EHLO
+ after starting a TLS session, it used the primary host name as the
+ argument, instead of the expansion of the helo_data option.
+
+ 9. Exim was failing to batch addresses for local delivery when errors_to was
+ set on the router to the same string for each address, in the case when the
+ string involved some kind of expansion (that ended up with the same value
+ each time). If the string was fixed (i.e. no expansion) the batching was
+ not blocked. In other words, I was testing the addresses of the strings but
+ forgetting to compare the content. The same problem was not present for
+ remote deliveries, but the code was written out instead of using a
+ subroutine that now exists for this purpose, so I tidied that code.
+
+10. When Exim passes a connected TCP/IP socket to a new Exim process in order
+ to deliver another message on the same connection, it closes down TLS,
+ because it can't pass on the state information that is required by the
+ OpenSSL package. The new process then tries to start up TLS again.
+ Unfortunately, not all servers handle this - and, it has to be said, it is
+ a bit of a dubious interpretation of the RFC. (Exim as a server copes OK,
+ needless to say.) The problem is that the server may just die or give an
+ invalid response, causing a retry delay to occur. The option
+ hosts_nopass_tls was invented to help with this, but an automatic way of
+ testing has been invented. What now happens is that Exim sends a new EHLO
+ after shutting down TLS, before passing the socket on. This in itself
+ reduces the dubiousness of the procedure. If there isn't an OK response,
+ Exim doesn't try to pass the socket on.
+
+11. There was inconsistency in the way failures to set up TLS sessions in the
+ smtp transport were handled when the host was not in hosts_require_tls.
+ It deferred for 4xx responses to STARTTLS, but tried in clear if the actual
+ TLS negotiation failed. It now does the same thing in both cases, and what
+ this is can be controlled by the new option tls_tempfail_tryclear. This
+ defaults true, causing a retry in clear to occur. If it is set false, these
+ kinds of temporary failure cause a defer (for that host; if there are
+ other hosts, they are tried).
+
+12. Tidying. When starting up a new delivery process to deliver another message
+ over an existing SMTP connection, pass over the IP address as well as the
+ host name. This saves having to get the IP address from the socket.
+
+13. Added "#define base_62 36" to OS/os.h-Darwin because the MacOS X operating
+ system has case-insensitive file names.
+
+14. Tidies to rewriting code: (1) It was getting an unnecessarily large block
+ of memory for a rewritten header. (2) Removed some unnecessary debugging
+ code that just duplicated log output.
+
+15. In an expansion like "${if <condition> {${mask:xxxx}}{yyyy}}" Exim still
+ tried to perform the masking operation even when the condition was false
+ and the yield was "yyyy". This could fail when "xxxx" wasn't a valid string
+ for the masking operation. Some other operators (e.g. base62) could fail in
+ a similar way. All string operations are now skipped when processing the
+ unused substring of a condition.
+
+16. If a verification of a sender address in a header (caused by verify =
+ header_sender in an ACL) caused the address in the header to be rewritten
+ (typically because a DNS lookup had widened the domain), the newline at the
+ end of the header got lost, thereby causing two headers to be run together.
+ Sometimes, but not always, this caused a "spool format error".
+
+17. A user wanted to use "save" in a filter file with a non-absolute path, and
+ to set file_transport to a non-appendfile transport that made use of
+ $address_file for its own purposes. This didn't work because Exim was
+ distinguishing between file and autoreplies by the leading '/' of the
+ former. It now checks for the leading '>' of the latter instead.
+
+18. The "accept" router was forcing log_as_local instead of just defaulting it.
+
+19. Exim crashed while verifying a recipient in an ACL if the address was
+ verified by a dnslookup router that widened the domain.
+
+20. When checking the parameters returned from an ident call, Exim was assuming
+ that the format would be textually identical to the values it sent,
+ including the white space. This is not always the case, causing Exim to
+ discard returned ident data that it should have been accepting.
+
+21. Typo (space missing) in "failed to expand condition" error message.
+
+22. The option of specifying an individual transport in a route_data or
+ route_list option of the manualroute router wasn't working. Such settings
+ were being completely ignored.
+
+23. The memory management was poor when building up a string from a lookup that
+ retrieved a large number of data items that had to be concatenated, for
+ example, an alias lookup in a database that returned thousands of
+ addresses. In extreme cases, this could grind the host to a halt. (Compare
+ change 8 for 4.00, which was a similar effect.) Two changes have been made
+ to improve matters: (a) For longer strings, it extends them in bigger
+ chunks, thus requiring fewer extensions. (b) It is now able to release some
+ unwanted memory when a string is copied out of it into a larger block.
+
+24. There was a small error in the memory sizes quoted when -d+memory was used
+ and emptied memory blocks were released.
+
+25. When helo[_try]_verify was set, Exim crashed if the reverse DNS lookup gave
+ a temporary error when trying to look up the host name. It now tries to
+ check with a forward DNS lookup (as it does when the reverse lookup can't
+ find a name). For helo_verify, a temporary error is now given if
+ verification failed, but the host name lookup gave a temporary error. (As
+ before, a permanent error is given if there is no host name available.)
+
+26. When checking quotes for maildir++ format, if the directory name was given
+ with a trailing slash in the "directory" option of the appendfile
+ transport, Exim got the quota calculation wrong because it scanned the
+ final directory instead of the parent directory.
+
+27. The "quota_xxx" error facility for retry rules was broken in Exim 4 if
+ the mailbox had not been read for more than approximately 10 hours.
+
+28. If a router with "unseen" had a setting of address_data, the value was not
+ passed on to subsequent routers for the continuing processing of the
+ address. It now is.
+
+29. If a daemon was started with (e.g.) -qff15m, it omitted the second 'f' when
+ starting queue runners. Likewise, if the flags included 'i', this was
+ omitted.
+
+30. Some operating systems log warnings if exec() happens without the standard
+ input, output, and error file descriptors existing. The worry is that the
+ called program will open some file which will be allocated one of these
+ fds. Another bit of code might assume it can write an error message to
+ stderr, or whatever. Exim was calling itself to regain privilege for
+ delivery without these fds set, thus provoking the warning. Of course, it
+ didn't make use of them itself, but the exposure was there for libraries it
+ might be using. The code has been changed to ensure that, if any of the
+ file descriptors 0, 1, or 2 does not exist at the time of a call to exec(),
+ they are opened to /dev/null.
+
+31. A delivery process could loop under the unusual combination of the
+ following circumstances:
+ (1) A delivery process had envelope_to_add set for its transport.
+ (2) The delivery was for a child address of an envelope address that
+ also had another child.
+ (3) This other child had been discarded because it was a duplicate of a
+ second envelope address.
+ (4) The second envelope address had generated a child that was discarded
+ because it was a duplicate of the first envelope address.
+
+32. The -bp option was failing to notice delivered addresses that were in the
+ -J file but had not yet made it into the -H file. (This got broken between
+ Exim 3 and Exim 4.)
+
+33. If "query" or "queries" in aliasfile director, or "route_query" or
+ "route_queries" in a domainlist router were enclosed in quotes, the
+ convert4r4 script was not removing the quotes before inserting the query
+ into an expansion string, leading to invalid queries within the string.
+
+34. If more than two addresses were being delivered in a batch (either local or
+ remote deliveries), and they all had the same, non-empty value for
+ $self_hostname, but had different domains, Exim crashed. (This is rare,
+ because the use of "self=pass", which is the only way $self_hostname gets
+ set, is rare.)
+
+35. If $message_headers was used in a context where there were no headers (e.g.
+ while verifying an address before receiving a message), it caused an
+ "unknown variable" error. Now it just returns an empty string.
+
+36. Exim was not diagnosing missing time units letters in times on retry
+ rules. It was treating such malformed times as "-1", which caused the rules
+ to misbehave.
+
+37. Added some debugging output to the CRAM-MD5 server code.
+
+38. In the appendfile transport, check for a file name supplied by redirection
+ by checking for "not pipe and not autoreply" instead of looking for a
+ leading '/' in the "address".
+
+39. The os.h file for Darwin defined CRYPT_H, which apparently is wrong.
+
+40. The "condition" condition in ACLs has been tightened up. Formerly, anything
+ other than an empty string, "0", "no" or "false" was treated as "true". Now
+ it insists on "yes", "true", or a non-zero number.
+
+41. Change 22 of 4.02 has been improved; somebody mailed me the correct code
+ to get an error message when ldap_result() doesn't set a result.
+
+42. Update convert4r4 to recognize "ldap:" in require_files, and double the
+ colon.
+
+43. Added "protocol violation" to the "SMTP synchronization" error message, to
+ make it clearer what it is complaining about.
+
+44. Change 26 of 4.03 was incomplete. The same problem could arise if a lookup
+ failed while checking the pre-conditions of a router that was subsequently
+ run. This can happen for negated conditions such as "domains = !<lookup>".
+
+45. Somebody managed to set up a configuration that crashed buildconfig such
+ that it left a half-built config.h but did not stop the build process. I
+ can't reproduce it, but I have added a check after building config.h to
+ test for the presence of its last line ("/* End of config.h */").
+
+46. Added a .PHONY target to the Makefile to be tidy for GNU make. (It should
+ be ignored by other versions).
+
+45. When Exim uses Berkeley DB version 3 or 4 to create a DBM file, it creates
+ it in hashed format. Previously, it opened these files for reading in the
+ same format. Now it opens them as "unknown", which means that other formats
+ can be accommodated when using DB files for auxiliary data.
+
+46. When concatenating header lines that may contain lists of addresses (From:,
+ To:, etc.) as a result of references to $h_from: etc., a comma is now
+ inserted at the concatenation point. Without it, the use of "if
+ foranyaddress" fails on such headers, which is dangerous.
+
+47. The code for ratelimiting MAIL commands was triggering on the count of
+ messages received, instead of the number of MAIL commands (which is not the
+ same thing if no message is accepted in a transaction). The smtp_accept_
+ max_per_connection limit has also been changed to use the count of MAIL
+ commands instead of the count of messages accepted.
+
+48. There was a typo in the exiwhat script which broke it if the esoteric
+ CONFIGURE_FILE_USE_NODE option was in use.
+
+
+Exim version 4.04
+-----------------
+
+ 1. Fix 10 for 4.03 had a bug in it, which could cause problems when converting
+ from an earlier 4.xx release with delayed "one_time" messages on the spool.
+ 4.03 incorrectly complains about spool format errors (and refuses to
+ process these messages).
+
+ 2. Changed the status of the text widgets in the monitor from Append to Edit,
+ because this matters on some versions of X.
+
+ 3. Change 22 for 4.03 turns out to be misguided. Luckily it is controlled by
+ a compile-time macro. I have removed the settings from OS/os.h-Linux that
+ made it try to use these functions.
+
+
+Exim version 4.03
+-----------------
+
+ 1. Change 12 for 4.02 overlooked one case where 256 should have been replaced
+ by MAX_LOCALHOST_NUMBER.
+
+ 2. Timeouts (etc) in dnslist lookups were not behaving as documented; they
+ were deferring (causing 4xx errors) instead of behaving as if the host was
+ not in the list. This has been fixed. In addition, some new special items
+ may appear in dns lists, to control what happens in this case. The items
+ are +include_unknown, +exclude_unknown, and +defer_unknown.
+
+ 3. Added #include <unix.h> to OS/os.h-QNX because it was reported that this
+ was needed, in order to get O_NDELAY.
+
+ 4. Added #define BASE_62 36 to OS/os.h-Cygwin.
+
+ 5. Change 8 for 4.02 overlooked the fact that "directory" need not be set if
+ the directory name is coming from a filter or forwarding file. The check
+ has now been moved from initialization time to run time. Thus, it happens
+ later, but it still helps to diagnose the problem.
+
+ 6. The file direct.c had been accidentally left in the distribution.
+
+ 7. When a new process was forked to deliver another message down an existing
+ SMTP connection, a pipe file descriptor was accidentally left open. This
+ meant that if there was a long chain of such processes, the number of open
+ file descriptors increased by one for each process, and if there were
+ sufficent, the limit of open descriptors could be reached, causing various
+ problems.
+
+ 8. When an address was being checked with -bt and the routing involved an
+ errors_to setting whose address verification also involved an errors_to
+ setting, Exim got into a verifying loop. It shouldn't verify an errors_to
+ setting when already verifying, but got this wrong if it started from -bt.
+
+ 9. Tidied up some compiler warnings when compiling with TCP wrappers.
+
+10. When a child address was promoted to a toplevel address by "one_time" after
+ a deferred delivery, it was not remembering any "errors_to" address that
+ was set by the routers that processed the original address. Consequently,
+ the subsequent delivery had (incorrectly) the original sender address in
+ the envelope. Exim now remembers the "errors_to" address with the new
+ toplevel address and reinstates it for the next delivery.
+
+11. When Exim received a message other than from the daemon, there were two
+ situations in which it did not re-exec itself for delivery: when it was
+ running as root, or when it was running in an unprivileged mode. This was
+ an attempt to save some resources (very early Exims ran as root more often)
+ but has turned out to be pretty rare. A bug has been discovered in this
+ case: if the incoming message was on a TLS session (from inetd, for
+ example), but the outgoing delivery was on an unencrypted SMTP connection,
+ Exim got confused. The effect was minimal: it sent two EHLO commands, but
+ otherwise worked. Multiple EHLOs are not an error, according to the RFCs,
+ but there was at least one broken MTA that objected. This error would have
+ occurred only when synchronous delivery (-odi or -odf) was specified.
+
+ While sorting this out, I have abandoned the logic that did a delivery
+ without forking in the interests of simplicity. This was an even rarer
+ case: it only happened when Exim was running as root or in an unprivileged
+ mode AND synchronous delivery was specified.
+
+12. Change references to /bin/rm in the Makefile to plain rm.
+
+13. If EXIM_PERL was set in Local/Makefile, but PERL_COMMAND was set to a
+ command that was not a file, or if it was set to a non-existent file,
+ the build process carried on trying to build Perl support, but without the
+ relevant variables for the Perl libraries, etc., which is disastrous. In
+ fact, the build process shouldn't have been using PERL_COMMAND; that is a
+ value for screwing into utility scripts. The build process assumes a
+ suitable PATH for things like rm, mv, etc., which have xxx_COMMAND
+ variables for scripts. So I've changed it to use just "perl". It now bombs
+ out if "perl --version" doesn't produce some output.
+
+14. Changed the #includes in perl.c for the Perl headers to use <> instead of
+ "" because this is apparently better usage.
+
+15. Added local_scan_timeout to apply a timeout to local_scan().
+
+16. Recognize IPv6 addresses as IP addresses, even when Exim is not compiled
+ with IPv6 support.
+
+17. When verifying a HELO/EHLO name, Exim was not checking the alias host names
+ it obtained from calling gethostbyaddr(). In many cases, this didn't cause
+ any unwanted rejections because as a last resort Exim does a forward lookup
+ on the HELO name to see if any of its IP addresses matches. But it fixing
+ the bug saves the unnecessary additional lookup.
+
+18. Added "domains = ! +local_domains" to the commented-out ipliteral router in
+ the default configuration.
+
+19. Default sender_host_aliases to an empty alias list, instead of NULL. This
+ is just for tidiness; the way it was coded, it didn't cause any problems.
+
+20. Added -tls-on-connect, which starts a TLS session without waiting for
+ STARTTLS. This supports older clients that used a different port.
+
+21. Added support for the Cyrus pwcheck daemon.
+
+22. Arranged to use getipnodebyaddr() instead of gethostbyaddr() in systems
+ with IPv6 support that have this function, because gethostbyaddr() doesn't
+ work for IPv6 addresses on all systems (it does on some).
+
+23. Header lines added by "warn" statements in the ACL for RCPT are saved up to
+ be added after the message's header has been received. Previously, Exim was
+ saving up all added headers, from both RCPT and DATA, until the very end.
+ Now it adds those from RCPT before the DATA ACL is obeyed, so that they can
+ be accessed from within the DATA ACL.
+
+24. Changed TLS initialization to use SSL_CTX_use_certificate_chain_file()
+ instead of SSL_CTX_use_certificate_file(). This means that the file can
+ contain the whole chain of certificates that authenticate the server.
+
+25. Updated convert4r4 to check for colons that look as if they are part of
+ expansion items in require_files lists (e.g. ${lc:xxxx}). In Exim 3, the
+ whole list was expanded before splitting up, but in Exim 4, the splitting
+ happens first, so such colons must be doubled. The conversion script now
+ doubles such colons, and outputs a warning message. The test for one of
+ these colons is a match against "\$\{\w+:".
+
+26. If, while verifying a recipient address, a router was skipped because a
+ lookup did not succeed, and the following router suffered a temporary
+ failure (e.g. a timeout), the log line for the temporary rejection showed
+ the error from the first router instead of from the second.
+
+27. Exim crashed if a dnslists test was obeyed in an ACL for an SMTP message
+ from the local host. Now it just fails to match the list.
+
+
+Exim version 4.02
+-----------------
+
+ 1. Bug in string expansion: if a "fail" substring of a conditional contained
+ another conditional that used the "fail" facility, Exim didn't swallow the
+ right number of closing parentheses in the case when the original condition
+ succeeded (i.e. when the condition containing the "fail" should be
+ skipped).
+
+ 2. helo_verify_hosts wasn't working when comparing host names.
+
+ 3. When delivering down an existing SMTP connection, the error "Unexpectedly
+ no free subprocess slot" was sometimes given for other addresses in the
+ message.
+
+ 4. Binary zeroes in the message body are now turned into spaces in the
+ contents of $message_body and $message_body_end.
+
+ 5. If the value of a field in a MySQL result was SQL NULL, and more than one
+ field was selected, Exim crashed.
+
+ 6. It seems that many OS treat 0.0.0.0 as meaning the local host, typically
+ making it behave like 127.0.0.1. Since there have been incidents where this
+ was found in the DNS, two changes have been made:
+ (a) Added 0.0.0.0 to the ignore_target_hosts setting in the default
+ configuration.
+ (b) Unconditionally recognize 0.0.0.0 as the local host while routing.
+
+ 7. Added helo_allow_chars so people can let in underscores if they really
+ have to. Sigh.
+
+ 8. Give configuration error if "maildir_format" or "mailstore_format" is
+ specified for appendfile without specifying "directory".
+
+ 9. When return_path was expanded in an smtp transport, the values of
+ $local_part and $domain were not set up.
+
+10. The optimization for sending multiple copies of a single message over one
+ SMTP connection when there are lots of recipients (but too many for one
+ copy of the message) was messing up in the case when max_rcpt was set to 1
+ (for VERP). It would send lots of copies with one RCPT each, correctly, but
+ because the transport was passed more than one address, $local_part and
+ $domain weren't set. Since setting max_rcpt to 1 is almost always
+ associated with VERP (or at least, you do it because you want to use
+ $domain or $local_part), I've made that a special case where the
+ optimization is disabled.
+
+11. Cygwin has case-insensitive file names. Therefore, we can't use base 62
+ numbers for Exim's identifiers. We have to use base 36 instead. Luckily 6
+ base 36 digits are still plenty enough to hold the time for some years to
+ come. There's now a macro that is set either to 62 or 36, but the names and
+ documentation still talk about "base 62".
+
+12. Added build-time variable MAX_LOCALHOST_NUMBER (default 256) to allow the
+ localhost number to be traded off against the maximum number of messages
+ one process can receive in one second. This is relevant only when
+ localhost_number is set. It may be useful for Cygwin, where the maximum
+ sequence number is much less when up to 256 hosts are allowed.
+
+13. Extended MySQL server data to allow for the specification of an alternate
+ Unix domain socket.
+
+14. Give error if too many slashes in mysql_servers or pgsql_servers item.
+
+15. Changed the wording "debug string overflowed buffer" to "debug string too
+ long - truncated" to make it clearer that it's not a big disaster.
+
+16. Now that I finally understand the difference between the resolver's returns
+ HOST_NOT_FOUND and NO_DATA, I've optimized Exim's DNS lookup so that if an
+ MX lookup gets HOST_NOT_FOUND, it doesn't bother to try to look up an
+ address record. Only if it gets NO_DATA does it do that.
+
+17. The contents of Envelope-To: were not correct in cases when more than one
+ envelope address was redirected to a single delivery address via an
+ intermediate address, because the duplication was detected at the
+ intermediate stage, but the checking for Envelope-To: only looked at
+ duplicates of the final address.
+
+18. If a message with the -N flag was on the spool, and was selected during a
+ queue run by -R or -S, the -N flag was incorrectly passed on to all
+ subsequent messages, leading to their being thrown away.
+
+19. Remove unnecessary check for the local host when looking up host names in
+ host lists.
+
+20. If tls_certificate is supplied, but tls_privatekey is not, assume that both
+ are in the tls_certificate file.
+
+21. If a router set transport_current_directory or transport_home_directory
+ to something that involved an LDAP lookup, and there was more than one
+ local delivery to be done for a single message, all but the first got
+ deferred because the LDAP connection for those variables got opened in the
+ superior process, but closed in the first subprocess. The second subprocess
+ then assumed it was still open. We now ensure that each subprocess starts
+ with a clean slate (everything closed down) so that it can open and close
+ its own connections as needed.
+
+22. After a failure of ldap_result(), Exim was calling ldap_result2error() in
+ order to get an error message. However, it appears that it shouldn't do
+ this if the value of result variable is NULL. As I can't find any way of
+ getting an error message out of LDAP in this circumstance, Exim now just
+ gives says "ldap_result failed and result is NULL".
+
+23. If a message arrives over a TLS connection via inetd, close down the SSL
+ library in the subprocess for message delivery (but don't molest the
+ parent's SSL connection).
+
+
+Exim version 4.01
+-----------------
+
+ 1. When setting TCP_NODELAY, the call to setsockopt() was using SOL_SOCKET
+ instead of IPPROTO_TCP, which caused excessive logging on some systems.
+
+ 2. Changed the Makefile for Cygwin to set EXIM_USER and EXIM_GROUP to 0.
+
+ 3. The SMTP rewriting facility was broken.
+
+ 4. There was some malformatting in the spec.txt file (the other formats were
+ OK).
+
+ 5. Made convert4r4 change "bydns_a" into "bydns" in route_list options, and
+ to do the same for "bydns_mx", but in this case to comment that it won't
+ work the same (and to suggest a workaround).
+
+ 6. Removed redundant code in deliver.c for indicating when a reused SMTP
+ connection had been closed in a subprocess - this was being done twice.
+
+ 7. Change 2 of 3.164 removed Exim's explicit checking that a reverse DNS
+ lookup yielded a name whose forwarded lookup gave the original IP address,
+ because I thought that gethostbyaddr() did this automatically (it seems to
+ on some systems). There is hard evidence that I was wrong, so this test has
+ been put back, and in a better form, because it now checks alias names.
+ This means that the verify=reverse_host_lookup condition in an ACL reduces
+ to requiring that the host name has been looked up, since the checks it
+ previously did are not always applied.
+
+ 8. When sender verification fails, the error associated with it is given by
+ default before the 550 error for the first RCPT command. Not everybody
+ wants to see this. There is now an option (no_details) that suppresses it.
+
+ 9. The patterns in rewriting rules with the 'S' flag were not being expanded.
+ For consistency with other patterns (and the documentation), this has been
+ changed.
+
+10. "domainlist", "hostlist", and "addresslist" weren't recognized if the
+ immediately following character was a tab rather than a space.
+
+11. The rules for writing daemon pid files have changed. A new option -oP has
+ been added to provide a way of specifying a pid file path on the command
+ line. Exim now writes a pid file when -bd is used, unless -oX is specified
+ without -oP.
+
+12. The version number of OpenSSL was included in the response to the STARTTLS
+ command - a legacy from the original contributed code that doesn't seem
+ sensible. It no longer appears, and I took it out of the debug output as
+ well because that was the only place left, and the code to compute it was
+ "mysterious magic" that didn't seem worth keeping.
+
+13. When another message was processed in order to send it down an existing
+ SMTP connection, Exim was doing the routing for all the addresses. Even if
+ called from a delivery from a queue runner, this doesn't count as "in a
+ queue run", so retry times were not being inspected. If the message had a
+ large number of recipients, and several of them timed out while routing,
+ the delay could be so large that the server at the other end of the SMTP
+ connection would time out. To avoid this happening, Exim now skips routing
+ for any addresses that have a domain retry time set for routing, whether or
+ not that retry time has arrived, when dealing with a pre-existing SMTP
+ connection. This will be "right" pretty well all of the time, and even
+ when it is "wrong", the only consequence will be some delay. (This doesn't
+ apply to "address" retry times, because those are usually the result of 4xx
+ errors, not timeouts.)
+
+14. Added words to the initial output from -bh pointing out that no ident
+ callback is done.
+
+15. The convert4r4 script wasn't getting it quite right with an aliasfile
+ director that had a "transport" setting. It was missing the "yes/no" in the
+ "condition" setting.
+
+
+Exim version 4.00
+-----------------
+
+ 1. Changed the name of debug_print for authenticators (3.953/38) to
+ server_debug_print because it applies only when the authenticator is
+ running as a server.
+
+ 2. Forgot to change DB_ to EXIMDB_ in the Cygwin Makefile.
+
+ 3. There were still a couple of uses of vfork() when passing a socket to a
+ new delivery process. The use of vfork() is not recommended these days,
+ so I changed them to fork().
+
+ 4. Added the spa authentication mechanism, using the code contributed by Marc
+ Prud'hommeaux (and mostly taken from the Samba project). This supports
+ Microsoft's "Secure Password Authentication", but only as a client.
+
+ 5. queryprogram had current_directory unset, but used "/" when it was unset.
+ It is tidier just to make the default "/" and have done with it.
+
+ 6. When a delivery is run with -v, the -v flag is no longer passed on to new
+ processes that are started in order to send other messages on existing
+ SMTP connections. This prevents non-admin users from seeing these other
+ deliveries. Admin users can specify a higher level of debugging, and when
+ this is done, the debugging selection is passed on.
+
+ 7. Increased the increment for dynamic strings from 50 to 100.
+
+ 8. When Exim was building a dynamic string for $header_xxx from a number of
+ headers of the same name, or for $message_headers, it was using the dynamic
+ string function which is designed for use with relatively short strings. If
+ a pathological message had an enormous header, it chewed up memory at a
+ ridiculous rate. The code has been rewritten so that it does not do this.
+ With a 64K header string (there's a limit set at 64K) it now just gets one
+ 64K buffer. Previously it used a large number of megabytes to build such a
+ string, and some system filter processing ran machines into the ground on
+ messages with huge headers.
+
+ 9. The work for 8 involved a small amount of other "refactoring" in the
+ expansion functions.
+
+10. If "headers add" or "headers remove" were used in a system filter, the
+ headers didn't actually get changed when testing with -bF. This could
+ affect later commands in the filter that referred to the headers.
+
+11. Two system filter bugs: (a) The system filter was always being run as root,
+ even if system_filter_user was set. (b) When the system filter was not run
+ as root, changes to the header lines by "headers add" or "headers remove"
+ were being lost. Because of (a), (b) would never have bitten.
+
+12. Some "refactoring" in the daemon:
+ (a) Removed redundant statement smtp_in=NULL.
+ (b) The test for fork failure for a delivery process was not quite in the
+ right place.
+ (c) Added main and panic logging for receive and delivery fork failures.
+ (d) Check for fdopen() failure, and don't try to continue, but ensure
+ the sockets get closed.
+ (e) Log fclose() failures.
+
+13. Added the "/data" facility to ACL dnslists so as to make it easy to use,
+ for example, the domain lookup of rfc-ignorant.org.
+
+14. Refactored the code in the daemon to use a vector of structures instead of
+ two separate vectors for storing the pid of a spawned accepting process and
+ the corresponding IP address of the client. (This is to make it easier to
+ add other things.)
+
+15. If EXIM_USER or EXIM_GROUP were set to the empty string in Local/Makefile,
+ the uid or gid were set to zero, which is unsafe. These settings now cause
+ an error message at build time.
+
+16. check_ancestor was doing its check case-sensitively, which meant that it
+ did not work with some configurations when redirecting changed the case of
+ the local part. Now check_ancestor respects the setting of
+ caseful_local_part on the router which routed the ancestor address.
+
+17. The check for router looping (whether the current router had previously
+ routed the same address) was always being done case-insensitively. It
+ should do the local part check case-sensitively when caseful_local_part is
+ set for that router.
+
+18. Added helo_try_verify_hosts, which is like helo_verify_hosts except that
+ it doesn't reject failing HELO/EHLO. Instead the verification state can be
+ testing in an ACL by verify=helo.
+
+19. When echoing log writes from a parallel remote delivery process to the
+ debug output, the pid of the parallel process was being omitted.
+
+20. In an ACL run for a RCPT command, the values of $domain and $local_part
+ were becoming unset after a sender or recipient verification.
+
+21. Exim crashed if called with -C followed by a ridiculously long string.
+
+22. Some other potential points of trouble caused by pathological input data
+ have been defended.
+
+23. If hosts_randomize was set on an smtp transport, the randomizing code had
+ a bug which could put the delivery process into a tight loop.
+
+
+
+Exim version 3.953
+------------------
+
+ 1. Exim was not terminating the names of named lists in memory. It got away
+ with this on systems where newly malloc()d store is zeroed (always a bad
+ practice). When running in its test harness, Exim now ensures that all
+ new memory from malloc is filled with a non-zero value. This will help
+ pick up bugs like this in future. (I haven't made it do it always, for
+ performance reasons.)
+
+ 2. When skip_syntax_errors was set on a redirect router, and a forward file
+ (NOT a filter file) contained only invalid addresses, the message was
+ discarded. The router now declines, as it does for invalid filter files.
+ Thus, the address is passed on unless no_more is set.
+
+ 3. When an address containing upper case letters in the local part was
+ deferred, eximon showed the lowercased version with the caseful version
+ as a "parent", as well as the original caseful version in its queue list.
+
+ 4. When hide_child_in_errmsg was set on a redirect router, bounce messages
+ still showed the failed addresses in the X-Failed-Recipients: header line.
+
+ 5. Change 6 for 3.952 should also have included SIGTERM.
+
+ 6. exim -bP +something was searching only the domain lists. It now searches
+ all lists for a matching name.
+
+ 7. If Local/Makefile contains more than one of USE_DB, USE_GDBM, or USE_TDB,
+ give a build-time error. When it does contain one of them, arrange for any
+ OS default for any other one to be overridden. (The code expects at most
+ one of these to be defined.)
+
+ 8. When a value for transport_home_directory is taken from the password
+ information, wrap it in \N...\N so that it isn't expanded in the transport.
+ This affects Cygwin, where home directories may contain $ characters.
+
+ 9. Fixed an occasional crash when autoreply was sending a message created by
+ a user's filter file. It was referencing uninitialized memory. (The
+ prophylactic mentioned in 1 above made it a hard error.)
+
+10. The "run" and "readfile" expansion items could sometimes return extra junk
+ characters (yet another uninitialized memory bug).
+
+11. The lockout options forbid_filter_existstest etc. were not propagating to
+ the expansion of files sent as part of "mail" messages from users' filter
+ files.
+
+12. Another unterminated string bug: when an ACL was read from a file
+ dynamically it wasn't properly terminated.
+
+13. Cached pgsql connections weren't being re-used, leading to a potential
+ build-up of open connections.
+
+14. $message_headers is supposed to be limited to 64K in length, but it wasn't
+ so limited if an individual header line was longer than 64K.
+
+15. An individual header line, or concatenation of multiple identically-
+ named header lines, inserted by $h_xxxx is supposed to be limited to 64K in
+ length, but it wasn't so limited if the only header line was longer than
+ 64K.
+
+16. A syntactically incorrect setting of -d... is now treated as a command line
+ syntax error (message to stderr, return code 1), without any entry on the
+ log.
+
+17. Modifications to the exim_install script:
+ (a) Scan the combined Makefile in the build directory instead of messing
+ around scanning its individual constituent files.
+ (b) Use sed instead of a pipe of grep, tail and cuts. This allows better
+ control, but has to be very simple sed in order to work on Solaris.
+ (c) Allow for the setting of EXE to add a subscript to executables for
+ the benefit of Cygwin.
+ (d) Use -c instead of -b with "cut" because the "cut" in BSD/OS doesn't
+ grok -b.
+
+18. Changes for Cygwin:
+ (a) Update scripts/os-type to recognize CYGWIN.
+ (b) Arrange (via the Uopen() macro) for all calls to open() to have
+ the O_BINARY flag, to avoid CRLF problems.
+ (c) If OS_INIT is defined, call it at the very start of Exim's execution.
+ (d) When resolver debugging is enabled, set _res.options |= RES_DEBUG
+ before calling res_init() as well as after, because that generates
+ some debugging info during initialization.
+
+19. Make the initial call to os_getloadavg() in exim.c conditional on
+ LOAD_AVG_NEEDS_ROOT because it is done just to initialize os_getloadavg()
+ on systems that require the first call to be done as root. It should be
+ called only when messages are being received; it was being called
+ unnecessarily in some cases.
+
+20. If Exim failed to open its retry hints database at routing time, it crashed
+ during a subsequent local delivery.
+
+21. If Exim is neither setuid root nor called by root, there is no need to
+ attempt to drop root privilege when it is not needed.
+
+22. I'd forgotten to remove the check for the presence of %s in pid_file_path
+ when it was set at run time.
+
+23. If a transport filter crashed, or yielded a non-zero return code during an
+ SMTP delivery, Exim was not aborting the delivery. This led to multiple
+ partial deliveries of the message until the transport filter was fixed.
+
+24. Do not try alternate hosts if a transport filter crashes or yields a
+ non-zero return during an SMTP delivery.
+
+25. When exim -be is reading input lines from stdin, backslash can now be used
+ for continuations. This makes it easier to test expansions from a
+ configuration file by cut and paste, and long expansions in general.
+
+26. The file src/auths/xtextdecode.c was incorrectly named xtestdecode.c, but
+ because the MakeLinks script built a symbolic link that worked, this
+ mistake didn't actually show up.
+
+27. When Exim is delivering another message down an existing connection,
+ remote_max_parallel should be forced to 1; this wasn't happening, though
+ it would have caused a problem only if a message had more than 100
+ recipients routed to the host.
+
+28. When there was a problem while delivering down an existing connection, such
+ that the transport process closed the connection, this fact wasn't getting
+ communicated to the calling delivery process, which might have tried to do
+ more deliveries on the same connection. This would only have caused a
+ problem if there were more than 100 recipients to the same host.
+
+29. The ${extract} action, with a negative field number that selected the first
+ field in a string, could return junk characters at the start of the
+ extracted field.
+
+30. When Exim is acting as a client, if an attempt to start a TLS session fails
+ during the TLS negotiation phase (i.e. STARTTLS is accepted, but there's a
+ problem such as an unrecognized certificate during TLS session startup),
+ Exim used always to defer delivery. Now, unless the host is in
+ hosts_require_tls, Exim makes a new connection to the host and attempts to
+ send the message unencrypted. This avoids stuck messages for servers that
+ advertise STARTTLS but don't actually support it properly.
+
+31. Added ${address:xxx} to go with ${domain:xxx} and ${local_part:xxx} which
+ extract from RFC 2822 addresses.
+
+32. The rules for recognizing when Exim is being called from inetd have
+ changed. Previously Exim required SMTP input, stdin to be a TCP/IP socket,
+ and the caller to be root or the Exim user. This left a gaping hole if the
+ caller was not root or the Exim user, because then it wouldn't do the
+ policy checking for a remote host, because it didn't realize it was being
+ called from inetd. (This was seen on Debian configurations). Exim now
+ behaves as follows: if the input is SMTP and stdin is a TCP/IP socket, a
+ call from inetd is assumed. This is allowed to proceed either if the caller
+ is root or the Exim user, or if the port used is privileged (less than
+ 1024). Otherwise (a different user passing an unprivileged port) Exim gives
+ a "Permission denied" error.
+
+33. Removed $compile_number from the default SMTP banner line (after discussion
+ on the mailing list). Also removed it from the default $Received: header.
+
+34. # is documented as a comment character in the run time configuration only
+ when it appears at the start of a line. In the case of boolean values,
+ extra characters after "= true" or "= false" were being ignored, leading to
+ a false impression that comments could appear there. This is now diagnosed
+ as an error.
+
+35. If a boolean option without a following "=" was followed by # (in the
+ mistaken belief that this would be a comment), the error was "missing =",
+ which was confusing. Exim now complains about extra characters.
+
+36. When Exim complains about extra characters following an option setting, it
+ now adds a comment about comments if the first extra character is #.
+
+37. Output debug_print strings when testing a host using -bh.
+
+38. Added server_debug_print to authenticators (compare routers and
+ transports). This outputs when an authenticator is called as a server. It
+ can be helpful while testing with -bh.
+
+39. Added debugging output to the crypteq condition.
+
+40. If a named domain or local part list used in a "domains" or "local_parts"
+ option on a router matched by means of a lookup, the $domain_data and
+ $local_part_data variables were set for the first router that did this, but
+ were not set for any subsequent routers that used the same named list. The
+ same was true for multiple tests of named domain or local parts lists in an
+ ACL.
+
+41. If the variable "build" is set when the top-level Makefile is run, the
+ variable now propagates from the top-level Makefile to subsidiary ones.
+ In addition, Local/Makefile-$(build) is added to the list of concatenated
+ files that go at the start of the Makefile in the build directory.
+
+42. If NO_SYMLINK is defined in Local/Makefile, the exim_install script just
+ copies the Exim binary in with its unique name, without moving the "exim"
+ symbolic link to it.
+
+43. Added BSDI 4.2 as a BSDI variant in scripts/os-type.
+
+44. The spool file format for remembering a "one_time" redirection has changed;
+ I had forgotten to make Exim 4 capable of reading Exim 3 spool files.
+
+45. Address lists are now permitted to include items of the form *@+name where
+ "name" is a named domain list. (Note that an item of the form +name is
+ taken as a named _address_ list.)
+
+46. When Exim gives up privilege and reverts to the calling user because it was
+ called with the -C, -D, -be, or -bi options, it now reinstates the
+ supplementary group list as well as the uid and gid.
+
+47. The crypteq condition has been extended. When the encrypted string begins
+ with "{md5}" Exim used to assume that the digest was encoded as a base64
+ string. Now it assumes this only if its length is 24 bytes. If the length
+ is 32 bytes, Exim assumes a digest expressed in hex characters. If the
+ length is neither 24 nor 32, the comparison always fails.
+
+48. Updated the convert4r4 script:
+
+ (a) Some typos in the comments.
+ (b) Remove kill_ip_options, log_ip_options, and refuse_ip_options, which
+ no longer exist.
+ (c) Move all macro definitions to the top of the output, to ensure that
+ they precede any references to them.
+ (d) If tls_verify_ciphers was set without tls_verify_hosts, the generated
+ new configuration insisted on encryption ("these ciphers must be
+ used for all connections") instead of just checking the cipher when
+ encryption happened ("if encrypted, these ciphers must be used").
+ (e) Address lists are now checked to see if they contain any bare lookup
+ items and if they do, these are converted to two items, the first
+ preceded by "*@" and the second with "partial-" removed. This makes
+ Exim 4 behave in the way that Exim 3 used to. An explanatory comment
+ is output.
+ (f) Put more explanation in above the "hosts = :" test.
+
+49. Write a main and panic log entry when "partial-" is ignored in a lookup
+ that is part of an address list. (Applies when the item is a lookup for
+ which the whole address is the key.)
+
+50. Two changes to the way $original_local_part and $parent_local_part work:
+
+ (a) When an address that had a prefix or suffix was redirected to another
+ address, the value of $original_local_part and $parent_local_part
+ had the prefix or suffix stripped when referred to during the
+ processing of the child address. This doesn't seem right, so it has
+ been changed.
+ (b) When an address that had a prefix or suffix was being processed,
+ $local_part had the affix stripped, and if it was a top-level
+ address, $original_local_part also has the affix stripped. This has
+ been changed. Now $original_local_part contains the same value at all
+ levels. ($parent_local_part remains empty at top level.)
+
+51. A number of macros in the Exim source began with "DB_". When compiling
+ with Berkeley DB version 4, DB_LOCK_TIMEOUT clashed with a macro set by
+ that package. The Exim macros now all start with "EXIMDB_", and Exim
+ therefore now supports DB version 4.
+
+52. Newlines in a "freeze" text from a system filter were being sent as \n
+ in messages created by the "freeze_tell" option. They are now converted
+ back to newlines (in the log line they continue to appear as \n).
+
+53. Added a new ACL condition "verify = reverse_host_lookup". This does a
+ reverse lookup of the client host's IP address, then does a forward lookup
+ for all the names it receives, and checks that at least one of the IP
+ addresses obtained from the forward lookup matches the incoming IP address.
+ The lookups are done with gethostbyaddr() and gethostbyname(),
+ respectively.
+
+54. A small fix to eximstats reduces its store usage substantially when it is
+ processing very large log files: when a message's "completed" line is
+ reached, discard the memory of the message's size.
+
+55. If an address was redirected to itself more than once (e.g. by two
+ different "redirect" routers, or because of the use of "unseen", it was
+ incorrectly discarded as a duplicate address.
+
+56. For a rewrite pattern of the form *@something, if an actual address
+ contained @ in the local part (e.g. "a@b"@x.y), the value of $1 was set
+ incorrectly during expansion of the replacement address (it stopped at the
+ first @ instead of at the last one).
+
+57. Added hosts_nopass_tls to the smtp transport. For any host that matches
+ this list, a connection on which a TLS session has been started will not be
+ passed to a new delivery process for sending another message on the same
+ connection.
+
+58. The -dropcr command line option now turns CRLF into LF, while leaving
+ isolated CR characters alone. (Previously it removed _all_ CR characters.)
+ There is now also a drop_cr main option which has the effect of -dropcr for
+ all incoming non-SMTP messages.
+
+59. If a configuration file macro expanded into a boolean option which was not
+ followed by = and a value, Exim gave a spurious error for an "unknown"
+ value for the option (typically a string from the previous line).
+
+
+Exim version 3.952
+------------------
+
+ 1. convert4r4 had an incorrect file name in its comment output.
+
+ 2. convert4r4 was looking up $local_part instead of $domain in its generated
+ manualroute output.
+
+ 3. There was no check that getpeername() was giving a socket address when
+ called on stdin passed from a previous delivery.
+
+ 4. Fixed an old bug whereby Exim could segfault if debugging was turned on and
+ a DNS lookup found MX records for hosts whose A records had to be looked up
+ separately, and some of them pointed to the local host (pretty rare).
+
+ 5. The debugging output for log writes now shows the names of any log selectors
+ instead of the hex value of the selector word.
+
+ 6. If a delivery subprocess is terminated by SIGKILL or SIGQUIT, do not freeze
+ the message. This can happen during system shutdown. Other kinds of process
+ failure indicate problems.
+
+ 7. If a sender verification did not complete (e.g. DNS lookup timed out), the
+ log line for the temporary RCPT rejection did not always say why (it lost
+ the message if there had been a previous call to any lookup).
+
+ 8. The special message about MX records that point to IP addresses instead of
+ host names was not getting returned in the SMTP response when a
+ verification failed. This has been fixed, and the message that is logged in
+ this circumstance has been made less verbose.
+
+ 9. When an SMTP callout is done, Exim tries to use the interface and port
+ number from the transport that the address was routed to during the prior
+ verification. If it wasn't routed to a remote transport, or if there's a
+ problem expanding the relevant options, Exim does not use a specific
+ interface, and it connects to port 25.
+
+10. If the string "syslog" happened to occur in the log file path, eximon was
+ failing to extract the name of the main log file correctly.
+
+11. Unlike other operating systems, Linux does not sync a directory after a
+ rename. However, we need this to happen to be sure an incoming message has
+ been safely recorded after it has been received. I have therefore added a
+ macro called NEED_SYNC_DIRECTORY (which is set in OS/os.h_Linux) to request
+ Exim to do an explicit sync on the directory after the rename. If
+ O_DIRECTORY is defined, it is used when opening the directory.
+
+12. When a system filter creates any new deliveries, they are given a fake
+ "parent" address which appears on the logs, and is necessary for pipes,
+ files, and autoreplies, which cannot be toplevel addresses. This fake was
+ set up with the text "system filter". It's been changed to "system-filter"
+ because the space in the previous text could cause trouble.
+
+13. The new option local_sender_retain suppresses the removal of Sender: header
+ lines in locally-submited (non-TCP/IP) messages from untrusted users. It is
+ required that no_local_from_check be set with local_sender_retain.
+
+14. In a file interpolated into an address list, if a local part contained a
+ # character and there was also a following comment (introduced by a #
+ preceded by white space), the comment was not recognized.
+
+15. Local part lists are now handled as address lists as far as recognition of
+ comments in interpolated files and the processing of +caseful at the top
+ level are concerned. In the local_parts option of a router, +caseful will
+ restore case-sensitive matching, even when the router does not have
+ caseful_local_part set (the default).
+
+16. The key used for a dsearch lookup may not contain '/'. If it does, the
+ lookup defers.
+
+17. When starting a delivery process after receiving a message locally, discard
+ the controlling terminal unless debugging is turned on.
+
+18. The exim group was automatically trusted; this was not correct because it
+ meant that admin users who were in the exim group were automatically
+ trusted. If you want the exim group to be trusted, it must now be
+ explicitly configured.
+
+19. The default configuration mentioned "dns_lists" instead of "dnslists" in a
+ comment.
+
+20. Minor corrections and changes to the Exim4.upgrade document and to the
+ OptionLists.txt document.
+
+21. If a local part beginning with a pipe symbol was routed to a pipe
+ transport, the transport got confused as to which command it should run.
+ This could be a security exposure if unchecked local parts are routed to
+ pipe transports.
+
+22. When logging SMTP connections to the daemon from other hosts, include the
+ connection count in the log line. Tidied up the identification of SMTP
+ sources in logging lines.
+
+23. Added "sender_domains" as a new ACL condition so that the Exim 3 setting
+ of sender_verify_callback_domains can easily be replicated. Corrected
+ convert4r4, which was incorrectly converting this to a "domains" setting.
+
+24. The code for reading ident values was not discarding leading spaces, which
+ some hosts seem to send.
+
+25. The building process was still insisting that PID_FILE_PATH contained %s,
+ but this is not required for Exim 4.
+
+26. The logging of ETRN commands had got lost. It has been restored, and the
+ log selector "etrn" (on by default) added to control it.
+
+27. IPv6 reverse DNS lookups were originally specified as happening in the
+ ip6.int domain, but this is being changed to ip6.arpa (and they've changed
+ the meaning of "arpa" to "Address and Routing Parameters Area"). The only
+ time Exim does reverse lookups directly (as opposed to calling
+ gethostbyaddress()) is in the code for the dnsdb lookup type. This has been
+ changed to use ip6.arpa.
+
+28. Made the test programs (test_dbfn for testing DBM files, and some others)
+ compile! Updated the help output from test_dbfn.
+
+29. Changed all occurrences of "r" and "w" in fopen() fdopen() calls to "rb"
+ and "wb". This makes no difference in Unix systems, but is apparently
+ necessary for running Exim under Cygwin.
+
+30. Three changes that make virtually no difference when Exim is run on a real
+ Unix system, but which were asked for to make life easier when porting it
+ to run under Cygwin:
+
+ (a) Changed the logic for locking a message when an Exim process is
+ handling it. Previously, the entire -D file was locked to indicate
+ this. Now Exim locks only the first line, which contains the name of
+ the file. Apparently, in the Cygwin environment, a subprocess cannot
+ read locked parts of a file, even when it is passed an open file
+ descriptor to that file from the process that did the locking. By
+ locking only the first line, which the subprocess does not want to read
+ (it just needs to read the data that follows), we can get round this
+ restriction with minimal effort.
+
+ (b) Added support for native gdbm function calls. GDBM is apparently the
+ only DBM library that is currently available Cygwin, and only with its
+ native API.
+
+ (c) The default modes for files, directories, and lock files in the
+ appendfile transport can now be set in Local/Makefile at build time.
+
+31. When transmitting a message using SMTP with PIPELINING, if the server gave
+ a malformed SMTP response, the message logged by Exim didn't associate it
+ with the pipelined SMTP command to which it referred. For example it logged
+ "after DATA" if all the recipients had been sent. Also, if the response
+ was an empty line (illegal), it didn't show up very clearly. The error
+ messages are now more accurate, and point out empty lines.
+
+32. Minor corrections and changes to src/configure.default.
+
+33. When a host list in a route_list item that was enclosed in double quotes
+ contained single quotes within it, the quoting was incorrectly terminated.
+ Both the pattern and the host list in route_list items are now handled by
+ the standard quote-processing function.
+
+34. Corrected the EDITME file for eximon so that the default stripchart
+ patterns work with the default runtime configuration for local deliveries.
+ (Previously it matched a delivery via a director - not possible in Exim 4.)
+
+
+Exim version 3.951
+------------------
+
+Exim 3.951 is the first alpha testing release for Exim 4. A list the many
+individual changes to the code made between Exim 3.33 and Exim 3.951 was not
+kept. The functional changes are listed in the Exim4.upgrade file.
+
+****
diff --git a/doc/doc-txt/Exim3.upgrade b/doc/doc-txt/Exim3.upgrade
new file mode 100644
index 000000000..ee68ed136
--- /dev/null
+++ b/doc/doc-txt/Exim3.upgrade
@@ -0,0 +1,673 @@
+$Cambridge: exim/doc/doc-txt/Exim3.upgrade,v 1.1 2004/10/07 15:04:35 ph10 Exp $
+
+This document contains information about upgrading Exim to the last of the 3.xx
+releases. It is provided to help anybody who is upgrading to release 4.xx from
+a release that is earlier than 3.33. It goes back as far as release 2.12. If
+you are upgrading to release 4.xx from an even earlier release, it is probably
+best to start again from the default configuration.
+
+
+Upgrading from release 3.16
+---------------------------
+
+1. The way LDAP returns values for multiple attributes has been changed to be
+the same as the NIS+ lookup.
+
+If you specify multiple attributes, they are returned as space-separated
+strings, quoted if necessary.
+
+e.g. ldap:///o=base?attr1,attr2?sub?(uid=fred)
+
+ used to give: attr1=value one, attr2=value2
+ now gives: attr1="value one" attr2=value2
+
+If you don't specify any attributes in the search, you now get them in
+the tagged format as well.
+
+e.g. ldap:///o=base??sub?(uid=fred)
+
+ used to give: top, value one, value2
+ now gives: objectClass=top attr1="value one" attr2=value2
+
+The reason for these changes is so that the results can be safely parsed -
+in fact, the existing ${extract{key}{val}} function does this nicely.
+This in turn allows a single LDAP query to be reused - one query can return
+the destination delivery address, the quota, and so forth.
+
+This is NOT a backwards compatible change, so there is a compile-time option
+to reverse it in the src/lookups/ldap.c module, for use in emergency. But it is
+not thought that the old behaviour was particularly useful as it stood, because
+a field that contained ',' or '=' would make the result unparseable.
+
+In the common case where you explicitly ask for a single attribute in your
+LDAP query, the behaviour is unchanged - the result is not quoted, and if there
+are multiple values they are comma-separated.
+
+2. The hosts_max_try option in the smtp transport limits the number of IP
+addresses that will actually be tried during one delivery attempt. The default
+is 5. Previously, all available addresses were tried.
+
+3. The extension of the "extract" expansion item has resulted in a change to
+the way Exim decides between the keyed form and the numeric form. If the first
+argument consists entirely of digits, the numeric form is assumed. This means
+that it is impossible to have keys that are digit strings, without manipulating
+the data first (e.g. by using ${sg} to add a letter to each key).
+
+
+Upgrading from release 3.15
+---------------------------
+
+1. The handling of "freeze" and "fail" in system filter files has changed.
+Previously, any deliveries set up by a filter that ended with "freeze" or
+"fail" were discarded. This no longer happens; such deliveries are honoured.
+A consequence of this is that first_delivery becomes false after freezing in a
+system filter; previously it remained true until a real delivery attempt
+happened.
+
+
+Upgrading from release 3.13
+---------------------------
+
+1. The handling of maildir_tag has been changed (see NewStuff). There are two
+small incompatibilities: (a) Exim now inserts a leading colon only if the
+string begins with an alphanumeric character. So if you were using a string
+starting with a special character, you will have to add the leading colon to
+it to remain compatible. (b) The expansion of maildir_tag now happens after the
+file has been written, and $message_size is updated to the correct file size
+before the expansion. The tag is not used on the temporary file (it was
+previously).
+
+2. The handling of Exim's configuration has changed in two ways:
+
+ (a) Any line may be continued by ending it with a backslash. Trailing white
+ space after the backslash, and leading white space on continuation lines is
+ ignored. This means that quotes are no longer needed just to make it possible
+ to continue an option setting. The difference between quoted and non-quoted
+ strings is that quoted strings are processed for internal backslashed items
+ such as \n. The only possible incompatibility of this change is if any
+ existing configuration has a non-quoted line ended in backslash, which seems
+ a very remote possibility.
+
+ (b) All lists, with the exception of log_file_path, can now use a different
+ character to colon as the separator. This is specified by starting the list
+ with <x where x is any punctuation character. For example:
+
+ local_interfaces = <; 127.0.0.1 ; ::1
+
+ The new feature is provided to make life easier with IPv6 addresses. It is
+ recommended that its use be confined to circumstances where it really is
+ needed, and that colon be used in most cases. I don't believe this change
+ is incompatible, because I don't think any list item can legitimately begin
+ with a '<' character.
+
+3. Previously, Exim took no action to ensure that the timestamps in its log
+files were "wall clock time". If the TZ environment variable was set when Exim
+was called, it could cause strange times to be logged. For the majority of
+operating systems, I have been able to fix this problem by deleting the entire
+environment. However, this doesn't work in some systems, and a macro called
+HANDS_OFF_ENVIRONMENT is defined in their OS/os.h files to suppress the action.
+These OS are: AIX, DGUX, HP-UX, IRIX, and SCO, and their behaviour should be
+unchanged from previous releases. On any other OS, if you find you are getting
+weird timestamps, it may be that your OS needs HANDS_OFF_ENVIRONMENT.
+
+4. As a result of the change described in 3, there may be some cases where Exim
+runs an external program that previously got passed the environment, and now do
+not. This does *not* apply to the pipe transport, where the environment has
+always been set up specifically, as described in the manual.
+
+5. The way in which Exim scans its queue when split_spool_directory is set has
+changed, but this shouldn't make any noticeable difference. See doc/NewStuff
+for defails.
+
+
+Upgrading from release 3.03
+---------------------------
+
+The from_hack option in the appendfile and pipe transports has been replace by
+two string options, check_string and escape_string. If your configuration
+contains any references to from_hack they should be replaced. Exim continues to
+recognize from_hack as a transitional measure. If no_from_hack is specified in
+an appendfile transport, the two new options are forced to be unset. Otherwise
+the setting of from_hack is ignored.
+
+
+Upgrading from release 3.02
+---------------------------
+
+The exim_dbmbuild utility has been changed to write a warning to stderr on
+encountering a duplicate key, and to return a value of 1. Formerly, it ignored
+all but the last of a set of duplicates; now it ignores all but the first, to
+make dbm-searched files behave the same way as lsearch-searched files. However,
+there is an option -lastdup which makes it behave as before. The -nowarn option
+suppresses the individual warnings, but the number of duplicates is always
+listed on stdout at the end.
+
+
+Updating from a release prior to 3.00
+-------------------------------------
+
+Prior to release 3.00 a lot of options which contained lists of various kinds
+came in groups such as sender_accept, sender_reject, sender_reject_except. This
+style of configuration has been abolished. Instead, it is now possible to put
+negative entries in such lists, so that a single option is all that is
+required. In addition to this, net lists have been abolished, and instead,
+host lists can now contain items that specify networks as well as hosts. The
+names of some of these options have also been changed.
+
+As a result of these changes, most configuration files used for earlier
+versions of Exim need to be changed. The opportunity has therefore been taken
+to remove a number of other obsolete features and options.
+
+A Perl script is built in the file util/convert4r3 to assist in updating Exim
+configuration files. It reads a configuration file on the standard input,
+writes a modified file on the standard output, and writes comments about what
+it has done to the standard error file. It assumes that the input is a valid
+Exim configuration file. A typical call to the conversion script might be
+
+ util/convert4r3 </opt/exim/configure >/opt/exim/configure.new
+
+The way the script merges an accept/reject/reject_except triple into a single
+accept option is to put the reject_except list first, followed by the reject
+list with every item negated, followed by the accept list. For example, if an
+old configuration file contains
+
+ sender_host_accept_relay = *.c.d : e.f.g
+ sender_host_reject_relay = *.b.c.d
+ sender_host_reject_relay_except = a.b.c.d
+
+the new configuration will contain
+
+ host_accept_relay = a.b.c.d : ! *.b.c.d : *.c.d : e.f.g
+
+The same ordering is used to merge a triple into a reject option, but this time
+the first and third sublists are negated. For example, if an old configuration
+file contains
+
+ sender_host_accept = *.c.d : e.f.g
+ sender_host_reject = *.b.c.d
+ sender_host_reject_except = a.b.c.d
+
+the new configuration file will contain
+
+ host_reject = ! a.b.c.d : *.b.c.d : ! *.c.d : ! e.f.g : *
+
+The output file should be checked before trying to use it. Each option change
+is preceded by an identifying comment. There are several specific things that
+you should look out for when checking:
+
+(1) If you are using macros to contain lists of items, and these have to be
+ negated in the new world, convert4r3 won't get it right. For example, if
+ the old configuration contains
+
+ ACCEPTHOSTS = *.c.d : e.f.g
+ sender_host_reject = ACCEPTHOSTS
+
+ then the rewritten configuration will be
+
+ ACCEPTHOSTS = *.c.d : e.f.g
+ host_reject = !ACCEPTHOSTS
+
+ but because this is just textual macro handling, that is equivalent to
+
+ host_reject = !*.c.d : e.f.g
+
+ which is not the correct translation, because the second item is not
+ negated. There is unfortunately no easy way to use a macro to provide a
+ list of things that are sometimes negated.
+
+(2) The conversion adds some settings of file_transport, pipe_transport, and
+ reply_transport to aliasfile and forwardfile directors. This is done
+ because the global implicit defaults for these options have been removed.
+ The default configuration now contains explicit settings, so convert4r3
+ makes these additions to be compatible with that. If your aliasfile and
+ forwardfile directors do not make use of the pipe, file, or autoreply
+ facilities, you can remove these new settings.
+
+(3) If you are using +allow_unknown in a host list which also has an exception
+ list, you may need to move +allow_unknown in the new configuration. For
+ example, if the old configuration contains
+
+ sender_host_reject = +allow_unknown : *.b.c
+ sender_host_reject_except = *.a.b.c
+
+ then the rewritten configuration will be
+
+ host_reject = ! *.a.b.c : +allow_unknown : *.b.c
+
+ Because the negated item contains a wild card, the reverse lookup for the
+ host name will occur before +allow_unknown is encountered, and therefore
+ +allow_unknown will have no effect. It should be moved to the start of the
+ list.
+
+One way of upgrading Exim from a pre-3.00 release to a post-3.00 release is as
+follows:
+
+1. Suppose your configuration file is called /opt/exim/configure, and you want
+ to continue with this name after upgrading. The first thing to do is to make
+ another copy of this file called, say, /opt/exim/configure.pre-3.00.
+
+2. Rebuild your existing Exim to use the copy of the configuration file instead
+ of the standard file. Install this version of Exim under a special name such
+ as exim-2.12, and point a symbolic link called "exim" at it. Then HUP your
+ daemon. You can check on the name of the configuration file by running
+
+ exim -bP configure_file
+
+ Ensure that everything is running smoothly.
+
+3. Build the new release, configured to use the standard configuration file.
+
+4. Use the convert4r3 utility to upgrade your configuration file for the new
+ release. After running it, check the file by hand.
+
+5. If any of the options that convert4r3 rewrote contained regular expressions
+ that had backslashes in them, and were not previously in quotes, they will
+ need modification if convert4r3 has put them into quotes. Either re-arrange
+ the option to remove the quoting, or escape each backslash. For example, if
+ you had
+
+ sender_reject_recipients = ^\d{8}@
+ sender_reject_except = ^\d{8}@x.y.z
+
+ convert4r3 will have combined the two settings into
+
+ sender_reject_recipients = "! ^\d{8}@x.y.z : \
+ ^\d{8}@"
+
+ This must be changed to
+
+ sender_reject_recipients = ! ^\d{8}@x.y.z : ^\d{8}@
+ or
+ sender_reject_recipients = "! ^\\d{8}@x.y.z : ^\\d{8}@"
+
+ In the second case, the quoted string could of course still be split
+ over several lines.
+
+6. If your configuration refers to any external lists of networks, check them
+ to ensure that all the masks are in the single-number form, because Exim no
+ longer recognizes the dotted quad form of mask. For example, if an item in
+ a netlist file is
+
+ 131.111.8.0/255.255.255.0
+
+ you must change it to
+
+ 131.111.8.0/24
+
+ Otherwise Exim will not recognize it as a masked IP address, and will treat
+ it as a host name. The convert4r3 utility makes this conversion for networks
+ that are mentioned inline in the configuration, but it does not handle
+ referenced files.
+
+7. Check the newly-built Exim as much as possible without installing; you can,
+ for example, use a command such as
+
+ ./exim -bV
+
+ in the build directory to test that it successfully reads the new
+ configuration file. You can also do tests using -bt and -bh.
+
+8. Install the new release under a special name such as exim-3.00.
+
+9. You can then easily change between the new and old releases simply by moving
+ the symbolic link and HUPping your daemon.
+
+
+Details of syntax changes at 3.00
+=================================
+
+1. A bare file name without a preceding search type may appear in a domain
+list; this causes each line of the file to be read and processed as if it were
+an item in the list, except that it cannot itself be a bare file name (that is,
+this facility cannot be used recursively). Wild cards and regular expressions
+may be used in the lines of the file just as in the main list.
+For example, if
+
+ local_domains = /etc/local-domains
+
+then the file could contain lines like
+
+ *.mydomain.com
+
+This is different to an lsearch file, which operates like any other lookup type
+and does an exact search for the key. If a # character appears anywhere in a
+line of the file, it and all following characters are ignored. Blank lines are
+also ignored.
+
+2. Any item in a domain list (including a bare file name) can be preceded by an
+exclamation mark character, to indicate negation. White space after the ! is
+ignored. If the domain matches the rest of the item, it is *not* in the set of
+domains that the option is defining. If the end of the list is reached, the
+domain is accepted if the last item was a negative one, but not if it was a
+positive one. If ! precedes a bare file name, then all items in the file are
+negated, unless they are preceded by another exclamation mark. For example:
+
+ relay_domains = !a.b.c : *.b.c
+
+sets up a.b.c as an exception to the more general item *.b.c, because lists are
+processed from left to right. If the domain that is being checked matches
+neither a.b.c nor *.b.c, then it is not accepted as a relay domain, because the
+last item in the list is a positive item. However, if the option were just
+
+ relay_domains = !a.b.c
+
+then all domains other than a.b.c would be relay domains, because the last item
+in the list is a negative item. In effect, a list that ends with a negative
+item has ": *" appended to it.
+
+3. Negation and bare file names are available as above in lists of local parts
+(e.g. in local_parts options) and complete addresses (address lists). For the
+special "@@" lookup form in address lists, negation also can be used in the
+list of local parts that is looked up for the domain. For example, with
+
+ sender_reject_recipients = @@dbm;/etc/reject-by-domain
+
+the file could contain lines like this:
+
+ baddomain.com: !postmaster : !hostmaster : *
+
+If a local part that actually begins with ! is required, it has to be specified
+using a regular expression. Because local parts may legitimately contain #
+characters, a comment in the file is recognized only if # is followed by white
+space or the end of the line.
+
+4. Host lists may now contain network items, as in the former net list options,
+which have all been abolished. The only form of network masking is the /n
+variety. Negation and bare file names can appear in host lists, and there is a
+new type of item which allows masked network numbers to be used as keys in
+lookups, thus making it possible to used DBM files for faster checking when the
+list of networks is large.
+
+The complete list of types of item which can now appear in a host list is:
+
+. An item may be a bare file name; each line of the file may take the form of
+ any of the items below, but it may not itself be another bare file name. If
+ the file name is preceded by ! then all items in the file are negated, unless
+ they are preceded by another exclamation mark. Comments in the file are
+ introduced by # and blank lines are ignored.
+
+. If the entire item is "*" it matches any host.
+
+. If the item is in the form of an IP address, it is matched against the IP
+ address of the incoming call.
+
+. If the item is in the form of an IP address followed by a slash and a mask
+ length (e.g. 131.111.0.0/16) then it is matched against the IP address of the
+ incoming call, subject to the mask.
+
+. If the item is of the form "net<number>-<search-type>;<search-data>", for
+ example:
+
+ net24-dbm;/networks.db
+
+ then the IP address of the incoming call is masked using <number> as the mask
+ length; a textual string is then constructed from the masked value, followed
+ by the mask, and this is then used as the key for the lookup. For example, if
+ the incoming IP address is 192.152.34.6 then the key that is looked up for
+ the above example is "192.152.34.0/24".
+
+. If the entire item is "@" the primary host name is used as the the match
+ item, and the following applies:
+
+. If the item is a plain domain name, then a forward DNS lookup is done on that
+ name to find its IP address(es), and the result is compared with the IP
+ address of the incoming call.
+
+The remaining items require the host name to be obtained by a reverse DNS
+lookup. If the lookup fails, Exim takes a hard line by default and access is
+not permitted. If the list is an "accept" list, Exim behaves as if the current
+host is not in the set defined by the list, whereas if it is a "reject" list,
+it behaves as if it is.
+
+To change this behaviour, the special item "+allow_unknown" may appear in the
+list (at top level - it is not recognized in an indirected file); if any
+subsequent items require a host name, and the reverse DNS lookup fails, Exim
+permits the access, that is, its behaviour is the opposite to the default.
+
+. If the item starts with "*" then the remainder of the item must match the end
+ of the host name. For example, *.b.c matches all hosts whose names end in
+ .b.c. This special simple form is provided because this is a very common
+ requirement. Other kinds of wildcarding require the use of a regular
+ expression.
+
+. If the item starts with "^" then it is taken to be a regular expression which
+ is matched against the host name. For example, ^(a|b)\.c\.d$ matches either
+ of the two hosts a.c.d or b.c.d. If the option string in which this occurs is
+ given in quotes, then the backslash characters must be doubled, because they
+ are significant in quoted strings. The following two settings are exactly
+ equivalent:
+
+ host_accept = ^(a|b)\.c\.d$
+ host_accept = "^(a|b)\\.c\\.d$"
+
+. If the item is of the form <search-type>;<filename or query>, for example
+
+ dbm;/host/accept/list
+
+ then the host name is looked up using the search type and file name or query
+ (as appropriate). The actual data that is looked up is not used.
+
+5. Early versions of Exim required commas and semicolons to terminate option
+settings in drivers. This hasn't been the case for quite some time. The code to
+handle them has now been removed.
+
+
+Details of option changes at 3.00
+=================================
+
+Main options
+------------
+
+ * address_directory_transport, address_directory2_transport,
+ address_file_transport, address_pipe_transport, and address_reply_transport
+ have been abolished as obsolete. The aliasfile and forwardfile directors
+ have been able for some time to set the transports they want to use for
+ these special kinds of delivery; there seems little need for global
+ defaults. The default configuration has been altered to add settings for
+ file_transport and pipe_transport to the aliasfile and forwardfile
+ directors, and to add reply_transport to forwardfile.
+
+ * check_dns_names, a deprecated synonym for dns_check_names, has been
+ abolished.
+
+ * helo_accept_junk_nets is abolished; nets can now appear in
+ helo_accept_junk_hosts.
+
+ * helo_verify_except_hosts and helo_verify_except_nets have been abolished,
+ and helo_verify has been changed from a boolean to a host list, listing
+ those hosts for which HELO verification is required.
+
+ * the obsolete option helo_verify_nets (a synonym for host_lookup_nets) has
+ been abolished. Note that host_lookup_nets itself has been replaced by
+ host_lookup.
+
+ * hold_domains_except has been abolished. Use negated items in hold_domains.
+
+ * host_lookup_nets has been replaced by host_lookup, which can contain hosts
+ and nets.
+
+ * ignore_fromline_nets has been replaced by ignore_fromline_hosts.
+
+ * If message_filter is set and the filter generates any deliveries to files,
+ pipes, or any autoreplies, then the appropriate message_filter_*_transport
+ options must be set to define the transports, following the abolition of
+ the global defaults (see above).
+
+ * queue_remote and queue_remote_except have been abolished and replaced by
+ queue_remote_domains, which lists those domains that should be queued. The
+ effect of queue_remote=true is now obtained by queue_remote_domains=*.
+
+ * queue_smtp and queue_smtp_except have been abolished and replaced by
+ queue_smtp_domains, which lists those domains that should be queued after
+ routing. The effect of queue_smtp=true is now obtained by
+ queue_smtp_domains=*.
+
+ * rbl_except_nets has been abolished and replaced by rbl_hosts, which can
+ contain hosts and nets. This defaults to "*" and defines the set of hosts
+ for which RBL checking is done.
+
+ * receiver_unqualified_nets is abolished; nets can now appear in
+ receiver_unqualified_hosts.
+
+ * receiver_verify_except_hosts and receiver_verify_except_nets have been
+ abolished and replaced by receiver_verify_hosts, which defaults to "*".
+ This is used, however, only when receiver_verify is set - together with the
+ other conditions (receiver_verify_addresses, receiver_verify_senders).
+
+ * receiver_verify_senders_except has been abolished; the functionality is now
+ available by using negation in receiver_verify_senders.
+
+ * rfc1413_except_hosts and rfc1413_except_nets have been abolished, and
+ replaced by rfc1413_hosts, which defaults to "*".
+
+ * sender_accept, sender_accept_recipients and sender_reject_except have
+ been abolished; the functionality is now available via sender_reject and
+ sender_reject_recipients.
+
+ * sender_host_accept, sender_net_accept, sender_host_reject,
+ sender_net_reject, sender_host_reject_except, sender_net_reject_except,
+ sender_host_reject_recipients and sender_net_reject_recipients
+ have all been abolished, and replaced by the options host_reject and
+ host_reject_recipients.
+
+ * sender_host_accept_relay, sender_net_accept_relay,
+ sender_host_reject_relay, sender_host_reject_relay_except,
+ sender_net_reject_relay, and sender_net_reject_relay_except are abolished,
+ and replaced by host_accept_relay. This defaults unset, and this means that
+ all relaying is now by default locked out in the Exim binary. Previously,
+ if no relaying options were set, relaying was permitted.
+
+ * sender_unqualified_nets has been abolished; nets can now appear in
+ sender_unqualified_hosts.
+
+ * sender_verify_except_hosts and sender_verify_except_nets have been
+ abolished and replaced by sender_verify_hosts, which defaults to "*". This
+ is used, however, only when sender_verify is set (to make it similar to
+ receiver_verify, even though there aren't at present any other conditions.)
+
+ * sender_verify_log_details has been abolished. This was a little-used
+ debugging option.
+
+ * smtp_etrn_nets has been abolished; nets can now appear in smtp_etrn_hosts.
+
+ * smtp_expn_nets has been abolished; nets can now appear in smtp_expn_hosts.
+
+ * smtp_log_connections, a deprecated synonym for log_smtp_connections, has
+ been abolished.
+
+ * smtp_reserve_nets is abolished; nets can now appear in smtp_reserve_hosts.
+
+Generic director and router options
+-----------------------------------
+
+ * except_domains, except_local_parts, and except_senders have been abolished.
+ Use negated items in domains, local_parts, and senders instead, for
+ example, replace
+
+ except_domains = a.b.c
+
+ with
+
+ domains = !a.b.c
+
+ If you already have a domains setting, add any negative items to the front
+ of it.
+
+The aliasfile director
+----------------------
+
+ * The option "directory", an obsolete synonym for home_directory, has been
+ abolished.
+
+The forwardfile director
+------------------------
+
+ * The option "directory", an obsolete synonym for file_directory, has been
+ abolished.
+
+ * The option forbid_filter_log, an obsolete synonym for
+ forbid_filter_logwrite, has been abolished.
+
+The localuser director
+----------------------
+
+ * The option "directory", an obsolete synonym for match_directory, has been
+ abolished.
+
+The lookuphost router
+---------------------
+
+ * mx_domains_except and its obsolete old name non_mx_domains have been
+ abolished. Use negated items in mx_domains.
+
+The pipe transport
+------------------
+
+ * The option "directory", an obsolete synonym for home_directory, has been
+ abolished.
+
+The smtp transport
+------------------
+
+ * mx_domains_except and its obsolete old name non_mx_domains have been
+ abolished. Use negated items in mx_domains.
+
+ * serialize_nets has been abolished; nets may now appear in serialize_hosts.
+
+
+Other items relevant to upgrading from Exim 2.12
+================================================
+
+1. RFC 2505 (Anti-Spam Recommendations for SMTP MTAs) recommends that the
+checking of addresses for spam blocks should be done entirely caselessly.
+Previously, although Exim retained the case of the local part, in accordance
+with the RFC 821 rule that local parts are case sensitive, some of the string
+comparisons were nevertheless done caselessly, but file lookups used the
+unmodified address.
+
+The way addresses are compared with options whose values are address lists has
+been changed. At the start of the comparison, both the local part and the
+domain are now forced to lower case, and any comparisons that are done with
+in-line strings are done caselessly. For example,
+
+ sender_reject = A@b.c
+
+rejects both A@b.c and a@b.c. Any lookups that occur use lowercased strings as
+their keys. If the @@ lookup facility is used, the lookup is done on the lower
+cased domain name, but any subsequent string comparisons on local parts are
+done caselessly.
+
+To retain possibility of caseful matching, the pseudo-item "+caseful" can
+appear in an address list. It causes any subsequent items to do caseful matches
+on local parts. The domain, however, remains lower cased.
+
+2. The handling of incoming batched SMTP has been re-worked so as to behave in
+a more useful way in cases of error:
+
+ (i) The option sender_verify_batch now defaults false.
+ (ii) EOF is no longer interpreted as end-of-message; the "." line must be
+ present.
+ (iii) Exim stops immediately in cases of error, writing information to stdout
+ and stderr, and setting the return code to 1 if some messages have been
+ accepted, and 2 otherwise.
+
+3. The first message delivered by -R, and all messages delivered by -Rf and -qf
+are "forced" in the sense that retry information is over-ridden. Previously,
+Exim also forcibly thawed any of these messages that was frozen. This no longer
+happens. Additional options -Rff and -qff have been implemented to force
+thawing as well as delivery.
+
+4. When recipients are being rejected because the sending host is in an RBL
+list, Exim used just to show the RBL text, if any, as part of the rejection
+response. Now, if prohibition_message is set, it expands that string instead,
+with the RBL message available in $rbl_text, and $prohibition_reason set to
+"rbl_reject".
+
+5. When a trusted caller passed a message to Exim, it used to check the From:
+header against the caller's login (even though the caller was trusted) unless
+the -f option had been used to supply a different sender. This has been changed
+so that From: is never checked if the caller is trusted.
+
+Philip Hazel
+May 1999
+
diff --git a/doc/doc-txt/Exim4.upgrade b/doc/doc-txt/Exim4.upgrade
new file mode 100644
index 000000000..db20d5dd6
--- /dev/null
+++ b/doc/doc-txt/Exim4.upgrade
@@ -0,0 +1,1732 @@
+$Cambridge: exim/doc/doc-txt/Exim4.upgrade,v 1.1 2004/10/07 15:04:35 ph10 Exp $
+
+Upgrading Exim from Release 3.33 to 4.xx
+----------------------------------------
+
+Exim 4.00 represents the largest upheaval in Exim's history. There are a lot of
+changes to the way some parts of Exim work, and a lot of incompatible changes
+to the run time configuration file.
+
+This document is in two parts. The first part contains instructions and
+suggestions for how you might go about performing the upgrade. The second part
+is a brief list of all the changes that have taken place. For full details of
+all the new features, please consult the current version of the reference
+manual.
+
+
+HOW TO UPGRADE YOUR EXIM
+------------------------
+
+When you compile Exim 4, a Perl script called convert4r4 is built in the build
+directory. It is not installed by the install script, because it is likely that
+you will run it only once.
+
+This script is provided to assist in updating Exim configuration files. It
+reads an Exim 3 configuration file on the standard input, and writes a modified
+file on the standard output. It also writes comments about what it has done to
+the standard error file. It assumes that the input is a valid Exim 3
+configuration file. A typical call to the conversion script might be
+
+ ./convert4r4 </etc/exim/configure >/etc/exim/configure.new
+
+The output file MUST be checked and tested before trying to use it on a live
+system. The conversion script is just an aid which does a lot of the "grunt
+work". It does not guarantee to produce an Exim 4 configuration that behaves
+exactly the same as the Exim 3 configuration it reads.
+
+Each option change in the new file is preceded by an identifying comment. In
+fact, the conversion script tends to make quite a mess of your configuration,
+and you should expect to go through it afterwards and tidy it up by hand.
+
+Unless you are running a very straightforward configuration, the automatic
+conversion is likely to generate a non-optimal configuration. You should not
+only check it thoroughly, but also run as many tests as you can, to ensure that
+it is working as you expect. In particular, you should test address routing,
+using -bt and -bv, and the policy controls, using -bh. If possible, you should
+also do some live tests (i.e. send and receive some messages) before putting
+Exim 4 into service.
+
+If you have a very complicated configuration, it is possible that convert4r4
+will break it in some situations, which is why thorough testing is strongly
+recommended.
+
+ *********************************
+ ***** You Have Been Warned ******
+ *********************************
+
+
+HOW TO MOVE FROM AN EXIM 3 RELEASE TO AN EXIM 4 RELEASE
+-------------------------------------------------------
+
+One way of upgrading to Exim 4 from a version 3 release is as follows:
+
+1. Suppose your run time configuration file is called /usr/exim/configure, and
+ you want to continue with this name after upgrading. The first thing to do
+ is to make another copy of this file called, say, /usr/exim/configure.r3.
+
+2. Rebuild your existing Exim to use the copy of the run time configuration
+ file instead of the standard file. Install this version of Exim and HUP your
+ daemon. You can check on the name of the configuration file by running
+
+ exim -bP configure_file
+
+ Ensure that everything is running smoothly. You now have something you can
+ fall back to. IMPORTANT: when you do this re-install, you should also
+ re-install the utilities because four of them (exicyclog, eximon, exinext,
+ and exiwhat) also refer to the configuration file.
+
+3. Build the new release, configured to use the standard configuration file.
+
+4. Use the convert4r4 utility to upgrade your configuration file for the new
+ release. After running the conversion utility, check the file by hand, and
+ tidy it up.
+
+5. Test, test, test! And test some more!
+
+6. You can run complete tests, including actual deliveries, from an uninstalled
+ binary, but you have to tell it where it is, so that any re-executions can
+ be done. You can do this by temporarily inserting a setting such as
+
+ exim_path = /source/exim/exim-4.00/build-SunOS5-5.8-sparc/exim
+
+ into the run time configuration. If you want to, you can also insert
+ settings for spool_directory and log_file_path to divert those away from
+ their normal places. Remember to remove these temporary settings when you
+ eventually install the binary for real.
+
+7. The new installation script installs the new release as exim-4.00-1, and
+ set a symbolic link called "exim" to point to it. The old version of Exim
+ will be renamed to something like exim-3.33-1.
+
+8. You can now easily change between the new and old releases simply by moving
+ the symbolic link and HUPping your daemon. The format of message files on
+ Exim's spool has _not_ changed, so there should be no problem in changing
+ between releases while there are messages on the queue.
+
+9. HOWEVER: If you do change back and forth between releases, you must also
+ change the utilities exicyclog, eximon, exinext, and exiwhat if you are
+ going to use them. Installing Exim 4 will have left the old versions with a
+ .O suffix. It might be helpful to rename these so that you don't lose them.
+
+
+WHAT HAS NOT CHANGED IN EXIM 4.00
+---------------------------------
+
+The basic overall philosophy, design, and process structure has not changed.
+The format of spool files is the same. The transports have had only minor
+modifications. The command line options remain the same, with a couple of
+additions.
+
+The general run time configuration approach has not changed, but the actual
+details of the configuration file are different.
+
+The Exim monitor has not changed, and there have been only very minor changes
+to other Exim utilities.
+
+
+WHAT HAS CHANGED IN EXIM 4.00
+-----------------------------
+
+The rest of this document lists the very many changes that have taken place.
+I'm going to give only brief details here, because this part of the document is
+intended as a way of alerting you to areas of difference. The reference manual
+describes how the new features work in detail.
+
+
+Named domain, host, address, and local part lists
+-------------------------------------------------
+
+A new feature makes it possible to give names to lists of domains, hosts,
+addresses, and local parts. The syntax used is
+
+ domainlist <name> = <a domain list>
+ hostlist <name> = <a host list>
+ addresslist <name> = <an address list>
+ localpartlist <name> = <a list of local parts>
+
+For example:
+
+ domainlist local_domains = *.my.domain
+ addresslist bad_senders = cdb;/etc/badsenders
+
+These lists are referenced in options by giving the name preceded by a + sign.
+For example, in a router you might have
+
+ domains = +local_domains
+
+At first sight, these lists might seem to be the same as macros, but they are
+not. Macros are just textual substitutions. If you write
+
+ ALIST = host1 : host2
+ auth_advertise_hosts = !ALIST
+
+it probably won't do what you want, because that is exactly the same as
+
+ auth_advertise_hosts = !host1 : host2
+
+Notice that the second host name is not negated. However, if you use a host
+list, and write
+
+ hostlist alist = host1 : host2
+ auth_advertise_hosts = ! +alist
+
+the negation applies to the whole list, and so that is equivalent to
+
+ auth_advertise_hosts = !host1 : !host2
+
+These named lists also have a performance advantage. When Exim is routing an
+address or checking an incoming message, it caches the result of tests on the
+lists. So, if you have a setting such as
+
+ domains = +local_domains
+
+on several of your routers, the actual test is done only for the first one.
+However, this caching works only if there are no expansions within the list
+itself or any sublists that it references. In other words, caching happens only
+if the list is known to be the same each time it is referenced.
+
+By default, there may be up to 16 named lists of each type. This limit can be
+extended by changing a compile-time variable.
+
+The use of domain and host lists is recommended for concepts such as local
+domains, relay domains, and relay hosts. The default configuration is set up
+like this.
+
+
+Processing of domain, host, local part, and address lists
+---------------------------------------------------------
+
+The handling of these lists is now more uniform. Every list is expanded as a
+single string before it is used. (In Exim 3, some options were expanded and
+some weren't, and query-style lookup items were then re-expanded.)
+
+If an expansion is forced to fail, Exim behaves as if the item has not been
+found in the list.
+
+The confusing $key variable has been abolished. When processing a domain list,
+$domain contains the relevant domain and can be used in generating database
+queries. Other appropriate variables are set when processing other kinds of
+list; $sender_host and $sender_host_address for checking incoming hosts and
+$host and $host_address for checking outgoing hosts.
+
+Note that this means that any \ and $ characters in regular expressions must be
+escaped if they appear in one of these lists. The new expansion feature to turn
+off expansion (\N ... \N) which is described below can be helpful here.
+
+IMPORTANT: The details of the processing of address lists has been revised. In
+particular, the handling of the case of an item that is a single-key lookup has
+changed. It no longer looks up the domain on its own before looking up the
+complete address. You need to supply an explicit "*@" before the lookup if you
+want just the domain to be looked up. Please check the manual for full details.
+
+If an item in a host list is the empty string, it matches only when no host is
+defined. If used when checking an incoming message, it matches only when the
+message is arriving by SMTP on the standard input from a local process (using
+-bs). This provides a way of distinguishing between SMTP mail from local
+processes and from remote hosts.
+
+The +allow_unknown and +warn_unknown settings for host lists have been replaced
+by a single item, +include_unknown. By default, failure to find a host name
+when needed causes Exim to behave as if the host does not match the list, but
+if +include_unknown is set, the opposite behaviour happens. Whenever
++include_unknown is invoked, the incident is logged.
+
+
+Merge of Directors and Routers
+------------------------------
+
+There are no longer any directors in Exim 4. There are just routers. All
+addresses are passed to a single list of routers which typically makes use of
+the "domains" option to choose which way to handle specific groups of domains.
+
+A consequence of this is that the code no longer contains any concept of "local
+domains". However, a typical configuration will probably define a named domain
+list (see above) called local_domains, and use it to control routing something
+like this:
+
+ route_remote:
+ driver = dnslookup
+ domains = ! +local_domains
+ transport = remote_smtp
+ no_more
+
+ system_aliases:
+ ....
+
+The first router does DNS routing for all domains that are not in the named
+list of local domains, and no_more ensures that it is the last router for those
+domains. All other domains fall through to the system_aliases and subsequent
+routers. For a complete configuration example, look at the default
+configuration file in src/configure.default.
+
+
+Router Actions
+--------------
+
+The concept of how the routers work is as follows:
+
+A number of pre-conditions are tested (details below). If any of them fails,
+control is passed to the next router. We say "the router is skipped". Otherwise
+the router is run, and can yield one of several different results:
+
+. accept: The router accepts the address, and either queues it for a transport,
+or generates one or more "child" addresses. Processing the original address
+ceases, unless "unseen" is set on the router, in which case the address is
+passed to the next router. Processing of any child addresses starts with the
+first router by default, or at the router defined by redirect_router if it is
+set. This may be any router in the list.
+
+. decline: The router declines to accept the address because it does not
+recognize it at all. The address is passed to the next router, unless no_more
+is set, in which case the address fails.
+
+. pass: The router recognizes the address, but cannot handle it itself. It
+requests that the address be passed to another router. This overrides no_more.
+By default the address is passed to the next router, but this can be changed by
+setting pass_router. However, in this case (unlike redirect_router) the named
+router must be below the current router (to avoid loops).
+
+. 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.
+
+. defer: The router cannot handle the address at the present time. (For
+example, a database may be offline.) No further processing of the address
+happens in this delivery attempt. It is tried again next time.
+
+. error: There is some error in the router (for example, a syntax error in
+its configuration). The action is as for defer.
+
+
+Router pre-conditions
+---------------------
+
+In Exim 3 there are some strange interactions between the generic options that
+test things before running a director or router and the no_more test that
+happens afterwards.
+
+In Exim 4 it is all more straightforward. If any of the pre-condition tests
+fail, the router is skipped and control passes to the next router. The no_more
+option has an effect only if the router is actually run - that is, if all the
+pre-condition tests succeed. The order in which these tests are run is:
+
+ verify status, expn status, domains, local_parts, check_local_user
+
+If all those match, the debug_print string is output when debugging. Exim then
+goes on to test
+
+ senders, require_files, condition
+
+Note that require_files comes near the end of the list, so you cannot use it to
+check for the existence of a file in which to lookup up a domain, local part,
+or sender. However, as these options are all expanded, you can use the "exists"
+expansion condition to make such tests. The require_files option is intended
+for checking files that the router may be going to use internally, or which are
+needed by a specific transport (e.g. .procmailrc).
+
+In Exim 4, local part prefixes and suffixes are recognized and removed before
+any of the other pre-condition tests are done (in Exim 3 they were removed
+afterwards). Note that this means that the local_parts option now tests the
+local part without its prefix or suffix.
+
+If you want to use local parts that include any affixes in a pre-condition
+test, you can do so by using a "condition" option that uses the variables
+$local_part, $local_part_prefix, and $local_part_suffix as necessary.
+
+
+A New Set of Routers
+--------------------
+
+The two sets of routers and directors of Exim 3 have been replaced by a single
+set of routers for Exim 4. These are as follows:
+
+. accept Always accepts an address. It has no private options.
+
+. dnslookup Routes by DNS lookup (descended from lookuphost).
+
+. ipliteral Routes IP literal addresses (unchanged).
+
+. iplookup Special-purpose lookup router (unchanged).
+
+. manualroute Routes domains from explicit data (descended from domainlist).
+
+. queryprogram Routes addresses by running a program (detail changed).
+
+. redirect Redirects addresses; handles all the functions previously
+ supported by aliasfile, forwardfile, and smartuser without
+ a transport.
+
+
+Saving duplication of effort while routing
+------------------------------------------
+
+Early versions of Exim used to copy the routing of one address for all other
+addresses in the same domain, thereby possibly saving some repeated DNS
+lookups. This feature was removed for release 2.12, after the possibility of
+varying the router actions according to the local part (the local_parts option)
+was added. (In fact, the use of $local_part could have broken it earlier.)
+
+For Exim 4, I have added an option called same_domain_copy_routing to the
+dnslookup and manualroute routers. When one of these routers routes an address
+to a remote transport and this option is set, any other addresses in the
+message that have the same domain are automatically given the same routing, but
+only if the router does not set headers_add or headers_remove, and does not
+`widen' the domain during the routing.
+
+
+Generic Router Options
+----------------------
+
+. The global locally_caseless option is replaced by a generic router option
+ called caseful_local_part. By default, routers handle local parts caselessly.
+
+. check_local_user is now a generic option that is needed to check for a local
+ account. Typically used on redirect (for user's forward files) and on accept
+ (for local deliveries).
+
+. The setting self=local has been removed (since there's no concept of local
+ domains in the code). The same kind of effect can be achieved by using
+ self=reroute or self=pass.
+
+. expn is now a generic router option.
+
+. local_part_prefix and local_part_suffix are now generic router options,
+ replacing prefix and suffix on directors.
+
+. Exim 3 has two logging styles for delivery, depending on whether the domain
+ is a local domain or not. For local domains, the address is given just as the
+ local part - this makes these deliveries easier to spot in the log. In Exim 4
+ there's no concept of local domains, so this functionality cannot be
+ automatic. Instead, there's a generic router option called log_as_local which
+ requests "local-style" logging. This option defaults on for the "accept"
+ router, and off for all the others.
+
+. There's an option called retry_use_local_part which is the default for any
+ router that has check_local_user set, and it applies to routing delays. (The
+ same option for transports applies to transport delays.)
+
+. transport_home_directory and transport_current_directory are new generic
+ options on all routers. They set up default values for home_directory and
+ current_directory on the transport to which they route an address. Any
+ settings in the transport override.
+
+. If transport_home_directory is not set, but check_local_user is set, the
+ user's home directory is used as a default value.
+
+. The special fudge that exists in Exim 3 for handling home_directory settings
+ in forwardfile directors is not needed in Exim 4. It has therefore been
+ removed.
+
+. The new_director option in Exim 3 allows the direction of redirected
+ addresses to start at a given director, instead of the first one. In Exim 4,
+ this option is now called redirect_router. The option is used when a redirect
+ router succeeds, and when a queryprogram router returns a "redirect"
+ response.
+
+. There is a new option called pass_router, which specifies the router to go to
+ when a router "passes" on an address. The named router must follow the
+ current router (to avoid routing loops). Note: if a router declines, control
+ always passes to the next router, unless no_more is set.
+
+. There is a new router option called address_data. This is set to a string
+ which is expanded just before the router is run, that is, after all the
+ pre-tests have succeeded. If the expansion is forced to fail, the router
+ declines. Other expansion failures cause delivery of the address to be
+ deferred.
+
+ When the expansion succeeds, the value is retained with the address, and can
+ be accessed using the variable $address_data. Even if the router declines or
+ passes, the value remains with the address, though it can be changed by
+ another address_data setting on a subsequent router. If a router generates
+ child addresses, the value of $address_data propagates to them.
+
+ The idea of address_data is that you can use it to look up a lot of data for
+ the address once, then then pick out parts of the data later. For example,
+ you could use an LDAP lookup to return a string of the form
+
+ uid=1234 gid=5678 mailbox=/mail/xyz forward=/home/xyz/.forward
+
+ In the transport you could then pick out the mailbox by a setting such as
+
+ file = ${extract{mailbox}{$address_data}}
+
+ This makes the configuration file less messy, and also reduces the number of
+ lookups. (Exim does cache the most recent lookup, but there may be several
+ addresses with different lookups.)
+
+. When a transport is run for several addresses simultaneously, the values of
+ $address_data, $local_part_data, and $domain_data are taken from the first
+ address that the transport handles. However, the order in which multiple
+ addresses are processed is not defined. You therefore need to be careful if
+ you want to use these variables with multiple addresses. The smtp transport
+ is the only one which by default handles multiple addresses.
+
+. When an address is routed by a router with the "unseen" option set, a "clone"
+ address is created, and it starts being routed at the next router. (This is
+ what people expect. In Exim 3 it starts at the top - in simple cases that has
+ the same effect because of the anti-looping rule, but if aliases are involved
+ it sometimes doesn't do what you want.)
+
+. The way that require_files works has been changed. Each item in the list is
+ now separately expanded as the test proceeds. The use of leading ! and +
+ characters is unchanged. However, user and group checking is done differently.
+ Previously, seteuid() was used, but seteuid() is no longer used in Exim (see
+ "Security" below). Instead, Exim now scans along the components of the file
+ path and checks the access for the given uid and gid. It expects "x" access
+ on directories and "r" on the final file. This means that file access control
+ lists (on those operating systems that have them) are ignored.
+
+
+Other Consequences of the Director/Router Merge
+-----------------------------------------------
+
+. The -odqr option is abolished, as there is no inbuilt concept of remote
+ domains.
+
+. The -odqs option is equivalent to queue_smtp_domains = *.
+
+. queue_remote_domains is renamed queue_domains, and applies to any domain.
+
+. The -ql option now suppresses remote delivery; routing always happens.
+
+. The "remote" facility of queue_only_file has been removed.
+
+. The match_directory option for forwardfile and localuser has been entirely
+ abolished. Its function can be achieved using the "condition" option in
+ conjunction with check_local_user.
+
+. When an address is being verified, if it is redirected to a single new
+ address, verification continues with that address. If it is redirected to
+ more than one address, verification ceases with a success result. (In Exim 3,
+ this applied only to aliasing, not to forwarding.)
+
+
+The dnslookup router
+--------------------
+
+This router replaces the lookuphost router of Exim 3. It is much the same,
+except that the "gethostbyname" option has been removed. It now does only DNS
+routing - hence the change of name. Routing using gethostbyname() can be done
+by the manualroute router.
+
+
+The manualroute router
+----------------------
+
+This is the new name for the domainlist router, supposedly to make its function
+clearer and to avoid confusion with the "domainlist" that is used to set up
+named domain lists. Several things have been removed and reorganized.
+
+. The old search mechanism (route_file, route_query, route_queries,
+ search_type) have been removed. Instead there is a new option called
+ route_data, which is an expanded string. It should expand to a single routing
+ entry. If the expansion ends up empty (or is forced to fail), the router
+ declines. The route_list option still exists, for convenient listing of a few
+ inline routes.
+
+. There is no longer any MX processing function in this router. The keywords
+ bydns_mx and bydns_a have been removed, leaving just
+
+ bydns => find IP addresses from address records in the DNS
+ byname => find IP addresses by calling gethostbyname()
+
+ The default lookup type is "byname", and this can be omitted from a route
+ data line. If an IP address is given, both "byname" and "bydns" are ignored
+ (so typically you omit this field).
+
+. The qualify_single and search_parents options have also been removed.
+
+. A transport is always required to be set, unless verify_only is set.
+
+. The host_find_failed option can be set to "decline", to cause the router to
+ decline if it can't find an IP address for a listed host.
+
+. If manualroute routes to a local transport, there is no need to specify
+ byname or bydns in the routing data. Any supplied host list is passed as a
+ string in $host, but $host_address is unset.
+
+
+The queryprogram router
+-----------------------
+
+This router has been re-designed:
+
+. You must now specify a user and group for the program to be run using
+ command_user and (if necessary) command_group. It no longer defaults to
+ "nobody". These options are expanded.
+
+. The command is now split up and each argument expanded separately, as happens
+ for the pipe transport. The command name is also expanded.
+
+. The return value "forcefail" has been renamed "fail", and it causes delivery
+ to fail. (The original usage of "fail" meaning "decline" has finally been
+ removed.)
+
+. The $route_option variable, which queryprogram used to be able to set has
+ been abolished. A facility to set the new $address_data variable replaces it.
+
+. The string returned from queryprogram must now be one of:
+
+ DECLINE
+ FAIL text
+ DEFER text
+ PASS
+ FREEZE text
+ REDIRECT text
+ ACCEPT TRANSPORT=transport HOSTS=host list LOOKUP=byname|bydns DATA=text
+
+The text returned for "redirect" is a list of new addresses. The text for FAIL
+is returned in the SMTP dialogue when the router is run as part of address
+verification. It is also logged. The text for DEFER and FREEZE is just logged.
+
+The data items in the "accept" return can be given in any order, and all are
+optional. If no transport is included in the "accept" return, the router's
+default transport is used. The host list and lookup type are needed only if the
+transport is an smtp transport that does not itself have a host list. The
+default lookup type is "byname". If the "data" field is set, its value is
+placed in the $address_data variable.
+
+
+The redirect router
+-------------------
+
+This router replaces forwardfile, appendfile, and the use of smartuser without
+a transport. It has two mutually exclusive options for specifying the data that
+it uses. If "file" is set, the data is taken from a file. Otherwise "data" must
+be set, and the data is the expanded value of that option.
+
+The data may be an alias list, possibly including special entries such as
+:fail:, or it may be a list of filtering instructions.
+
+If "file" is set, but the file does not exist or is empty, or its contents have
+no effect (entirely comments, or a filter that does nothing), the router
+declines. This also happens if the expansion of "file" is forced to fail. Any
+other expansion failure causes the router to defer.
+
+Ownership of the file is checked if check_local_user is set or if owners is
+set, unless check_owner is explicitly set false.
+
+Likewise, the group is checked if owngroups is set, or if check_local_user is
+set and a modemask not containing 020 is set, unless check_group is explicitly
+set false.
+
+If "data" is set, a forced expansion causes the router to decline. This also
+happens if "data" is an empty string or a string that causes nothing to be
+generated and no action to be taken.
+
+Because "data" is now used for traditional /etc/aliases lookups, an empty alias
+no longer gives an error. It behaves in the same way as :unknown: (which is
+still recognized, but ignored).
+
+. If no_repeat_use is set, the router is skipped if _any_ ancestor of the
+ current address was routed by this router. This pre-test happens before any
+ of the others. (Contrast the default loop avoidance logic, which skips a
+ router if an ancestor with the same local part was routed by the router.)
+
+. If include_directory is set, :include: files are constrained to this
+ directory.
+
+. When an address is redirected to a file or a pipe, $address_file or
+ $address_pipe (as appropriate) is set when expanding the value of
+ file_transport or directory_transport.
+
+. There are new options forbid_filter_readfile and forbid_filter_run to lock
+ out the use of the new ${readfile and ${run expansion items in filters.
+
+. If one_time is set, forbid_pipe, forbid_file, and forbid_filter_reply are
+ forced to be true, and headers_add and headers_remove are forbidden.
+
+
+Generic transport options
+-------------------------
+
+. All remote deliveries are now done in subprocesses running with specified
+ UIDs and GIDs. (Formerly, only remote parallel deliveries were done in
+ subprocesses.) As a result, user and group are now generic options that can
+ be used on all transports. The default for both local and remote transports
+ is to run as the Exim user and group. For remote transports, this should not
+ normally be changed, but if it is, the user or group should be able to access
+ the hints databases, though failure to open a hints database is always
+ ignored.
+
+ If it turns out that a transport user is in the never_users list, Exim now
+ defers delivery and writes to the panic log. (Previously it just ran the
+ delivery as "nobody".) Because subprocesses (usually running as "exim")
+ are now always used for remote deliveries, you should *not* include "exim" in
+ the never_users list.
+
+. initgroups is now also a generic transport option.
+
+. home_directory and current_directory are generic options on all transports,
+ though some transports (e.g. smtp) make no use of them. If they are unset,
+ values supplied by the router are used.
+
+. The message_size_limit option is now expanded, which makes it possible to
+ have different limits for different hosts, for example.
+
+
+Multiple (batch) deliveries in the appendfile, lmtp, and pipe transports
+------------------------------------------------------------------------
+
+The options controlling batch deliveries, including BSMTP, were a mess, and
+have been reworked.
+
+. The batch option has been removed from all three transports, and the bsmtp
+ and bsmtp_helo options have been removed from appendfile and pipe.
+
+. The batch_max option defaults to 1 in all three transports.
+
+. A new option called use_bsmtp has been added to appendfile and pipe. When
+ set, the message is delivered in BSMTP format. If you want to have a HELO
+ line at the start of the message, you can configure this by making use of the
+ message_prefix option. You must include the terminating newline.
+
+. A new option called batch_id has been added to all three transports.
+
+Batching is now achieved by setting batch_max to a value greater than 1. This
+is recommended for lmtp. When multiple addresses are routed to the same
+transport that has a batch_max value greater than one, the addresses are
+delivered in a batch, subject to certain conditions:
+
+. 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
+ addresses with the same domain are batched.
+
+. If batch_id is set, it is expanded for each address, and only those addresses
+ with the same expanded value are batched.
+
+. Batched addresses must also have the same errors address (where to send
+ delivery errors), the same header additions and removals, the same user and
+ group for the transport, and if a host list is present, the first host must
+ be the same.
+
+
+The appendfile transport
+------------------------
+
+. The prefix and suffix options have been renamed message_prefix and
+ message_suffix to avoid confusion with address affixes. The default values,
+ which are suitable for mbox deliveries, now apply only if "file" is set and
+ use_bsmtp is not set. Otherwise, the default values for these options are
+ unset. They can, of course, always be overridden.
+
+. If "directory" is set (which means that "file" is not set), the check_string
+ and escape_string options now default unset.
+
+. The require_lockfile options has been abolished. If use_lockfile is set, a
+ lock file is always required.
+
+. The quota_filecount option is now expanded.
+
+. The create_file option now also applies when delivering into an individual
+ file in a given directory, as well as when appending to a single file. In the
+ case of maildir delivery, the restriction applies to the top directory of the
+ maildir folder.
+
+. There's a new option called directory_file which is expanded to form the
+ final leaf name of files when "directory" is set, but neither maildir nor
+ mailstore is set. The default is "q${base62:$tod_epoch}-$inode", which
+ reproduces the old fixed value. The variable $inode is available only when
+ expanding this new option.
+
+
+The pipe transport
+------------------
+
+. The prefix and suffix options have been renamed message_prefix and
+ message_suffix to avoid confusion with address affixes. The default values
+ that are suitable for vacation deliveries now apply only if use_bsmtp is not
+ set. Otherwise the default values for these options are unset. They can, of
+ course, always be overridden.
+
+
+The smtp transport
+------------------
+
+. The badly-named batch_max option is now called connection_max_messages.
+
+. If hosts_randomize is set, it now affects host lists that come from a router
+ as well as the contents of the "hosts" option, but only if the hosts were not
+ obtained from MX records. Typically, such lists come from the manualroute
+ router. This change means that the router can provide the same host list for
+ multiple addresses - causing them all to be sent to the transport at once.
+ Randomizing is then done each time the transport is called. (If you set
+ hosts_randomize on the router, the randomizing happens for each address.)
+
+. The way that smtp operates when there are multiple addresses to be sent to
+ the same host is now different. Previously, the transport was called many
+ times, with a maximum of max_rcpt addresses per call. Each call made a new
+ connection to the host. When remote_max_parallel = 1, all the addresses are
+ now passed to the transport at once. It makes a single TCP/IP call, but may
+ send multiple copies of the message, each with no more than max_rcpt
+ recipients.
+
+ When remote_max_parallel is greater than 1, a heuristic is used. The number
+ of addresses passed to a single call of the transport is limited to
+
+ (the total number of recipients) / (the value of remote_max_parallel)
+
+ so, for example, if there are 100 recipients and remote_max_parallel is 2, no
+ more than 50 are passed in one call, even if max_rcpt is 100. (The idea is
+ that the other 50 will be passed to another call running in parallel.)
+
+ There is an option of the smtp transport called connection_max_messages
+ which limits the number of messages, or copies of a message, that Exim sends
+ down a single TCP/IP connection. This applies both to this mechanism for
+ multiple copies of a single message, and the re-use of a TCP/IP connection
+ for sending other messages destined for the same host, after a delivery
+ delay. The default value is 500.
+
+. The "interface" option is now expanded. If the result is a forced failure or
+ an empty string, it is ignored. Otherwise, the result must be a list of IP
+ addresses. The first one of the correct type (IPv4 or IPv6) for the outgoing
+ connection is used. If there isn't one of the correct type, the option is
+ ignored.
+
+. At the start of running the transport, the value of $host is taken from the
+ first host in a multi-host list. However, just before the transport connects
+ to a host, the value is changed to refer to that particular host. (This
+ applies to $host_address as well.) This means that options such as helo_data
+ and the tls_options can be made host-specific.
+
+. The tls_verify_ciphers option has been renamed tls_require_ciphers, in order
+ to leave the word "verify" as something that refers to the verification of
+ certificates.
+
+. The resolution of hosts and fallback_hosts used to look up MX records. This
+ was some kind of ancient silliness that I recently noticed. These are
+ definitely hosts, not mail domains. Exim 4 just looks up address records.
+ As a consequence of this, the mx_domains option of the smtp transport is
+ removed.
+
+. The authenticate_hosts option has been renamed as hosts_try_auth. A new
+ option called hosts_require_auth has been added; if authentication fails for
+ one of these hosts, Exim does _not_ try to send unauthenticated. It defers
+ instead. The deferal error is detectable in the retry rules, so this can be
+ turned into a hard failure if required.
+
+
+The System Filter
+-----------------
+
+. The system filter options that were called message_filter_xxx have all been
+ renamed as system_filter_xxx.
+
+. The value of system_filter is expanded.
+
+. message_filter_directory_transport and message_filter_file_transport are now
+ both expanded before use. If the filter set up any file or pipe deliveries,
+ $address_file and $address_pipe are set as appropriate while doing the
+ expansions.
+
+. message_filter_directory2_transport has been removed. The effect of using
+ different directory-style transports can be achieved by specifying a suitable
+ expansion string to system_filter_directory_transport.
+
+. When a system filter added recipients to a message, Exim 3 added an
+ X-Envelope-To: header, listing the real recipients (up to 100). This has been
+ abolished because you can do this kind of thing using "headers_add" nowadays.
+
+. The "fail" command has been extended to allow for two different messages, one
+ for Exim's log and the other to be returned to the sender. The syntax is
+
+ fail "<<log message>>user message"
+
+ That is, if the first two characters of the message are "<<" the following
+ text, up to ">>", is written to the log, and the remainder is returned to the
+ user. If there is no log message, the user message is logged. The motivation
+ for this feature was to reduce the amount of text logged, while being able to
+ send quite long (maybe even multi-line) messages back to the sender.
+
+
+Changes to Lookups
+------------------
+
+. Oracle support is available. It works like the mysql and pgsql support,
+ except that there is no "database name" involved, and the "host name" field
+ is used for what is called "service name" in Oracle. This often looks like a
+ host name. Also, semicolons are not used at the end of an SQL query for
+ Oracle.
+
+. There's a new single-key lookup type called dsearch. It searches a directory
+ for a file whose name matches the key. The result of a successful search is
+ the key. One possible use of this could be for recognizing virtual domains.
+ If each domain is represented by a file whose name is the domain name, you
+ needn't make a separate list of the domains. You could test for them in an
+ ACL (see below), for example, by a line like this
+
+ accept domains = dsearch;/etc/virtual/domains
+
+. The format of LDAP output has been changed for cases where multiple
+ attributes are requested. The data for each attribute is now always quoted.
+ Within the quotes, the quote character, backslash, and newline are escaped
+ with backslashes and commas are used to separate multiple values for the
+ attribute. Thus, the string in quotes takes the same form as the output when
+ a single attribute is requested. If multiple entries are found, their data is
+ still separated by a newline.
+
+. There's a new expansion condition called ldapauth which exists so that the
+ LDAP authentication mechanism can be used for user authentication. It is
+ described under "string expansion" below.
+
+. Exim now supports ldaps:// URLs as well as ldap:// URLs. The former do LDAP
+ over TLS (i.e. encrypted) connections.
+
+. There is now support for the "whoson" mechanism for doing "POP-before-SMTP"
+ authentication. This is provided by new query-style lookup type called
+ "whoson", with queries that consist of IP addresses. For example, in an ACL
+ you can write
+
+ require condition = ${lookup whoson {$sender_host_address}{yes}{no}}
+
+
+Special items in domain and host lists
+--------------------------------------
+
+. In a domain list, the special item @ matches the primary host name, and the
+ special item @[] matches any local interface address enclosed in square
+ brackets (as in domain literal email addresses). The special item @mx_any
+ matches any domain that has an MX record pointing to the local host. The
+ special items @mx_primary and @mx_secondary are similar, except that the
+ first matches only when the primary MX is to the local host, and the second
+ only when the primary MX is not the local host, but a secondary MX is.
+
+. In a host list, the special item @ matches the primary host name, and the
+ special item @[] matches any local interface address (not in brackets).
+
+
+Access Control Lists (ACLs)
+---------------------------
+
+All the policy control options for incoming messages have been replaced by
+Access Control Lists (ACLs). These give more flexibility to the sysadmin, and
+allow the order of testing to be specified. For example, using an ACL, it is
+possible to specify "accept if authenticated, even if from an RBL host, but
+otherwise deny if from an RBL host", which is not possible in Exim 3.
+
+ACLs are defined in a new part of the configuration file, and given names.
+Which ones to run are controlled by a new set of options that are placed in the
+main part of the configuration.
+
+ acl_smtp_auth specifies the ACL to run when AUTH is received
+ acl_smtp_data specifies the ACL to run after a message has been received
+ acl_smtp_etrn specifies the ACL to run when ETRN is received
+ acl_smtp_expn specifies the ACL to run when EXPN is received
+ acl_smtp_rcpt specifies the ACL to run when RCPT is received
+ acl_smtp_vrfy specifies the ACL to run when VRFY is received
+
+The default actions vary. If acl_smtp_auth is not defined, AUTH is always
+accepted (and an attempt is made to authenticate the session). If acl_smtp_data
+is not defined, no checks are done after a message has been received, and it is
+always accepted at that point.
+
+However, if any of the others are not defined, the relevant SMTP command is
+rejected. In particular, this means that acl_smtp_rcpt must be defined in order
+to receive any messages over an SMTP connection. The default configuration file
+contains a suitable default for this.
+
+ACLs can be provided in line, or in files, or looked up from databases. One ACL
+can call another in a subroutine-like manner. String expansion is used, and
+which ACL to run can be varied according to sender host or any other criterion
+that a string expansion can test.
+
+This is not the place to give a full specification of ACLs, but here is a
+typical example for checking RCPT commands, taken from the default
+configuration. The tests are performed in order.
+
+acl_check_rcpt:
+ # Accept if source is local SMTP (i.e. not over TCP/IP - undefined host)
+ accept hosts = :
+
+ # Deny if the local part contains @ or % or /
+ deny local_parts = ^.*[@%/]
+
+ # Accept mail to postmaster in any local domain, regardless of the source,
+ # and without verifying the sender.
+ accept domains = +local_domains
+ local_parts = postmaster
+
+ # Deny unless the sender address can be verified.
+ require verify = sender
+
+ # Accept if the address is in a local domain, but only if the recipient can
+ # be verified. Otherwise deny. The "endpass" line is the border between
+ # passing on to the next ACL statement (if tests above it fail) or denying
+ # access (if tests below it fail).
+ accept domains = +local_domains
+ endpass
+ message = unknown user
+ verify = recipient
+
+ # We get here only for non-local domains. Accept if the message arrived over
+ # an authenticated connection, from any host. These messages are usually from
+ # MUAs, so recipient verification is omitted.
+ accept authenticated = *
+
+ # Reaching the end of the ACL causes a "deny", but we might as well give
+ # an explicit message.
+ deny message = relay not permitted
+
+The following options have been abolished as a consequence of the introduction
+of ACLs:
+
+auth_hosts, auth_over_tls_hosts, headers_checks_fail, headers_check_syntax,
+headers_sender_verify, headers_sender_verify_errmsg, host_accept_relay,
+host_auth_accept_relay, host_reject_recipients, prohibition_message,
+rbl_domains, rbl_hosts, rbl_log_headers, rbl_log_rcpt_count,
+rbl_reject_recipients, rbl_warn_header, receiver_try_verify, receiver_verify,
+receiver_verify_addresses, receiver_verify_hosts, receiver_verify_senders,
+recipients_reject_except, recipients_reject_except_senders, relay_domains,
+relay_domains_include_local_mx, relay_match_host_or_sender,
+sender_address_relay, sender_address_relay_hosts, sender_reject,
+sender_reject_recipients, sender_try_verify, sender_verify,
+sender_verify_batch, sender_verify_hosts, sender_verify_fixup,
+sender_verify_hosts_callback, sender_verify_callback_domains,
+sender_verify_callback_timeout, sender_verify_max_retry_rate,
+sender_verify_reject, smtp_etrn_hosts, smtp_expn_hosts. smtp_verify, tls_hosts.
+
+The variable $prohibition_reason has been abolished.
+
+The host_reject option has been retained, but with its name changed to
+host_reject_connection, to emphasize that it causes a rejection at connection
+time. I've left it available just in case it is needed - but its use is not
+recommended in normal circumstances.
+
+
+Other Incoming SMTP Session Controls
+------------------------------------
+
+. The option smtp_accept_max_per_connection (default 1000) limits the number of
+ messages accepted over a single SMTP connection. This is a safety catch in
+ case some sender goes mad (incidents of this kind have been seen). After the
+ limit is reached, a 421 response is given to MAIL commands.
+
+. Some sites find it helpful to be able to limit the rate at which certain
+ hosts can send them messages, and the rate at which an individual message can
+ specify recipients. There are now options for controlling these two different
+ rates.
+
+ Rate limiting applies only to those hosts that match smtp_ratelimit_hosts,
+ whose value is a host list. When a host matches, one or both of the options
+ smtp_ratelimit_mail and smtp_ratelimit_rcpt may be set. They apply to the
+ rate of acceptance of MAIL and RCPT commands in a single SMTP session,
+ respectively.
+
+ The value of each option is a set of four comma-separated values:
+
+ 1. A threshold, before which there is no rate limiting.
+ 2. An initial time delay. Unlike other times in Exim, fractions are allowed
+ here.
+ 3. A factor by which to increase the delay each time.
+ 4. A maximum value for the delay.
+
+ For example, these settings have been used successfully at the site which
+ first suggested this feature, for controlling mail from their customers:
+
+ smtp_ratelimit_mail = 2, 0.5s, 1.05, 4m
+ smtp_ratelimit_rcpt = 4, 0.25s, 1.015, 4m
+
+. The default value for smtp_connect_backlog has been increased to 20.
+
+. The SMTP protocol specification requires the client to wait for a response
+ from the server at certain points in the dialogue. (Without PIPELINING these
+ are after every command; with PIPELINING they are fewer, but still exist.)
+ Some spamming sites send out a complete set of SMTP commands without waiting
+ for any response. Exim 4 protects against this by rejecting messages if the
+ client has sent further input when it should not have. The error response
+ "554 SMTP synchronization error" is sent, and the connection is dropped.
+
+ This check is controlled by smtp_enforce_sync, which is true by default.
+
+. helo_strict_syntax has been abolished. The default is now to enforce strict
+ domain syntax for HELO/EHLO arguments. You can use helo_accept_junk_hosts if
+ you want to avoid this.
+
+. There's a new option called helo_lookup_domains. If the domain given in a
+ HELO or EHLO command matches this list, a reverse lookup is done in order to
+ establish the host's true name. The default setting is
+
+ helo_lookup_domains = @ : @[]
+
+ That is, a lookup is forced if the client host gives the server's name or
+ [one of its IP addresses] in HELO or EHLO. (In Exim 3 this happened
+ automatically and was not configurable.)
+
+. The value of the global message_size_limit option is now expanded. For
+ locally submitted messages this happens at the start of message reception.
+ For messages from remote hosts, the expansion is done just after the host
+ connects, so that the value can depend on the host.
+
+
+Handling of Resent- Fields
+--------------------------
+
+RFC 2822 makes it clear that Resent- fields are purely informational. Exim used
+to make use of Resent-Reply-To: which does not actually exist, and it also used
+to use the last set of resent- fields for all the address fields it recognized.
+
+In Exim 4, resent- headers are dealt with as follows:
+
+. A Resent-From: header that just contains the login id as the address is
+ automatically rewritten in the same way as From: is (using qualify domain,
+ and user name from the passwd data).
+
+. If there's a rewrite rule for a header, it is also applied to resent- headers
+ of the same type. For example, a rule that rewrites From: headers also
+ rewrites Resent-From: headers.
+
+. For local messages, if Sender: is being removed on input, Resent-Sender: is
+ also removed.
+
+. If there are any resent- headers but no Resent-Date: or Resent-From: they are
+ added.
+
+. The logic for adding Sender: is now duplicated for Resent-Sender.
+
+. If there's no Resent-Message-Id: one is created, and it is the
+ Resent-Message-Id: which is included in the log line.
+
+
+Authentication
+--------------
+
+. The auth_hosts option has been abolished; this functionality is now
+ controlled by ACLs.
+
+. The auth_always_advertise option has been abolished because it depended on
+ auth_hosts and and host_auth_accept_relay, both of which are no more. In its
+ place there is a new option called auth_advertise_hosts, whose default value
+ is *, meaning "advertise AUTH to all".
+
+. The value of server_setid is now used when logging failed authentication
+ attempts.
+
+. The -oMaa option allows trusted users to set the value of
+ $sender_host_authenticated (the authenticator name). This is normally used in
+ conjunction with -oMa.
+
+
+Encryption
+----------
+
+. Because tls_hosts is no more, tls_advertise_hosts is now the only means of
+ controlling the advertisement of STARTTLS (previously, tls_hosts overrode).
+
+. The global option tls_verify_ciphers has been abolished. There are now
+ facilities for checking which cipher is in use in ACLs.
+
+. There's a new option called tls_try_verify_hosts. Like tls_verify_hosts, this
+ causes the server to request a certificate from a client, and it verifies the
+ certificate that it receives. However, unlike tls_verify_hosts, Exim
+ continues with the SMTP connection (encrypted) if a client certificate is not
+ received, or if the certificate does not verify. This state can be detected
+ in an ACL, which makes it possible to implement policies such as "accept for
+ relay only if a verified certificate has been received but accept for local
+ delivery if encrypted, even without a verified certificate".
+
+ A match in tls_verify_hosts overrides tls_try_verify_hosts.
+
+
+The Daemon
+----------
+
+. local_interfaces can now specify a port number with each address, thus
+ allowing a single Exim daemon to listen on multiple ports. The format of each
+ address is either [aaaa]:ppp or aaaa.ppp where aaaa is an IP address and ppp
+ is a port number. For example:
+
+ local_interfaces = 192.168.3.4.25 : 192.168.3.4.26
+
+ If an address is listed without a port, the setting of daemon_smtp_port, or
+ the value of the -oX option, is the default.
+
+. The -oX option can now override local_interfaces. That is, it can supply IP
+ addresses as well as just a port. It is interpreted in this way if its value
+ contains any of the characters . : or []. For example:
+
+ exim -bd -oX 10.9.8.7:10.11.12.13.2525
+
+ The format of the string is identical to the format recognized by the
+ local_interfaces option.
+
+. The way the daemon wrote PID files was overly complicated and messy. It no
+ longer tries to be clever. A PID file is written if, and only if, -bd is used
+ and -oX is _not_ used. In other words, only if the daemon is started with its
+ standard options. There is only one PID file. If pid_file_path is unset, it
+ is exim-daemon.pid in Exim's spool directory. Otherwise the value of
+ pid_file_path is used. For backwards compatibility, "%s" in this value is
+ replaced by an empty string.
+
+
+Logging
+-------
+
+The log_level option and all the various independent logging control options
+have been abolished. In their place there is a single option called
+log_selector. It takes a string argument composed of names preceded by + or -
+characters. These turn on or off the logging of different things. For example:
+
+ log_selector = +arguments -retry_defer
+
+The optional logging items (defaults marked *) are:
+
+ address_rewrite address rewriting
+ all_parents all parents in => lines
+ arguments exim arguments
+ *connection_reject connection rejections
+ *delay_delivery immediate delivery delayed (message queued)
+ delivery_size add S=nnn to delivery lines
+ *dnslist_defer defers of DNS list (aka RBL) lookups
+ incoming_interface incoming interface on <= lines
+ incoming_port incoming port on <= lines
+ *lost_incoming_connection as it says (includes timeouts)
+ *queue_run start and end queue runs
+ received_sender sender on <= lines
+ received_recipients recipients on <= lines
+ *retry_defer "retry time not reached"
+ sender_on_delivery add sender to => lines
+ *size_reject rejection because too big
+ *skip_delivery "message is frozen"
+ smtp_confirmation SMTP confirmation on <= lines
+ smtp_connection SMTP connections
+ smtp_protocol_error SMTP protocol errors
+ smtp_syntax_error SMTP syntax errors
+ subject contents of Subject: on <= lines
+ *tls_cipher TLS cipher on <= lines
+ tls_peerdn TLS peer DN on <= lines
+
+ all all of the above
+
+"retry time not reached" is always omitted from individual message logs after
+the first delivery attempt.
+
+The log line "error message sent to" has been abolished, because the R= item on
+the incoming message line gives the relationship between the original message
+and the bounce.
+
+The logging options that have been abolished are: log_all_parents,
+log_arguments, log_incoming_port, log_interface, log_ip_options,
+log_level, log_queue_run_level, log_received_sender, log_received_rceipients,
+log_rewrites, log_sender_on_delivery, log_smtp_confirmation,
+log_smtp_connections, log_smtp_syntax_errors, log_subject, tls_log_cipher,
+tls_log_peerdn.
+
+
+Debugging
+---------
+
+The debug_level option has been removed. The -dm option has been removed. The
+-df option has also be removed, along with its related build-time option
+STDERR_FILE. (To debug inetd usage, an auxiliary script should be used.)
+
+The -d option has been reworked. It no longer takes a debug level number
+argument, but instead takes a list of debugging names, each preceded by + or -
+to turn on or off individual sets of debugging messages.
+
+. The -v option now shows just the SMTP dialog and any log lines.
+
+. -d with no argument gives a lot of standard debugging data. This is in effect
+ the equivalent of the old -d9, the thing you ask people to set for an initial
+ debugging test.
+
+. -d+x adds debugging option x to the default set
+ -d-x removes debugging option x from the default set
+ -d-all+x leaves only debugging option x
+
+The available debugging names are:
+
+ acl ACL interpretation
+ auth authenticators
+ deliver general delivery logic
+ dns DNS lookups (see also resolver)
+ dnsbl DNS black list (aka RBL) code
+ exec arguments for execv() calls
+ filter filter handling
+ hints_lookup hints data lookups
+ host_lookup all types of name->IP address handling
+ ident ident lookup
+ interface lists of local interfaces
+ lists matching things in lists
+ load system load checks
+ lookup general lookup code and all lookups
+ memory memory handling (replaces the old -dm)
+ process_info setting info for the process log
+ queue_run queue runs
+ receive general message reception logic
+ resolver turn on the DNS resolver's debugging output; goes to stdout
+ retry retry handling
+ rewrite rewriting
+ route address routing
+ tls TLS logic
+ transport transports
+ uid changes of uid/gid and looking up uid/gid
+ verify address verification logic
+
+ all all of the above, and also -v
+
+The default (-d with no argument) includes all of the above, plus -v, with the
+exception of filter, interface, load, memory, and resolver. Some debugging
+output always happens unconditionally whenever any debugging is selected. This
+includes some initial output and every log line.
+
+-d without any value was previously allowed for non-admin users because it used
+to be synonymous with -v. In Exim 4, non-admin users may use -v, but not -d.
+
+If the debug_print option is set in any driver, it produces output whenever any
+debugging is selected, or if -v is used.
+
+
+Local Scan Function
+-------------------
+
+For customized message scanning, you can now supply a C function that is linked
+into the Exim binary. The function is called local_scan(), and it is called
+when Exim has received a message, but has not yet sent a final
+acknowledgement to the sender. This applies to all messages, whether local or
+remote, SMTP or not.
+
+From within your function you can inspect the message, change the recipients,
+add or remove headers, and tell Exim whether to accept or reject the message.
+
+The manual contains the specification of the API for this function.
+
+
+String Expansion
+----------------
+
+. The lookup feature that allowed for subkeys using the syntax
+
+ ${lookup {key:subkey} type {data...
+
+ has been abolished (a) because the effect can be achieved using ${extract,
+ and (b) because in non-lsearch lookups, a colon can be a valid character in a
+ key.
+
+. When a string key is used in a ${extract expansion item, it is now handled
+ case-insensitively.
+
+. A new expansion variable called $tod_epoch gives the time as a single decimal
+ number representing the number of seconds from the start of the Unix epoch.
+
+. There's a new expansion operator that can turn numbers into base 62, for
+ example, ${base62:$tod_epoch}.
+
+. ${extract{number} now recognizes a negative number as a request to count
+ fields from the right.
+
+. There's a new expansion feature for reading files:
+
+ ${readfile{/some/file}{eolstring}}
+
+ The contents of the file replace the item. If {eolstring} is present (it's
+ optional) any newlines in the file are replaced by that string.
+
+. There's a new expansion feature for running commands:
+
+ ${run{comand args}{yes}{no}}
+
+ Like all the other conditional items, the {yes} and {no} strings are
+ optional. Omitting both is equivalent to {$value}. The standard output of the
+ command is put into $value if the command succeeds (returns a zero code). The
+ value of the code itself is put into $runrc, and this remains set afterwards,
+ so in a filter file you can do things like
+
+ if "${run{x y z}{}}$runrc" is 1 then ...
+ elsif $runrc is 2 then ...
+
+ As in other command executions from Exim, a shell is not used by default.
+ If you want a shell, you must explicitly code it.
+
+. The redirect router has options for forbidding ${readfile and ${run in
+ filters.
+
+. A feature is provided to suppress expansion of part of a string. Any
+ characters between two occurrences of \N are copied to the output string
+ verbatim. This is particularly useful for protecting regular expressions from
+ unwanted expansion effects. For example:
+
+ queue_smtp_domains = ! \N^ten-\d+\.testing\.com$\N
+
+ Without \N the \ and $ characters in the regex would have to be escaped.
+
+. Radius authentication is supported in a similar way to PAM. You must set
+ RADIUS_CONFIG_FILE in Local/Makefile to specify the location of the Radius
+ client configuration file. Then you can use expansions such as
+
+ server_condition = ${if radius{arguments}{yes}{no}}
+
+. User authentication can now also be done by attempting to bind to an LDAP
+ server. The syntax is again similar to PAM and Radius.
+
+ server_condition = ${if ldapauth{ldap query}{yes}{no}}
+
+ A user and password are required to be supplied with the query. No actual
+ data is looked up; Exim just does a bind to the LDAP server and sets the
+ condition according to the result. Here's an example of an SMTP
+ authenticator:
+
+ login:
+ driver = plaintext
+ public_name = LOGIN
+ server_prompts = "Username:: : Password::"
+ server_condition = ${if ldapauth \
+ {user="uid=${quote_ldap:$1},ou=people,o=example.org" pass="$2" \
+ ldap://ldap.example.org/}{yes}{no}}
+ server_set_id = uid=$1,ou=people,o=example.org
+
+
+
+Security
+--------
+
+Exim 3 could be run in a variety of ways as far as security was concerned. This
+has all been simplified in Exim 4. The security-conscious might like to know
+that it no longer makes any use of the seteuid() function.
+
+. A UID and GID are required to be specified when Exim is compiled. They can be
+ now specified by name as well as by number, so the relevant options are now
+ called EXIM_USER and EXIM_GROUP. If you really feel you have to run Exim as
+ root, you can specify root here, but it is not recommended.
+
+. The "security" option has been abolished. Exim always releases its root
+ privilege when it can. In a conventional configuration, that means when it is
+ receiving a message, when it is delivering a message, when it is running a
+ queryprogram router, and when it is obeying users' filter files (and system
+ filters if it has been given a user for that purpose).
+
+. One important change is that Exim 4 runs as root while routing addresses for
+ delivery. Exim 3 used seteuid() to give up privilege temporarily while
+ routing. Apart from the unliked use of seteuid(), this sometimes gave rise to
+ permissions problems on configuration files.
+
+. However, Exim still runs as the Exim user while receiving messages, and
+ therefore while using the routing logic for verifying at SMTP time.
+
+. There is a new option called deliver_drop_privilege. If this is set, Exim
+ gives up its privilege right at the start of a delivery process, and runs the
+ entire delivery as the Exim user. This is the same action that used to be
+ requested by setting security=unprivileged.
+
+
+Hints Databases
+---------------
+
+. A single "misc" hints database is now used for ETRN and host serialization.
+ There have been appropriate consequential changes to the utilities for
+ managing the hints.
+
+. The exim_tidydb -f option has been abolished. A full tidy is now always done
+ (it hasn't proved to be very expensive).
+
+
+The run time Configuration File
+------------------------------
+
+. The format of the configuration file has changed. Instead of using "end" to
+ terminate sections, it now uses "begin <name>" to start sections. This means
+ that the sections, apart from the first, may appear in any order.
+
+. You can now include other files inside Exim run time configuration files, by
+ using this syntax:
+
+ .include <file name>
+
+. Quotes round the file name are optional. Includes may be nested to any depth,
+ but remember that Exim reads its configuration file often. The processing of
+ .include happens early, at a physical line level, so, like comment lines, it
+ can be used in the middle of an options setting, for example:
+
+ hosts_lookup = a.b.c \
+ .include /some/file
+
+ Include processing happens _before_ macro processing. Its effect is simply to
+ process the lines of the file as if they occurred inline where the .include
+ appears.
+
+. A macro at the start of a configuration line can now turn the line into an
+ empty line or a comment line. This applies to _logical_ input lines, that is,
+ after any concatenations have been done.
+
+
+Format of spool files
+---------------------
+
+. -local_scan is used in spool files to record the value of $local_scan_data,
+ the string returned from the locally-provided local_scan() function.
+
+
+Renamed Options
+---------------
+
+Some options have been renamed, to make their function clearer, or for
+consistency.
+
+. receiver_unqualified_hosts has been renamed as recipient_unqualified_hosts.
+ I'm going to use "recipient" everywhere in future.
+
+. helo_verify has become helo_verify_hosts.
+
+. remote_sort has become remote_sort_domains.
+
+. In the appendfile and pipe transports, "prefix" and "suffix" have become
+ "message_prefix" and "message_suffix". In the generic router options,
+ "prefix" and "suffix" have become "local_part_prefix" and "local_part_suffix".
+
+
+Miscellaneous
+-------------
+
+. ETRN serialization now uses a double fork, so that an Exim process (detached
+ from the original input process) can wait for the command to finish. This
+ means that it works whatever command ETRN causes to run. (Previously it
+ worked only if ETRN ran "exim -Rxxx".)
+
+. For incoming messages, the server's port number is preserved, and is
+ available in $interface_port. The privileged option -oMi can be used to
+ set this value.
+
+. The -Mmd option (to mark addresses delivered) now operates in a
+ case-sensitive manner.
+
+. Checks for duplicate deliveries are now case-sensitive in the local part.
+
+. The number of situations where Exim panics has been reduced. For example,
+ expansion failures for the "domains" or "local_parts" options in a router now
+ cause deferral instead of a panic.
+
+. EXPN no longer attempts to distinguish local and remote addresses (but you
+ can cause it to be rejected for certain arguments in the ACL).
+
+. accept_timeout has been renamed as receive_timeout, to match
+ smtp_receive_timeout.
+
+. The ability to check an ident value as part of an item in a host list has
+ been removed.
+
+. The reject log shows a message's headers only if the rejection happens after
+ the SMTP DATA command (because they aren't available for earlier checks). The
+ sender, and up to five recipients are listed in Envelope-from: and
+ Envelope-to: header lines. After the headers, a line of separator characters
+ is output. Separators are no longer used for other reject log entries.
+
+. Because header checks are now done as part of ACLs, they now apply only to
+ SMTP input.
+
+. The port number on SMTP connections is now logged in the format [aaaa]:ppp
+ where aaaa is an IP address and ppp is a port, instead of in the format
+ [aaaa.ppp] because the former format causes some software to complain about
+ bad IP addresses.
+
+. The -oMa and -oMi options can now use the [aaaa]:ppp notation to set a port
+ number, but they still also recognize the aaaa.ppp notation.
+
+. The build-time option HAVE_AUTH is abolished. Exim automatically includes
+ authentication code if any authenticators are configured.
+
+. The nobody_user and nobody_group options have been abolished.
+
+. The $message_precedence variable has been abolished. The value is now
+ available as $h_precedence:.
+
+. There's a new utility script called exim_checkaccess which packages up a call
+ to Exim with the -bh option, for access control checking. The syntax is
+
+ exim_checkaccess <IP address> <email address> [exim options]
+
+ It runs "exim -bh <IP address>", does the SMTP dialogue, tests the result and
+ outputs either "accepted" or "Rejected" and the SMTP response to the RCPT TO
+ command. The sender is <> by default, but can be changed by the use of the
+ -f option.
+
+. The default state of Exim is now to forbid domain literals. For this reason,
+ the option that changes this has been renamed as allow_domain_literals.
+
+. The dns_check_names boolean option has been abolished. Checking is now turned
+ off by unsetting dns_check_names_pattern.
+
+. The errors_address and freeze_tell_mailmaster options have been abolished. In
+ their place there is a new option called freeze_tell, which can be set to a
+ list of addresses. A message is sent to these addresses whenever a message is
+ frozen - with the exception of failed bounce messages (this is not changed).
+
+. The message_size_limit_count_recipients option has been abolished on the
+ grounds that it was a failed experiment.
+
+. The very-special-purpose X rewrite flag has been abolished. The facility it
+ provided can now be done using the features of ACLs.
+
+. The timestamps_utc option has been abolished. The facility is now provided by
+ setting timezone = utc.
+
+. The value of remote_max_parallel now defaults to 2.
+
+. ignore_errmsg_errors has been abolished. The effect can be achieved by
+ setting ignore_bounce_errors_after = 0s. This option has been renamed from
+ ignore_errmsg_errors_after to make its function clearer. The default value
+ for ignore_bounce_errors_after is now 10w (10 weeks - i.e. likely to be
+ longer than any other timeouts, thereby disabling the facility).
+
+. The default for message_size_limit is now 50M as a guard against DoS attacks.
+
+. The -qi option does only initial (first time) deliveries. This can be helpful
+ if you are injecting message onto the queue using -odq and want a queue
+ runner just to process new messages. You can also use -qqi if you want.
+
+. Rewriting and retry patterns are now anything that can be single address list
+ items. They are processed by the same code, and are therefore expanded before
+ the matching takes place. Regular expressions must be suitably quoted. These
+ patterns may now be enclosed in double quotes so that white space may be
+ included. Normal quote processing applies.
+
+. Some scripts were built in the util directory, which was a mistake, because
+ they might be different for different platforms. Everything that is built is
+ now built in the build directory. The util directory just contains a couple
+ of scripts that are not modified at build time.
+
+. The installation script now installs the Exim binary as exim-v.vv-bb (where
+ v.vv is the version number and bb is the build number), and points a symbolic
+ link called "exim" to this binary. It does this in an atomic way so that
+ there is no time when "exim" is non-existent. The script is clever enough to
+ cope with an existing non-symbolic-link binary, converting it to the new
+ scheme automatically (and atomically).
+
+. When installing utilities, Exim now uses cp instead of mv to add .O to the
+ old ones, in order to preserve the permissions.
+
+. If the installation script is installing the default configuration, and
+ /etc/aliases does not exist, the script installs a default version. This does
+ not actually contain any aliases, but it does contain comments about ones
+ that should be created. A warning is output to the user.
+
+. A delay warning message is not sent if all the addresses in a message get a
+ "retry time not reached" error. Exim waits until a delivery is actually
+ attempted, so as to be able to give a more informative message.
+
+. The existence of the three options deliver_load_max, queue_only_load, and
+ deliver_queue_load_max was confusing, because their function overlapped. The
+ first of them has been abolished. We are left with
+
+ queue_only_load no immediate delivery if load is high when
+ message arrives
+ deliver_queue_load_max no queued delivery if load is too high
+
+. The ability to edit message bodies (-Meb and the Eximon menu item) has been
+ removed, on the grounds that it is bad practice to do this.
+
+. Eximstats is now Steve Campbell's patched version, which displays sizes in K
+ and M and G, and can optionally generate HTML.
+
+. If bounce_sender_authentication is set to an email address, this address is
+ used in an AUTH option of the MAIL command when sending bounce messages, if
+ authentication is being used. For example, if you set
+
+ bounce_sender_authentication = mailer-daemon@your.domain
+
+ a bounce message will be sent over an authenticated connection using
+
+ MAIL FROM:<> AUTH=mailer-daemon@your.domain
+
+. untrusted_set_sender has changed from a boolean to an address pattern. It
+ permits untrusted users to set sender addresses that match the pattern. Like
+ all address patterns, it is expanded. The identity of the user is in
+ $sender_ident, so you can, for example, restrict users to setting senders
+ that start with their login ids by setting
+
+ untrusted_set_sender = ^$sender_ident-
+
+ The effect of the previous boolean can be achieved by setting the value to *.
+ This option applies to all forms of local input.
+
+. The always_bcc option has been abolished. If an incoming message has no To:
+ or Cc: headers, Exim now always adds an empty Bcc: line. This makes the
+ message valid for RFC 822 (sic). In time, this can be removed, because RFC
+ 2822 does not require there to be a recipient header.
+
+. ACTION_OUTPUT=no is now the default in the Exim monitor.
+
+. dns_ipv4_lookup has changed from a boolean into a domain list, and it now
+ applies only to those domains. Setting this option does not stop Exim from
+ making IPv6 calls: if an MX lookup returns AAAA records, Exim will use them.
+ What it does is to stop Exim looking for AAAA records explicitly.
+
+. The -G option is ignored (another Sendmail thing).
+
+. If no_bounce_return_message is set, the original message is not included in
+ bounce messages. If you want to include additional information in the bounce
+ message itself, you can use the existing errmsg_file and errmsg_text
+ facilities.
+
+. -bdf runs the daemon in the foreground (i.e. not detached from the terminal),
+ even when no debugging is requested.
+
+. Options for changing Exim's behaviour on receiving IPv4 options have been
+ abolished. Exim now always refuses calls that set these options, and logs the
+ incident. The abolished options are kill_ip_options, log_ip_options, and
+ refuse_ip_options.
+
+. The pattern for each errors_copy entry is now matched as an item in an
+ address list.
+
+. A number of options and variables that used the word "errmsg" have been
+ changed to use "bounce" instead, because it seems that "bounce message" is
+ now a reasonably well-understood term. I used it in the book and am now using
+ it in the manual; it's a lot less cumbersome than "delivery error
+ notification message". The changes are:
+
+ $errmsg_recipient => $bounce_recipient
+ errmsg_file => bounce_message_file
+ errmsg_text => bounce_message_text
+ ignore_errmsg_errors_after => ignore_bounce_errors_after
+
+ For consistency, warnmsg_file has been changed to warn_message_file. However,
+ the two variables $warnmsg_delay and $warnmsg_recipients are unchanged.
+
+ The hide_child_in_errmsg option has not changed, because it applies to both
+ bounce and delay warning messages.
+
+. smtp_accept_max_per_host is now an expanded string, so it can be varied on
+ a per-host basis. However, because this test happens in the daemon before it
+ forks, the expansion should be kept as simple as possible (e.g. just inline
+ tests of $sender_host_address).
+
+. The retry rules can now recognize the error "auth_failed", which happens when
+ authentication is required, but cannot be done.
+
+. There's a new option called local_sender_retain which can be set if
+ no_local_from_check is set. It causes Sender: headers to be retained in
+ locally-submitted messages.
+
+. The -dropcr command line option now turns CRLF into LF, and leaves isolated
+ CRs alone. Previously it simply dropped _all_ CR characters. There is now
+ also a drop_cr main option which, if turned on, assumes -dropcr for all
+ non-SMTP input.
+
+
+Removal of Obsolete Things
+--------------------------
+
+. The obsolete values "fail_soft" and "fail_hard" for the "self" option have
+ been removed.
+
+. The obsolete "log" command has been removed from the filter language.
+
+. "service" was an obsolete synonym for "port" when specifying IP port numbers.
+ It has been removed.
+
+. The obsolete option collapse_source_routes has been removed. It has done
+ nothing since release 3.10.
+
+. The obsolete from_hack option in appendfile and pipe transports has been
+ removed.
+
+. The obsolete ipv4_address_lookup has been abolished (dns_ipv4_lookup has been
+ a synonym for some time, but it's changed - see above).
+
+. The obsolete generic transport options add_headers and remove_headers have
+ been abolished. The new names, headers_add and headers_remove, have been
+ available for some time.
+
+Philip Hazel
+February 2002
diff --git a/doc/doc-txt/NewStuff b/doc/doc-txt/NewStuff
new file mode 100644
index 000000000..dfcc5e711
--- /dev/null
+++ b/doc/doc-txt/NewStuff
@@ -0,0 +1,605 @@
+$Cambridge: exim/doc/doc-txt/NewStuff,v 1.1 2004/10/07 15:04:35 ph10 Exp $
+
+New Features in Exim
+--------------------
+
+This file contains descriptions of new features that have been added to Exim,
+but have not yet made it into the main manual (which is most conveniently
+updated when there is a relatively large batch of changes). The doc/ChangeLog
+file contains a listing of all changes, including bug fixes.
+
+
+Version 4.43
+------------
+
+ 1. There is a new Boolean global option called mua_wrapper, defaulting false.
+ This causes Exim to run an a restricted mode, in order to provide a very
+ specific service.
+
+ Background: On a personal computer, it is a common requirement for all
+ email to be sent to a smarthost. There are plenty of MUAs that can be
+ configured to operate that way, for all the popular operating systems.
+ However, there are MUAs for Unix-like systems that cannot be so configured:
+ they submit messages using the command line interface of
+ /usr/sbin/sendmail. In addition, utility programs such as cron submit
+ messages this way.
+
+ Requirement: The requirement is for something that can provide the
+ /usr/sbin/sendmail interface and deliver messages to a smarthost, but not
+ provide any queueing or retrying facilities. Furthermore, the delivery to
+ the smarthost should be synchronous, so that if it fails, the sending MUA
+ is immediately informed. In other words, we want something that in effect
+ converts a command-line MUA into a TCP/SMTP MUA.
+
+ Solutions: There are a number of applications (for example, ssmtp) that do
+ this job. However, people have found them to be lacking in various ways.
+ For instance, some sites want to allow aliasing and forwarding before
+ sending to the smarthost.
+
+ Using Exim: Exim already had the necessary infrastructure for doing this
+ job. Just a few tweaks were needed to make it behave as required, though it
+ is somewhat of an overkill to use a fully-featured MTA for this purpose.
+
+ Setting mua_wrapper=true causes Exim to run in a special mode where it
+ assumes that it is being used to "wrap" a command-line MUA in the manner
+ just described.
+
+ If you set mua_wrapper=true, you also need to provide a compatible router
+ and transport configuration. Typically there will be just one router and
+ one transport, sending everything to a smarthost.
+
+ When run in MUA wrapping mode, the behaviour of Exim changes in the
+ following ways:
+
+ (a) A daemon cannot be run, nor will Exim accept incoming messages from
+ inetd. In other words, the only way to submit messages is via the
+ command line.
+
+ (b) Each message is synchonously delivered as soon as it is received (-odi
+ is assumed). All queueing options (queue_only, queue_smtp_domains,
+ control=queue, control=freeze in an ACL etc.) are quietly ignored. The
+ Exim reception process does not finish until the delivery attempt is
+ complete. If the delivery was successful, a zero return code is given.
+
+ (c) Address redirection is permitted, but the final routing for all
+ addresses must be to the same remote transport, and to the same list of
+ hosts. Furthermore, the return_address must be the same for all
+ recipients, as must any added or deleted header lines. In other words,
+ it must be possible to deliver the message in a single SMTP
+ transaction, however many recipients there are.
+
+ (d) If the conditions in (c) are not met, or if routing any address results
+ in a failure or defer status, or if Exim is unable to deliver all the
+ recipients successfully to one of the hosts immediately, delivery of
+ the entire message fails.
+
+ (e) Because no queueing is allowed, all failures are treated as permanent;
+ there is no distinction between 4xx and 5xx SMTP response codes from
+ the smarthost. Furthermore, because only a single yes/no response can
+ be given to the caller, it is not possible to deliver to some
+ recipients and not others. If there is an error (temporary or
+ permanent) for any recipient, all are failed.
+
+ (f) If more than one host is listed, Exim will try another host after a
+ connection failure or a timeout, in the normal way. However, if this
+ kind of failure happens for all the hosts, the delivery fails.
+
+ (g) When delivery fails, an error message is written to the standard error
+ stream (as well as to Exim's log), and Exim exits to the caller with a
+ return code value 1. The message is expunged from Exim's spool files.
+ No bounce messages are ever generated.
+
+ (h) No retry data is maintained, and any retry rules are ignored.
+
+ (i) A number of Exim options are overridden: deliver_drop_privilege is
+ forced true, max_rcpt in the smtp transport is forced to "unlimited",
+ remote_max_parallel is forced to one, and fallback hosts are ignored.
+
+ The overall effect is that Exim makes a single synchronous attempt to
+ deliver the message, failing if there is any kind of problem. Because no
+ local deliveries are done and no daemon can be run, Exim does not need root
+ privilege. It should be possible to run it setuid=exim instead of
+ setuid=root. See section 48.3 in the 4.40 manual for a general discussion
+ about the advantages and disadvantages of running without root privilege.
+
+ 2. There have been problems with DNS servers when SRV records are looked up.
+ Some mis-behaving servers return a DNS error or timeout when a non-existent
+ SRV record is sought. Similar problems have in the past been reported for
+ MX records. The global dns_again_means_nonexist option can help with this
+ problem, but it is heavy-handed because it is a global option. There are
+ now two new options for the dnslookup router. They are called
+ srv_fail_domains and mx_fail_domains. In each case, the value is a domain
+ list. If an attempt to look up an SRV or MX record results in a DNS failure
+ or "try again" response, and the domain matches the relevant list, Exim
+ behaves as if the DNS had responded "no such record". In the case of an SRV
+ lookup, this means that the router proceeds to look for MX records; in the
+ case of an MX lookup, it proceeds to look for A or AAAA records, unless the
+ domain matches mx_domains.
+
+ 3. The following functions are now available in the local_scan() API:
+
+ (a) void header_remove(int occurrence, uschar *name)
+
+ This function removes header lines. If "occurrence" is zero or negative,
+ all occurrences of the header are removed. If occurrence is greater
+ than zero, that particular instance of the header is removed. If no
+ header(s) can be found that match the specification, the function does
+ nothing.
+
+ (b) BOOL header_testname(header_line *hdr, uschar *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 colon. If the "notdel" argument is TRUE, a
+ FALSE return is forced for all "deleted" headers; otherwise they are
+ not treated specially. For example:
+
+ if (header_testname(h, US"X-Spam", 6, TRUE)) ...
+
+ (c) void header_add_at_position(BOOL after, uschar *name, BOOL topnot,
+ int type, char *format, ...)
+
+ This function adds a new header line at a specified point in the header
+ chain. If "name" is NULL, the new header is added at the end of the
+ chain if "after" is TRUE, or at the start if "after" is FALSE. If
+ "name" is not NULL, the headers are searched for the first non-deleted
+ header that matches the name. If one is found, the new header is added
+ before it if "after" is FALSE. If "after" is true, the new header is
+ added after the found header and any adjacent subsequent ones with the
+ same name (even if marked "deleted"). If no matching non-deleted header
+ is found, the "topnot" option controls where the header is added. If it
+ is TRUE, addition is at the top; otherwise at the bottom. Thus, to add
+ a header after all the Received: headers, or at the top if there are no
+ Received: headers, you could use
+
+ header_add_at_position(TRUE, US"Received", TRUE, ' ', "X-xxx: ...");
+
+ Normally, there is always at least one non-deleted Received: header,
+ but there may not be if received_header_text expands to an empty
+ string.
+
+ (d) BOOL receive_remove_recipient(uschar *recipient)
+
+ This is a convenience function to remove a named recipient from the
+ list of recipients. It returns TRUE if a recipient was removed, and
+ FALSE if no matching recipient could be found. The argument must be a
+ complete email address.
+
+ 4. When an ACL "warn" statement adds one or more header lines to a message,
+ they are added at the end of the existing header lines by default. It is
+ now possible to specify that any particular header line should be added
+ right at the start (before all the Received: lines) or immediately after
+ the first block of Received: lines in the message. This is done by
+ specifying :at_start: or :after_received: (or, for completeness, :at_end:)
+ before the text of the header line. (Header text cannot start with a colon,
+ as there has to be a header name first.) For example:
+
+ warn message = :after_received:X-My-Header: something or other...
+
+ If more than one header is supplied in a single warn statement, each one is
+ treated independently and can therefore be placed differently. If you add
+ more than one line at the start, or after the Received: block, they will
+ end up in reverse order.
+
+ Warning: This facility currently applies only to header lines that are
+ added in an ACL. It does NOT work for header lines that are added in a
+ system filter or in a router or transport.
+
+ 5. There is now a new error code that can be used in retry rules. Its name is
+ "rcpt_4xx", and there are three forms. A literal "rcpt_4xx" matches any 4xx
+ error received for an outgoing SMTP RCPT command; alternatively, either the
+ first or both of the x's can be given as digits, for example: "rcpt_45x" or
+ "rcpt_436". If you want (say) to recognize 452 errors given to RCPT
+ commands by a particular host, and have only a one-hour retry for them, you
+ can set up a retry rule of this form:
+
+ the.host.name rcpt_452 F,1h,10m
+
+ Naturally, this rule must come before any others that would match.
+
+ These new errors apply to both outgoing SMTP (the smtp transport) and
+ outgoing LMTP (either the lmtp transport, or the smtp transport in LMTP
+ mode). Note, however, that they apply only to responses to RCPT commands.
+
+ 6. The "postmaster" option of the callout feature of address verification has
+ been extended to make it possible to use a non-empty MAIL FROM address when
+ checking a postmaster address. The new suboption is called "postmaster_
+ mailfrom", and you use it like this:
+
+ require verify = sender/callout=postmaster_mailfrom=abc@x.y.z
+
+ Providing this suboption causes the postmaster check to be done using the
+ given address. The original "postmaster" option is equivalent to
+
+ require verify = sender/callout=postmaster_mailfrom=
+
+ If both suboptions are present, the rightmost one overrides.
+
+ Important notes:
+
+ (1) If you use a non-empty sender address for postmaster checking, there is
+ the likelihood that the remote host will itself initiate a callout
+ check back to your host to check that address. As this is a "normal"
+ callout check, the sender will most probably be empty, thus avoiding
+ possible callout loops. However, to be on the safe side it would be
+ best to set up your own ACLs so that they do not do sender verification
+ checks when the recipient is the address you use for postmaster callout
+ checking.
+
+ (2) The caching arrangements for postmaster checking do NOT take account of
+ the sender address. It is assumed that either the empty address, or a
+ fixed non-empty address will be used. All that Exim remembers is that
+ the postmaster check for the domain succeeded or failed.
+
+ 7. When verifying addresses in header lines using the verify=header_sender
+ option, Exim behaves by default as if the addresses are envelope sender
+ addresses from a message. Callout verification therefore tests to see
+ whether a bounce message could be delivered, by using an empty address in
+ the MAIL FROM command. However, it is arguable that these addresses might
+ never be used as envelope senders, and could therefore justifiably reject
+ bounce messages (empty senders). There is now an additional callout option
+ for verify=header_sender that allows you to specify what address to use in
+ the MAIL FROM command. You use it as in this example:
+
+ require verify = header_sender/callout=mailfrom=abcd@x.y.z
+
+ Important notes:
+
+ (1) As in the case of postmaster_mailfrom (see above), you should think
+ about possible loops.
+
+ (2) In this case, as in the case of recipient callouts with non-empty
+ senders (the use_sender option), caching is done on the basis of a
+ recipient/sender pair.
+
+ 8. If you build Exim with USE_READLINE=yes in Local/Makefile, it will try to
+ load libreadline dynamically whenever the -be (test expansion) option is
+ used without command line arguments. If successful, it will then use
+ readline() for reading the test data. A line history is supported. By the
+ time Exim does this, it is running as the calling user, so this should not
+ cause any security problems. Security is the reason why this is NOT
+ supported for -bt or -bv, when Exim is running as root or exim,
+ respectively. Note that this option adds to the size of the Exim binary,
+ because the dynamic loading library is not otherwise included. On my
+ desktop it adds about 2.5K. You may need to add -ldl to EXTRA_LIBS when you
+ set USE_READLINE=yes.
+
+ 9. Added ${str2b64:<string>} to the expansion operators. This operator
+ converts an arbitrary string into one that is base64 encoded.
+
+10. A new authenticator, called cyrus_sasl, has been added. This requires
+ the presence of the Cyrus SASL library; it authenticates by calling this
+ library, which supports a number of authentication mechanisms, including
+ PLAIN and LOGIN, but also several others that Exim does not support
+ directly. The code for this authenticator was provided by Matthew
+ Byng-Maddick of A L Digital Ltd (http://www.aldigital.co.uk). Here follows
+ draft documentation:
+
+ xx. THE CYRUS_SASL AUTHENTICATOR
+
+ The cyrus_sasl authenticator provides server support for the Cyrus library
+ Implementation of the RFC 2222 "Simple Authentication and Security Layer".
+ It provides a gatewaying mechanism directly to the Cyrus interface, so if
+ your Cyrus library can do, for example, CRAM-MD5, then so can the
+ cyrus_sasl authenticator. By default it uses the public name of the driver
+ to determine which mechanism to support.
+
+ Where access to some kind of secret file is required, for example in GSSAPI
+ or CRAM-MD5, it is worth noting that the authenticator runs as the exim
+ user, and that the Cyrus SASL library has no way of escalating privileges
+ by default. You may also find you need to set environment variables,
+ depending on the driver you are using.
+
+ xx.1 Using cyrus_sasl as a server
+
+ The cyrus_sasl authenticator has four private options. It puts the username
+ (on a successful authentication) into $1.
+
+ server_hostname Type: string* Default: $primary_hostname
+
+ This option selects the hostname that is used when communicating with
+ the library. It is up to the underlying SASL plug-in what it does with
+ this data.
+
+ server_mech Type: string Default: public_name
+
+ This option selects the authentication mechanism this driver should
+ use. It allows you to use a different underlying mechanism from the
+ advertised name. For example:
+
+ sasl:
+ driver = cyrus_sasl
+ public_name = X-ANYTHING
+ server_mech = CRAM-MD5
+ server_set_id = $1
+
+ server_realm Type: string Default: unset
+
+ This is the SASL realm that the server is claiming to be in.
+
+ server_service Type: string Default: "smtp"
+
+ This is the SASL service that the server claims to implement.
+
+ For straigthforward cases, you do not need to set any of the
+ authenticator's private options. All you need to do is to specify an
+ appropriate mechanism as the public name. Thus, if you have a SASL library
+ that supports CRAM-MD5 and PLAIN, you might have two authenticators as
+ follows:
+
+ sasl_cram_md5:
+ driver = cyrus_sasl
+ public_name = CRAM-MD5
+ server_set_id = $1
+
+ sasl_plain:
+ driver = cyrus_sasl
+ public_name = PLAIN
+ server_set_id = $1
+
+11. There is a new global option called tls_on_connect_ports. Its value must be
+ a list of port numbers; the most common use is expected to be
+
+ tls_on_connect_ports = 465
+
+ Setting this option has the same effect as -tls-on-connect on the command
+ line, but only for the specified ports. It applies to all connections, both
+ via the daemon and via inetd. You still need to specify all the ports for
+ the daemon (using daemon_smtp_ports or local_interfaces or the -X command
+ line option) because this option does not add an extra port -- rather, it
+ specifies different behaviour on a port that is defined elsewhere. The
+ -tls-on-connect command line option overrides tls_on_connect_ports, and
+ forces tls-on-connect for all ports.
+
+12. There is a new ACL that is run when a DATA command is received, before the
+ data itself is received. The ACL is defined by acl_smtp_predata. (Compare
+ acl_smtp_data, which is run after the data has been received.)
+ This new ACL allows a negative response to be given to the DATA command
+ itself. Header lines added by MAIL or RCPT ACLs are not visible at this
+ time, but any that are defined here are visible when the acl_smtp_data ACL
+ is run.
+
+13. The "control=submission" ACL modifier has an option "/domain=xxx" which
+ specifies the domain to be used when creating From: or Sender: lines using
+ the authenticated id as a local part. If the option is supplied with an
+ empty domain, that is, just "/domain=", Exim assumes that the authenticated
+ id is a complete email address, and it uses it as is when creating From:
+ or Sender: lines.
+
+14. It is now possible to make retry rules that apply only when the failing
+ message has a specific sender. In particular, this can be used to define
+ retry rules that apply only to bounce messages. The syntax is to add a new
+ third item to a retry rule, of the form "senders=<address list>". The retry
+ timings themselves then become the fourth item. For example:
+
+ * * senders=: F,1h,30m
+
+ would match all bounce messages. If the address list contains white space,
+ it must be enclosed in quotes. For example:
+
+ a.domain timeout senders="x@b.dom : y@c.dom" G,8h,10m,1.5
+
+ When testing retry rules using -brt, you can supply a sender using the -f
+ command line option, like this:
+
+ exim -f "" -brt user@dom.ain
+
+ If you do not set -f with -brt, a retry rule that contains a senders list
+ will never be matched.
+
+15. Two new control modifiers have been added to ACLs: "control = enforce_sync"
+ and "control = no_enforce_sync". This makes it possible to be selective
+ about when SMTP synchronization is enforced. The global option
+ smtp_enforce_sync now specifies the default state of the switch. These
+ controls can appear in any ACL, but the most obvious place to put them is
+ in the ACL defined by acl_smtp_connect, which is run at the start of an
+ incoming SMTP connection, before the first synchronization check.
+
+16. Another two new control modifiers are "control = caseful_local_part" and
+ "control = caselower_local_part". These are permitted only in the ACL
+ specified by acl_smtp_rcpt (i.e. during RCPT processing). By default, the
+ contents of $local_part are lower cased before ACL processing.
+ After "control = caseful_local_part", any uppercase letters in the original
+ local part are restored in $local_part for the rest of the ACL, or until
+ "control = caselower_local_part" is encountered. However, this applies only
+ to local part handling that takes place directly in the ACL (for example,
+ as a key in lookups). If a "verify = recipient" test is obeyed, the
+ case-related handling of the local part during the verification is
+ controlled by the router configuration (see the caseful_local_part generic
+ router option).
+
+ This facility could be used, for example, to add a spam score to local
+ parts containing upper case letters. For example, using $acl_m4 to
+ accumulate the spam score:
+
+ warn control = caseful_local_part
+ set acl_m4 = ${eval:\
+ $acl_m4 + \
+ ${if match{$local_part}{[A-Z]}{1}{0}}\
+ }
+ control = caselower_local_part
+
+ Notice that we put back the lower cased version afterwards, assuming that
+ is what is wanted for subsequent tests.
+
+17. The option hosts_connection_nolog is provided so that certain hosts can be
+ excepted from logging when the +smtp_connection log selector is set. For
+ example, you might want not to log SMTP connections from local processes,
+ or from 127.0.0.1, or from your local LAN. The option is a host list with
+ an unset default. Because it is consulted in the main loop of the daemon,
+ you should strive to restrict its value to a short inline list of IP
+ addresses and networks. To disable logging SMTP connections from local
+ processes, you must create a host list with an empty item. For example:
+
+ hosts_connection_nolog = :
+
+ If the +smtp_connection log selector is not set, this option has no effect.
+
+18. There is now an acl called acl_smtp_quit, which is run for the QUIT
+ command. 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 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" command.
+
+ 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.
+
+ This ACL is run only for a "normal" QUIT. For certain kinds of disastrous
+ failure (for example, failure to open a log file, or when Exim is bombing
+ out because it has detected an unrecoverable error), all SMTP commands
+ from the client are given temporary error responses until QUIT is received
+ or the connection is closed. In these special cases, the ACL is not run.
+
+19. The appendfile transport has two new options, mailbox_size and mailbox_
+ filecount. If either these options are set, it is expanded, and the result
+ is taken as the current size of the mailbox or the number of files in the
+ mailbox, respectively. This makes it possible to use some external means of
+ maintaining the data about the size of a mailbox for enforcing quota
+ limits. The result of expanding these option values must be a decimal
+ number, optionally followed by "K" or "M".
+
+20. It seems that there are broken clients in use that cannot handle multiline
+ SMTP responses. Can't people who implement these braindead programs read?
+ RFC 821 mentions multiline responses, and it is over 20 years old. They
+ must handle multiline responses for EHLO, or do they still use HELO?
+ Anyway, here is YAWFAB (yet another workaround for asinine brokenness).
+ There's a new ACL switch that can be set by
+
+ control = no_multiline_responses
+
+ If this is set, it suppresses multiline SMTP responses from ACL rejections.
+ One way of doing this would have been just to put out these responses as
+ one long line. However, RFC 2821 specifies a maximum of 512 bytes per
+ response ("use multiline responses for more" it says), and some of the
+ responses might get close to that. So I have implemented this by doing two
+ very easy things:
+
+ (1) Extra information that is normally output as part of a rejection
+ caused by sender verification failure is omitted. Only the final line
+ (typically "sender verification failed") is now sent.
+
+ (2) If a "message" modifier supplies a multiline response, only the first
+ line is output.
+
+ The setting of the switch can, of course, be made conditional on the
+ calling host.
+
+21. There is now support for the libradius library that comes with FreeBSD.
+ This is an alternative to the radiusclient library that Exim already
+ supports. To use the FreeBSD library, you need to set
+
+ RADIUS_LIB_TYPE=RADLIB
+
+ in Local/Makefile, in addition to RADIUS_CONFIGURE_FILE, and you probably
+ also need -libradius in EXTRALIBS.
+
+
+Version 4.42
+------------
+
+ 1. The "personal" filter test is brought up-to-date with recommendations from
+ the Sieve specification: (a) The list of non-personal From: addresses now
+ includes "listserv", "majordomo", and "*-request"; (b) If the message
+ contains any header line starting with "List=-" it is treated as
+ non-personal.
+
+ 2. The Sieve functionality has been extended to support the "copy" and
+ "vacation" extensions, and comparison tests.
+
+ 3. There is now an overall timeout for performing a callout verification. It
+ defaults to 4 times the callout timeout, which applies to individual SMTP
+ commands during the callout. The overall timeout applies when there is more
+ than one host that can be tried. The timeout is checked before trying the
+ next host. This prevents very long delays if there are a large number of
+ hosts and all are timing out (e.g. when the network connections are timing
+ out). The value of the overall timeout can be changed by specifying an
+ additional sub-option for "callout", called "maxwait". For example:
+
+ verify = sender/callout=5s,maxwait=20s
+
+ 4. Changes to the "personal" filter test:
+
+ (1) The list of non-personal local parts in From: addresses has been
+ extended to include "listserv", "majordomo", "*-request", and "owner-*",
+ taken from the Sieve specification recommendations.
+
+ (2) If the message contains any header line starting with "List-" it is
+ treated as non-personal.
+
+ (3) The test for "circular" in the Subject: header line has been removed
+ because it now seems ill-conceived.
+
+ 5. The autoreply transport has a new option called never_mail. This is an
+ address list. If any run of the transport creates a message with a
+ recipient that matches any item in the list, that recipient is quietly
+ discarded. If all recipients are discarded, no message is created.
+
+
+Version 4.40
+------------
+
+The documentation is up-to-date for the 4.40 release. What follows here is a
+brief list of the new features that have been added since 4.30.
+
+ 1. log_incoming_interface affects more log lines.
+
+ 2. New ACL modifier "control = submission".
+
+ 3. CONFIGURE_OWNER can be set at build time to define an alternative owner for
+ the configuration file, in addition to root and exim.
+
+ 4. Added expansion variables $body_zerocount, $recipient_data, and
+ $sender_data.
+
+ 5. The time of last modification of the "new" subdirectory is now used as the
+ "mailbox time last read" when there is a quota error for a maildir
+ delivery.
+
+ 6. The special item "+ignore_unknown" may now appear in host lists.
+
+ 7. The special domain-matching patterns @mx_any, @mx_primary, and
+ @mx_secondary can now be followed by "/ignore=<ip list>".
+
+ 8. New expansion conditions: match_domain, match_address, match_local_part,
+ lt, lti, le, lei, gt, gti, ge, and new expansion operators time_interval,
+ eval10, and base62d.
+
+ 9. New lookup type called "iplsearch".
+
+10. New log selectors ident_timeout, tls_certificate_verified, queue_time,
+ deliver_time, outgoing_port, return_path_on_delivery.
+
+11. New global options smtp_active_hostname and tls_require_ciphers.
+
+12. Exinext has -C and -D options.
+
+13. "domainlist_cache" forces caching of an apparently variable list.
+
+14. For compatibility with Sendmail, the command line option -prval:sval
+ is equivalent to -oMr rval -oMs sval.
+
+15. New callout options use_sender and use_postmaster for use when verifying
+ recipients.
+
+16. John Jetmore's "exipick" utility has been added to the distribution.
+
+17. The TLS code now supports CRLs.
+
+18. The dnslookup router and the dnsdb lookup type now support the use of SRV
+ records.
+
+19. The redirect router has a new option called qualify_domain.
+
+20. exigrep's output now also includes lines that are not related to any
+ particular message, but which do match the pattern.
+
+21. New global option write_rejectlog. If it is set false, Exim no longer
+ writes anything to the reject log.
+
+****
diff --git a/doc/doc-txt/OptionLists.txt b/doc/doc-txt/OptionLists.txt
new file mode 100644
index 000000000..2437abfa8
--- /dev/null
+++ b/doc/doc-txt/OptionLists.txt
@@ -0,0 +1,927 @@
+$Cambridge: exim/doc/doc-txt/OptionLists.txt,v 1.1 2004/10/07 15:04:35 ph10 Exp $
+
+LISTS OF EXIM OPTIONS
+---------------------
+
+This file contains complete lists of three kinds of Exim option:
+
+ 1. Those that can appear in the run time configuration file;
+ 2. Those that can be used on the command line;
+ 3. Those that can appear in the build time configuration (Local/Makefile);
+ 4. Those that can appear in the build time configuration for the Exim monitor
+ (Local/eximon.conf).
+
+This file was last updated for Exim release 4.40.
+
+
+1. RUN TIME OPTIONS
+-------------------
+
+As Exim has developed, new options have been added at each major release. For
+the most part, backwards compatibility has been maintained, and obsolete
+options continue to be recognized. However, incompatible changes took place at
+releases 3.00, and 4.00. In both cases, several groups of options were
+amalgamated into new, extended options, and obsolete options were removed.
+
+The table below contains a complete list of all Exim's current options, along
+with their types, default values, and where they can be used. String options
+that are expanded before use are marked with *. Host lists, domain lists, and
+address lists are always expanded. In some cases the defaults are not fixed
+values, or not short enough to fit in the table. These are indicated by +. Some
+other default values are determined when the Exim binary is compiled; these are
+indicated by ++.
+
+For options that are specific to a particular driver, the fourth column
+contains the driver name, for example, appendfile. Otherwise, it contains
+
+ . `main' for options that appear in the main section of Exim's configuration
+ file;
+
+ . `authenticators' for generic options that apply to any authenticator;
+
+ . `routers' for generic options that apply to any router;
+
+ . `transports' for generic options that apply to any transport.
+
+The fifth column contains the version of Exim in which the option was added, or
+substantially changed. Where no number is given, the option has been in Exim
+since the very early releases. The routers were completely reorganised for
+release 4.00, and so no router options are shown as earlier than 4.00, though
+in fact some of them were inherited from earlier versions.
+
+-----------------------------------------------------------------------------------------
+accept_8bitmime boolean false main 1.60
+acl_not_smtp string* unset main 4.11
+acl_smtp_auth string* unset main 4.00
+acl_smtp_connect string* unset main 4.11
+acl_smtp_data string* unset main 4.00
+acl_smtp_etrn string* unset main 4.00
+acl_smtp_expn string* unset main 4.00
+acl_smtp_helo string* unset main 4.20
+acl_smtp_mail string* unset main 4.11
+acl_smtp_mailauth string* unset main 4.21
+acl_smtp_predata string* unset main 4.43
+acl_smtp_quit string* unset main 4.43
+acl_smtp_rcpt string* unset main 4.00
+acl_smtp_starttls string* unset main 4.11
+acl_smtp_vrfy string* unset main 4.00
+address_data string* unset routers 4.00
+address_test boolean true routers 4.14
+admin_groups string list unset main 3.02
+allow_domain_literals boolean false main 4.00 replacing forbid_domain_literals
+allow_commands string list* unset pipe 1.89
+allow_defer boolean false redirect 4.00
+allow_fail boolean false redirect 4.00
+allow_filter boolean false redirect 4.00
+allow_freeze boolean false redirect 4.00
+allow_fifo boolean false appendfile 3.13
+allow_localhost boolean false smtp 1.73
+allow_mx_to_ip boolean false main 3.14
+allow_symlink boolean false appendfile
+allow_utf8_domains boolean false main 4.14
+auth_advertise_hosts host list "*" main 4.00
+authenticated_sender string* unset smtp 4.14
+authenticate_hosts host list unset smtp 3.13
+auto_thaw time 0s main
+batch_id string unset appendfile 4.00
+ unset lmtp 4.00
+ unset pipe 4.00
+batch_max integer 100 appendfile
+ 100 lmtp 3.20
+ 100 pipe
+bcc string* unset autoreply
+bi_command string unset main
+body_only boolean false transports 2.05
+bounce_message_file string unset main 4.00
+bounce_message_text string unset main 4.00
+bounce_return_body boolean true main 4.23
+bounce_return_message boolean true main 4.00
+bounce_return_size_limit int 100K main 4.23 better name for return_size_limit
+bounce_sender_authentication string unset main 4.00
+callout_domain_negative_expire time 3h main 4.11
+callout_domain_positive_expire time 7d main 4.11
+callout_negative_expire time 2h main 4.11
+callout_positive_expire time 24h main 4.11
+callout_random_local_part string* + main 4.11
+cannot_route_message string* unset routers 4.11
+caseful_local_part boolean false routers 4.00
+cc string* unset autoreply
+check_ancestor boolean false redirect 4.00
+check_group boolean false appendfile
+ + redirect 4.00
+check_local_user boolean false routers 4.00
+check_log_inodes integer 0 main
+check_log_space integer 0 main
+check_owner boolean true appendfile 3.14
+ + redirect 4.00
+check_secondary_mx boolean false dnslookup 4.00
+check_spool_inodes integer 0 main
+check_spool_space integer 0 main
+check_string string "From " appendfile 3.03
+ unset pipe 3.03
+check_srv string* unset dnslookup 4.31
+client_name string* + cram_md5 3.10
+client_secret string* unset cram_md5 3.10
+client_send string* unset plaintext 3.10
+command string* unset lmtp 3.20
+ unset pipe
+ unset queryprogram 4.00
+command_group string unset queryprogram 4.00
+command_timeout time 5m smtp
+command_user string unset queryprogram 4.00
+condition string* unset routers 4.00
+connect_timeout time 0s smtp 1.60
+connection_max_messages integer 500 smtp 4.00 replaces batch_max
+create_directory boolean true appendfile
+create_file string "anywhere" appendfile
+current_directory string unset transports 4.00
+ unset queryprogram 4.00
+daemon_smtp_ports string unset main 1.75 pluralised in 4.21
+data string unset redirect 4.00
+data_timeout time 5m smtp
+debug_print string* unset authenticators 4.00
+ unset routers 4.00
+ unset transports 2.00
+delay_after_cutoff boolean true smtp
+delay_warning time list 24h main
+delay_warning_condition string* + main 1.73
+deliver_drop_privilege boolean false main 4.00
+deliver_queue_load_max fixed-point unset main 1.70
+delivery_date_add boolean false transports
+delivery_date_remove boolean true main
+directory string* unset appendfile
+directory_mode octal-integer 0700 appendfile
+directory_transport string* unset redirect 4.00
+disable_logging boolean false routers 4.11
+disable_logging boolean false transports 4.11
+dns_again_means_nonexist domain list unset main 1.89
+dns_check_names_pattern string + main 2.11
+dns_ipv4_lookup boolean false main 3.20
+dns_qualify_single boolean true smtp
+dns_retrans time 0s main 1.60
+dns_retry integer 0 main 1.60
+dns_search_parents boolean false smtp
+domains domain list unset routers 4.00
+driver string unset authenticators
+ unset routers 4.00
+ unset transports
+drop_cr boolean false main 4.00 became a no-op in 4.21
+envelope_to_add boolean false transports
+envelope_to_remove boolean true main
+environment string* unset pipe 2.95
+errors_copy string list* unset main
+errors_reply_to string unset main
+errors_to string* unset routers 4.00
+escape_string string ">From " appendfile 3.03
+ unset pipe 3.03
+exim_group string ++ main
+exim_path string ++ main
+exim_user string ++ main
+expn boolean true routers
+extra_local_interfaces string unset main 4.21
+extract_addresses_remove_arguments boolean true main 1.92
+fail_verify boolean false routers
+fail_verify_recipient boolean false routers 4.00
+fail_verify_sender boolean false routers 4.00
+fallback_hosts string list unset routers 4.00
+ unset smtp
+file string* unset appendfile
+ unset autoreply
+ unset redirect 4.00
+file_expand boolean false autoreply
+file_format string unset appendfile 3.03
+file_must_exist boolean false appendfile
+file_optional boolean false autoreply
+file_transport string* unset redirect 4.00
+final_timeout time 10m smtp
+finduser_retries integer 0 main
+forbid_blackhole boolean false redirect 4.00
+forbid_fail boolean false redirect 4.00
+forbid_file boolean false redirect 4.00
+forbid_filter_existstest boolean false redirect 4.00
+forbid_filter_logwrite boolean false redirect 4.00
+forbid_filter_lookup boolean false redirect 4.00
+forbid_filter_perl boolean false redirect 4.00
+forbid_filter_readfile boolean false redirect 4.00
+forbid_filter_readsocket boolean false redirect 4.11
+forbid_filter_reply boolean false redirect 4.00
+forbid_filter_run boolean false redirect 4.00
+forbid_include boolean false redirect 4.00
+forbid_pipe boolean false redirect 4.00
+freeze_exec_fail boolean false pipe 1.89
+freeze_tell boolean false main 4.00 replaces freeze_tell_mailmaster
+from string* unset autoreply
+gecos_name string* unset main
+gecos_pattern string unset main
+gethostbyname boolean false smtp
+group string + routers 4.00
+ unset transports 4.00 replaces local option in some transports
+header_line_maxsize integer 0 (unset) main 4.14
+header_maxsize integer 1M main 4.14
+headers string* unset autoreply
+headers_add string* unset routers 4.00
+ unset transports
+headers_charset string ++ main 4.21
+headers_only boolean false transports 2.05
+headers_remove string* unset routers 4.00
+ unset transports
+headers_rewrite string unset transports 3.20
+helo_accept_junk_hosts host list unset main 3.00
+helo_allow_chars string "" main 4.02
+helo_lookup_domains domain list unset main 4.00
+helo_data string* "$primary_hostname" smtp 3.21
+helo_try_verify_hosts host list unset main 4.00
+helo_verify_hosts host list unset main 1.73
+hide_child_in_errmsg false redirect 4.00
+hold_domains domain list unset main 1.70
+home_directory string* unset transports 4.00 replaces individual options
+host_find_failed string "freeze" manualroute 4.00
+host_lookup host list unset main 3.00
+host_lookup_order string list "bydns:byaddr" main 4.30
+host_reject_connection host list unset main 4.00
+hosts string unset iplookup 4.00
+ string list* unset smtp
+hosts_avoid_esmtp host list unset smtp 4.21
+hosts_avoid_tls host list unset smtp 3.20
+hosts_connection_nolog host list unset main 4.43
+hosts_max_try integer 5 smtp 3.20
+hosts_nopass_tls host list unset smtp 4.00
+hosts_override boolean false smtp 2.11
+hosts_randomize boolean false manualroute 4.00
+ false smtp 3.14
+hosts_require_auth host list unset smtp 4.00
+hosts_require_tls host list unset smtp 3.20
+hosts_treat_as_local domain list unset main 1.95
+hosts_try_auth host list unset smtp 4.00
+ignore_bounce_errors_after time 0s main 4.00
+ignore_eacces boolean false redirect 4.00
+ignore_enotdir boolean false redirect 4.00
+ignore_fromline_hosts host list unset main
+ignore_fromline_local boolean false main 2.05
+ignore_status boolean false pipe
+ignore_target_hosts host list unset routers 4.00
+include_directory string unset redirect 4.00
+initgroups false routers 4.00
+interface string list unset smtp 1.70
+keep_malformed time 4d main
+keepalive boolean true smtp 2.05
+ldap_default_servers string list unset main 3.02
+ldap_version int 2 or 3 main 4.14
+local_from_check boolean true main 3.14
+local_from_prefix string unset main 3.14
+local_from_suffix string unset main 3.14
+local_interfaces string list unset main 1.60
+local_part_prefix string unset routers 4.00 replaces prefix
+local_part_prefix_optional boolean unset routers 4.00 replaces prefix_optional
+local_part_suffix string unset routers 4.00 replaces suffix
+local_part_suffix_optional boolean unset routers 4.00 replaces suffix_optional
+local_parts string list* unset routers 4.00
+local_scan_timeout time 5m main 4.03
+local_sender_retain boolean false main 4.00
+localhost_number string unset main
+lock_fcntl_timeout time 0s appendfile 3.14
+lock_flock_timeout time 0s appendfile 4.11
+lock_interval time 3s appendfile
+lock_retries integer 10 appendfile
+lockfile_mode octal-integer 0600 appendfile
+lockfile_timeout time 30m appendfile
+log string* unset autoreply
+log_as_local boolean + routers 4.00
+log_file_path string list ++ main
+log_defer_output boolean false pipe 1.89
+log_fail_output boolean false pipe 1.60
+log_output boolean false pipe 1.60
+log_selector string unset main 4.00
+log_timezone boolean false main 4.11
+lookup_open_max integer 25 main 2.05
+mailbox_filecount string* unset appendfile 4.43
+mailbox_size string* unset appendfile 4.43
+maildir_format boolean false appendfile 1.70
+maildir_retries integer 10 appendfile 1.70
+maildir_tag string* unset appendfile 1.92
+maildir_use_size_file boolean false appendfile 4.30
+mailstore_format boolean false appendfile 2.00
+mailstore_prefix string* unset appendfile 2.00
+mailstore_suffix string* unset appendfile 2.00
+match_directory string* unset localuser
+max_output integer 20K pipe
+max_rcpt integer 100 smtp 1.60
+max_user_name_length integer 0 main
+mbx_format boolean false appendfile 2.10
+message_body_visible integer 500 main
+message_id_header_domain string* unset main 4.11
+message_id_header_text string* unset main
+message_logs boolean true main 4.10
+message_prefix string* + appendfile 4.00 replaces prefix
+ string* unset pipe 4.00 replaces prefix
+message_size_limit integer 0 main
+ 0 transports 2.05
+message_suffix string* + appendfile 4.00 replaces suffix
+ string* unset pipe 4.00 replaces suffix
+mode octal-integer 0600 appendfile
+ 0600 autoreply
+mode_fail_narrower boolean true appendfile 1.70
+modemask octal-integer 022 redirect 4.00
+more boolean true routers 4.00
+move_frozen_messages boolean false main 3.09
+multi_domain boolean true smtp
+mx_domains domain list unset dnslookup 4.00
+mx_fail_domains domain list unset dnslookup 4.43
+mysql_servers string list unset main 3.03
+never_users string list unset main
+notify_comsat boolean false appendfile
+once string* unset autoreply
+once_file_size integer 0 autoreply 3.20
+once_repeat time 0s autoreply 2.95
+one_time boolean false redirect 4.00
+optional boolean false iplookup 4.00
+oracle_servers string unset main 4.00
+owners string list unset redirect 4.00
+owngroups string list unset redirect 4.00
+pass_on_timeout boolean false routers 4.00
+pass_router string unset routers 4.00
+path string "/usr/bin" pipe
+percent_hack_domains domain list unset main
+perl_at_start boolean false main 2.10
+perl_startup string unset main 2.10
+pgsql_servers string list unset main 3.14
+pid_file_path string ++ main
+pipe_as_creator boolean false pipe
+pipe_transport string* unset redirect 4.00
+pipelining_advertise_hosts host list "*" main 4.14
+port integer 0 iplookup 4.00
+ string "smtp" smtp
+preserve_message_logs boolean false main
+primary_hostname string + main
+print_topbitchars boolean false main 1.89
+process_log_path string unset main 4.21
+prod_requires_admin boolean true main 1.70
+protocol string "udp" iplookup 4.00
+ string "smtp" smtp 3.20
+public_name string unset authenticators 3.10
+qualify_domain string + main
+ string* unset redirect 4.31
+qualify_preserve_domain boolean false redirect 4.00
+qualify_recipient string + main
+qualify_single boolean true dnslookup 4.00
+query string* + iplookup 4.00
+queue_domains domain list unset main 4.00
+queue_list_requires_admin boolean true main 1.95
+queue_only boolean false main
+queue_only_file string unset main 2.05
+queue_only_load fixed-point unset main
+queue_only_override boolean true main 4.21
+queue_run_in_order boolean false main 1.70
+queue_run_max integer 5 main
+queue_smtp_domains domain list unset main
+quota string* unset appendfile 1.60
+quota_directory string* unset appendfile 4.11
+quota_filecount integer 0 appendfile 2.05
+quota_is_inclusive boolean true appendfile 3.20
+quota_size_regex string unset appendfile 3.14
+quota_warn_message string* + appendfile 2.10
+quota_warn_threshold string* 0 appendfile 2.10
+rcpt_include_affixes boolean false transports 4.21
+receive_timeout time 0s main 4.00 replacing accept_timeout
+received_header_text string* + main
+received_headers_max integer 30 main
+recipient_unqualified_hosts host list unset main 4.00 replacing receiver_unqualified_hosts
+recipients_max integer 0 main 1.60
+recipients_max_reject boolean false main 1.70
+redirect_router string unset routers 4.00
+remote_max_parallel integer 1 main
+remote_sort_domains domain list unset main 4.00 replacing remote_sort
+repeat_use boolean true redirect 4.00
+reply_to string* unset autoreply 2.05
+reply_transport string* unset redirect 4.00
+require_files string list* unset routers 4.00
+reroute string* unset iplookup 4.00
+response_pattern string unset iplookup 4.00
+restrict_to_path boolean false pipe
+retry_data_expire time 7d main 3.03
+retry_include_ip_address boolean true smtp 1.92
+retry_interval_max time 24h main
+retry_use_local_part boolean + routers 4.00
+ + transports 4.00 replacing individual options
+return_fail_output boolean false pipe 1.60
+return_message boolean false autoreply
+return_output boolean false pipe
+return_path string* unset transports 2.05
+return_path_add boolean false transports
+return_path_remove boolean true main
+return_size_limit integer 100K main renamed bounce_return_size_limit in 4.23
+rewrite boolean true redirect 4.00
+rewrite_headers boolean true dnslookup 4.00
+rfc1413_hosts host list * main
+rfc1413_query_timeout time 30s main
+router_home_directory string* unset routers 4.11
+route_data string* unset manualroute 4.00
+route_list string list unset manualroute 4.00
+same_domain_copy_routing boolean false dnslookup 4.00
+search_parents boolean false dnslookup 4.00
+self string "freeze" routers 4.00
+sender_unqualified_hosts host list unset main
+senders address list unset routers 4.00
+serialize_hosts host list unset smtp 1.60
+server_advertise_condition string* unset authenticators 4.14
+server_condition string* unset plaintext 3.10
+server_hostname string* "$primary_hostname" cyrus_sasl 4.43
+server_mail_auth_condition string* unset authenticators 3.22
+server_mech string public_name cyrus_sasl 4.43
+server_prompts string* unset plaintext 3.10
+server_realm string unset cyrus_sasl 4.43
+server_secret string* unset cram_md5 3.10
+server_service string "smtp" cyrus_sasl 4.43
+server_set_id string* unset authenticators 3.10
+shadow_condition string* unset transports
+shadow_transport string unset transports
+size_addition integer 1024 smtp 1.91
+skip_syntax_errors boolean false redirect 4.00
+smtp_accept_keepalive boolean true main
+smtp_accept_max integer 20 main
+smtp_accept_max_nonmail integer 10 main 4.11
+smtp_accept_max_nonmail_hosts host list * main 4.14
+smtp_accept_max_per_connection integer 1000 main 4.00
+smtp_accept_max_per_host integer 0 main 2.05
+smtp_accept_queue integer 0 main
+smtp_accept_queue_per_connection integer 10 main 2.03
+smtp_accept_reserve integer 0 main
+smtp_active_hostname string* unset main 4.33
+smtp_banner string* + main
+smtp_check_spool_space boolean true main 2.10
+smtp_connect_backlog integer 5 main
+smtp_enforce_sync boolean true main 4.00
+smtp_etrn_command string* unset main 1.92
+smtp_etrn_serialize boolean true main 1.89
+smtp_load_reserve fixed-point unset main
+smtp_max_synprot_errors integer 3 main 4.30
+smtp_max_unknown_commands integer 3 main 4.14
+smtp_ratelimit_hosts host list unset main 4.00
+smtp_ratelimit_mail string unset main 4.00
+smtp_ratelimit_rcpt string unset main 4.00
+smtp_receive_timeout time 5m main
+smtp_reserve_hosts host list unset main
+smtp_return_error_details boolean false main 4.11
+socket string* unset lmtp 4.11
+split_spool_directory boolean false main 1.70
+spool_directory string ++ main
+srv_fail_domains domain list unset dnslookup 4.43
+strip_excess_angle_brackets boolean false main
+strip_trailing_dot boolean false main
+subject string* unset autoreply
+syntax_errors_text string* unset redirect 4.00
+syntax_errors_to string unset redirect 4.00
+syslog_duplication boolean true main 4.21
+syslog_facility string unset main 4.20
+syslog_processname string "exim" main 4.20
+syslog_timestamp boolean true main 4.00
+system_filter string unset main 4.00 replacing message_filter
+system_filter_directory_transport string unset main 4.00 replacing message_filter
+system_filter_file_transport string unset main 4.00 replacing message_filter
+system_filter_group string unset main 4.00 replacing message_filter
+system_filter_pipe_transport string unset main 4.00 replacing message_filter
+system_filter_reply_transport string unset main 4.00 replacing message_filter
+system_filter_user string unset main 4.00 replacing message_filter
+tcp_nodelay boolean true main 4.23
+ true smtp 4.23
+temp_errors string list + pipe 1.95
+text string* unset autoreply
+timeout time 5m lmtp 3.20
+ 1h pipe
+ 1h queryprogram 4.00
+ 5s iplookup 4.00
+timeout_frozen_after time 0s main 3.20
+timezone string + main 3.15
+tls_advertise_hosts host list * main 3.20
+tls_certificate string* unset main 3.20
+ unset smtp 3.20
+tls_dhparam string* unset main 3.20
+tls_on_connect_ports string unset main 4.43
+tls_privatekey string* unset main 3.20
+ unset smtp 3.20
+tls_remember_emstp boolean false main 4.21
+tls_require_ciphers string* unset smtp 4.00 replaces tls_verify_ciphers
+ string* unset main 4.33
+tls_tempfail_tryclear boolean true smtp 4.05
+tls_try_verify_hosts host list unset main 4.00
+tls_verify_certificates string* unset main 3.20
+ unset smtp 3.20
+tls_verify_hosts host list unset main 3.20
+to string* unset autoreply
+translate_ip_address string unset routers 4.00
+transport string* unset routers 4.00
+transport_current_directory string unset routers 4.00
+transport_home_directory string unset routers 4.00
+transport_filter string unset transports
+transport_filter_timeout time 5m transports 4.30
+trusted_groups string list unset main
+trusted_users string list unset main
+umask octal-integer 022 pipe
+unknown_login string unset main
+unknown_username string unset main
+unseen boolean false routers 4.00
+untrusted_set_sender boolean false main 3.20
+use_bsmtp boolean false appendfile 4.00
+ false pipe 4.00
+use_crlf boolean false appendfile 1.89
+ false pipe 1.89
+use_fcntl_lock boolean + appendfile 1.70
+use_flock_lock boolean + appendfile 4.11
+use_lockfile boolean + appendfile
+use_mbx_lock boolean + appendfile 2.10
+use_shell boolean false pipe 1.70
+user string + routers 4.00
+ unset transports 4.00 replaces individual options
+uucp_from_pattern string + main 1.75
+uucp_from_sender string* "$1" main 1.75
+verify boolean true routers 4.00
+verify_only boolean false routers 4.00
+verify_recipient boolean true routers 4.00
+verify_sender boolean true routers 4.00
+warn_message_file string unset main 4.00
+widen_domains string list unset dnslookup 4.00
+write_rejectlog boolean true main 4.31
+
+
+
+2. COMMAND LINE OPTIONS
+-----------------------
+
+The table below contains a complete list of all Exim's command line options.
+Those marked with # are available only to trusted users, those marked with +
+are available only to admin users, and those marked with * exist only to
+provide compatibility with Sendmail.
+
+-- Terminate options
+--help Give a little help (not a lot)
+-B * Ignored
+-bd + Start daemon
+-bdf + Start daemon and run it in the foreground
+-be Test string expansion
+-bF Test system filter file
+-bf Test user filter file
+-bfd Set domain for filter testing
+-bfl Set local part for filter testing
+-bfp Set local part prefix for filter testing
+-bfs Set local part suffix for filter testing
+-bh Test incoming SMTP call, omitting callouts
+-bhc Test incoming SMTP call, with callouts
+-bi * Run <command>bi_command</command>
+-bm Accept message on standard input
+-bnq Don't qualify addresses in locally submitted messages
+-bP Show configuration option settings
+-bp + List the queue
+-bpa + ... with generated addresses as well
+-bpc + ... but just show a count of messages
+-bpr + ... do not sort
+-bpra + ... with generated addresses, unsorted
+-bpru + ... only undelivered addresses, unsorted
+-bpu + ... only undelivered addresses
+-brt Test retry rules
+-brw Test rewriting rules
+-bS Read batch SMTP on standard input
+-bs Run SMTP on standard input and output
+-bt Test address directing and routing
+-bV Verify version number
+-bv Test recipient address verification
+-bvs Test sender address verification
+-C + Use alternate configuration file
+-D + Define macro for configuration file
+-d Turn on debugging output
+-dropcr Remove CR character in input: became a no-op in 4.21
+-E Internal use only
+-ex * Synonym for -oex (for several different x)
+-F Set calling user name
+-f # Set calling user address
+-G * Ignored
+-h * Ignored
+-i Dot does not terminate message
+-M + Force deliver specific message
+-Mar + Add recipient to message
+-MC Internal use only
+-MCA Internal use only
+-MCP Internal use only
+-MCQ Internal use only
+-MCS Internal use only
+-MCT Internal use only
+-Mc + Deliver specific message
+-Mes + Edit message sender
+-Mf + Freeze message(s)
+-Mg + Give up (bounce) message(s)
+-Mmad + Mark all recipients delivered
+-Mmd + Mark one recipient delivered
+-Mrm + Remove message(s) (no bounce)
+-Mt + Thaw message(s)
+-Mvb + View message body
+-Mvh + View message header
+-Mvl + View message log
+-m * Ignored
+-N + Deliver without transporting
+-n * Ignored
+-O * Ignored
+-oA * Supply argument for <option>-bi</option>
+-oB Set max messages down one connection
+-odb Background delivery
+-odf Foreground delivery
+-odi Foreground delivery
+-odq Queue message; do not deliver
+-odqs ... do not do SMTP deliveries
+-oee Error sent by mail; zero return code
+-oem Error sent by mail; non-zero return code
+-oep Error written to standard error stream
+-oeq * Error written to standard error stream
+-oew * Error sent by mail; non-zero return code
+-oi Dot does not terminate message
+-oitrue * Dot does not terminate message
+-oMa # Supply host address
+-oMaa # Supply authenticator name
+-oMai # Supply authenticated id
+-oMas # Supply authenticated sender
+-oMi # Supply interface address
+-oMr # Supply protocol name
+-oMs # Supply host name
+-oMt # Supply ident string
+-om * Ignored
+-oo * Ignored
+-oP * Specify path for daemon's pid file
+-or Timeout non-SMTP messages
+-os Timeout for SMTP messages
+-ov * Verbose; same as -v
+-oX Alternative port for daemon
+-pd Delay Perl interpreter start
+-ps Do not delay Perl interpreter start
+-p<r>:<s> * Same as -oMr <r> -oMs <s>
+-q + Run the queue )
+-qf + ... force delivery ) Other combinations are
+-qff + ... and include frozen messages ) possible. The syntax is
+-qi + ... initial deliveries only )
+-ql + ... local deliveries only ) -q[q][f][f][i|l][time]
+-qq + Two-stage queue run )
+-qR * Same as -R
+-qS * Same as -S
+-R Select by recipient in queue run
+-Rf ... with forcing
+-Rff ... and frozen messages
+-Rr ... using regular expression
+-Rrf ... with forcing
+-Rrff ... and frozen messages
+-r * Synonym for -f
+-S Select by sender in queue run
+-Sf ... with forcing
+-Sff ... and frozen messages
+-Sr ... using regular expression
+-Srf ... with forcing
+-Srff ... and frozen messages
+-Tqt * Used by Exim test suite; not recognized in normal use
+-t Take recipients from header lines
+-ti * Same as -t -i
+-tls-on-connect Do TLS on startup (for legacy clients)
+-U * Ignored
+-v Verbose - shows SMTP dialogue and other delivery info
+-x Ignored (AIX compatibility)
+
+
+3. BUILD TIME OPTIONS FOR EXIM
+------------------------------
+
+The table below contains a complete list of options that can be set in
+Local/Makefile when building Exim. More information about individual options
+can be found in src/EDITME and OS/Makefile-Default.
+
+The second column below gives the type of option:
+
+ . `system' means the option is concerned with the operating system;
+
+ . `driver' means the option selects a driver to be included in the binary;
+
+ . `lookup' means the option selects a lookuptype to be included in the binary;
+
+ . `mandatory' means the option is required to be supplied;
+
+ . `recommended' means the option is recommended to be supplied;
+
+ . `optional' means what it says;
+
+Those marked with * are specialized and are unlikely to be required in most
+installations. Those that are marked with ** are commonly set in OS-specific
+Makefiles. If you use any of these in your Local/Makefile, you may need to
+reproduce some of the OS-specific settings. For example, in the Makefile for
+Solaris (which is actually called OS/Makefile-SunOS5), there is
+
+ LIBS=-lsocket -lnsl -lkstat
+
+If you use LIBS to add extra libraries, you must also include the OS ones in
+your setting. It is better, in this particular case, to use EXTRALIBS, which is
+empty by default, and is provided for just this reason. Of course, if you do
+actually want to modify a setting from the OS-specific file, there is nothing
+to stop you overriding it in your Local/Makefile.
+
+Option Type Description
+------------------------------------------------------------------------------
+
+ALT_CONFIG_PREFIX optional restricts location of -C files
+ALT_CONFIG_ROOT_ONLY optional* privileged -C needs root (not exim)
+APPENDFILE_MODE optional*
+APPENDFILE_DIRECTORY_MODE optional*
+APPENDFILE_LOCKFILE_MODE optional*
+AR system command to build a library
+AUTH_CRAM_MD5 driver include cram_md5 authenticator
+AUTH_PLAINTEXT driver include plaintext authenticator
+AUTH_SPA driver include SPA (NTLM) authenticator
+BASENAME_COMMAND system** path to basename
+BASE_62=62 optional* not normally changed for Unix
+BIN_DIRECTORY mandatory Exim binary directory
+CC system** C compiler
+CFLAGS system** flags for C compiler
+CHGRP_COMMAND system** path to chgrp
+CHOWN_COMMAND system** path to chown
+COMPRESS_COMMAND system path to a compress command
+COMPRESS_SUFFIX system suffix added to compressed files
+CONFIGURE_FILE mandatory Exim runtime configuration file
+CONFIGURE_FILE_USE_EUID optional*
+CONFIGURE_FILE_USE_NODE optional*
+CONFIGURE_OWNER optional* alternate owner for configuration file
+CYRUS_PWCHECK_SOCKET optional socket for pwcheck daemon
+DBMLIB optional** location of DBM library
+DB_DIRECTORY_MODE optional* mode for hints directory
+DB_LOCKFILE_MODE optional* mode for hints lock files
+DB_LOCK_TIMEOUT optional* timeout for hints lock files
+DB_MODE optional* mode for hints files
+DEFAULT_CRYPT optional use crypt16() as default
+DELIVER_IN_BUFFER_SIZE optional*
+DELIVER_OUT_BUFFER_SIZE optional*
+DISABLE_D_OPTION optional disables -D option
+ERRNO_QUOTA optional* error code for system quota failures
+EXICYCLOG_MAX optional number of old log files to keep
+EXIMDB_DIRECTORY_MODE optional* for hints database directory
+EXIMDB_LOCKFILE_MODE optional* for hints lock files
+EXIMDB_MODE optional* mode for hints files
+EXIMON_TEXTPOP system**
+EXIM_CHMOD optional*
+EXIM_GROUP mandatory group to use for Exim
+EXIM_MONITOR optional set to eximon.bin to compile
+EXIM_PERL optional
+EXIM_USER mandatory user to use for Exim
+EXIWHAT_EGREP_ARG system** to find Exim processes from ps
+EXIWHAT_KILL_SIGNAL system** -SIGUSER1 or numerical equivalent
+EXIWHAT_MULTIKILL_CMD system**
+EXIWHAT_MULTIKILL_ARG system**
+EXIWHAT_PS_ARG system** to list all processes
+EXIWHAT_PS_CMD system** path to ps command
+EXTRALIBS system additional libraries
+EXTRALIBS_EXIM system additional libraries for Exim only
+EXTRALIBS_EXIMON system additional libraries for the monitor
+FIXED_NEVER_USERS optional can't override at runtime
+HAVE_ICONV system the iconv() function is available
+HAVE_IPV6 system include IPv6 support
+HEADERS_CHARSET optional charset for decoded header lines
+HEADER_ADD_BUFFER_SIZE optional* buffer for header_add()
+HEADER_MAXSIZE optional* max memory for message header
+HOSTNAME_COMMAND system** path to hostname command
+INCLUDE system path to include files
+INFO_DIRECTORY optional directory for Info documentation
+INPUT_DIRECTORY_MODE optional mode for input directory
+IPV6_INCLUDE system additional includes for IPv6
+IPV6_LIBS system additional libraries for IPv6
+LDAP_LIB_TYPE optional type of LDAP library
+LFLAGS system** link editor flags
+LIBIDENTCFLAGS system C flags when compiling libident
+LIBIDENTNAME system name for libident library
+LIBRESOLV system** library for DNS resolver
+LIBS system** additional libraries
+LIBS_EXIM system** additional libraries for Exim ony
+LIBS_EXIMON system** additional libraries for monitor
+LOCAL_SCAN_SOURCE optional location of local_scan() source
+LOG_DIRECTORY_MODE optional mode for log directory
+LOG_FILE_PATH optional path to log files
+LOG_MODE optional mode for log files
+LOOKUP_CDB lookup include cdb lookup
+LOOKUP_DBM lookup include dbm lookup
+LOOKUP_DNSDB lookup include dnsdb lookup
+LOOKUP_DSEARCH lookup include dsearch lookup
+LOOKUP_INCLUDE lookup include files for lookups
+LOOKUP_LDAP lookup include ldap lookup
+LOOKUP_LIBS lookup include libraries for lookups
+LOOKUP_LSEARCH lookup include all lsearch lookups
+LOOKUP_MYSQL lookup include mysql lookup
+LOOKUP_NIS lookup include nis lookup
+LOOKUP_NISPLUS lookup include nisplus lookup
+LOOKUP_ORACLE lookup include oracle lookup
+LOOKUP_PGSQL lookup include pgsql lookup
+LOOKUP_TESTDB lookup*
+LOOKUP_WHOSON lookup include whoson lookup
+MAKE_SHELL optional* shell to use for make
+MAX_FILTER_SIZE optional* max file size for filter files
+MAX_INCLUDE_SIZE optional* max file size for :include: files
+MAX_LOCALHOST_NUMBER=256 optional* for when localhost_number is set
+MAX_NAMED_LIST optional* max named lists of a given type
+MAX_INTERFACES system maximum network interfaces
+MSGLOG_DIRECTORY_MODE optional* mode for message log directory
+MV_COMMAND system path to mv command
+NO_SYMLINK optional install doesn't make 'exim" symlink
+PCRE_CFLAGS system compile flags for PCRE library
+PERL_CC system* compiler for Perl interface code
+PERL_CCOPTS system* flags for same
+PERL_COMMAND system path to Perl
+PERL_LIBS system* library for compiling Perl interface
+PID_FILE_PATH optional path to daemon's pid file
+RADIUS_CONFIG_FILE optional path to Radius config file
+RADIUS_LIB_TYPE optional type of RADIUS library
+RANLIB system** path to ranlib command
+RM_COMMAND system path to rm command
+ROUTER_ACCEPT driver include accept router
+ROUTER_DNSLOOKUP driver include dnslookup router
+ROUTER_MANUALROUTE driver include manualroute router
+ROUTER_IPLITERAL driver include ipliteral router
+ROUTER_IPLOOKUP driver include iplookup router
+ROUTER_REDIRECT driver include redirect router
+ROUTER_QUERYPROGRAM driver include queryprogram router
+SPOOL_DIRECTORY recommended path to spool directory
+SPOOL_DIRECTORY_MODE optional mode of spool directory
+SPOOL_MODE optional mode of spool files
+STRING_SPRINTF_BUFFER_SIZE optional* buffer for string_sprintf()
+STRIP_COMMAND optional* can be used to strp binaries
+SUPPORT_A6 optional* support A6 DNS records
+SUPPORT_CRYPTEQ optional support crypteq (if no auths)
+SUPPORT_MAILDIR optional support for maildir delivery
+SUPPORT_MAILSTORE optional support for mailstore delivery
+SUPPORT_MBX optional support for MBX delivery
+SUPPORT_MOVE_FROZEN_MESSAGES optional* support for frozen message moving
+SUPPORT_PAM optional support for PAM authentication
+SUPPORT_TLS optional support for TLS encryption over SMTP
+SUPPORT_TRANSLATE_IP_ADDRESS optional* support for address translation
+SYSLOG_LOG_PID optional add pid to syslog lines
+SYSLOG_LONG_LINES optional do not split long syslog lines
+SYSTEM_ALIASES_FILE optional defaults to /etc/aliases
+TIMEZONE_DEFAULT optional default for timezone option
+TLS_INCLUDE optional path to include files for TLS
+TLS_LIBS optional additional libraries for TLS
+TMPDIR system value for TMPDIR environment variable
+TRANSPORT_APPENDFILE driver include appendfile transport
+TRANSPORT_AUTOREPLY driver include autoreply transport
+TRANSPORT_LMTP driver include lmtp transport
+TRANSPORT_PIPE driver include pipe transport
+TRANSPORT_SMTP driver include smtp transport
+USE_DB system** use native DB interface
+USE_GNUTLS optional use GnuTLS instead of OpenSSL
+USE_READLINE optional try to load libreadline for -be
+USE_TCP_WRAPPERS system link with tcpwrappers
+USE_TDB optional use the tdb DB interface
+X11 system** X11 base directory
+X11_LD_LIB system** X11 link library
+XINCLUDE system** X11 include directory
+XLFLAGS system** X11 link time flags
+ZCAT_COMMAND system path to zcat command
+
+
+4. BUILD TIME OPTIONS FOR EXIMON
+--------------------------------
+
+The table below contains a complete list of options that can be set in
+Local/eximon.conf when building the Exim monitor. Where the default is shown as
+** it means that the text string is too long to fit in the table and is instead
+given below. A blank default means that there is no default value.
+
+ACTION_OUTPUT=no show output for every action
+ACTION_QUEUE_UPDATE=yes update queue display after actions
+BODY_MAX=20000 maximum body display
+DOMAIN= domain to strip from window title
+LOG_BUFFER=20K buffer for log tail
+LOG_DEPTH=300 depth of log subwindow
+LOG_FONT=** font for log display
+LOG_STRIPCHARTS=** patterns for stripcharts
+LOG_WIDTH=950 width of log subwindow
+MENU_EVENT='Shift<Btn1Down>' keypress for menu
+MIN_HEIGHT=162 minimum window height
+MIN_WIDTH=103 minimum window width
+QUALIFY_DOMAIN= local domain to strip from addresses
+QUEUE_DEPTH=200 depth of queue subwindow
+QUEUE_FONT=$LOG_FONT font for queue display
+QUEUE_INTERVAL=300 queue refresh interval
+QUEUE_MAX_ADDRESSES=10 max addresses to show in queue
+QUEUE_STRIPCHART_NAME=queue name for queue stripchart
+QUEUE_WIDTH=950 width of queue subwindow
+SIZE_STRIPCHART= request partition size stripchart
+SIZE_STRIPCHART_NAME=space name for size stripchart
+START_SMALL=no if yes, start with small window
+STRIPCHART_INTERVAL=60 stripchart refresh interval
+TEXT_DEPTH=200 depth of text windows
+WINDOW_TITLE="${hostname} eximon" window title
+
+The default for LOG_FONT is
+
+ LOG_FONT=-misc-fixed-medium-r-normal-*-14-140-*-*-*-*-iso8859-1
+
+and the default for LOG_STRIPCHARTS is
+
+ LOG_STRIPCHARTS='/ <= /in/
+ / => /out/
+ / => .+ R=local/local/
+ / => .+ T=[^ ]*smtp/smtp/'
+
+That is, there are four stripcharts, named in, out, local, and smtp. The first
+counts message arrivals, the second counts all deliveries, the third counts
+deliveries where the router's name starts with "local", and the fourth counts
+deliveries where the transport name contains "smtp".
+
+**** End of OptionLists ****
diff --git a/doc/doc-txt/README b/doc/doc-txt/README
new file mode 100644
index 000000000..996f89274
--- /dev/null
+++ b/doc/doc-txt/README
@@ -0,0 +1,84 @@
+$Cambridge: exim/doc/doc-txt/README,v 1.1 2004/10/07 15:04:35 ph10 Exp $
+
+Exim Documentation
+------------------
+
+This directory should contain the following files:
+
+ ChangeLog most recent log of all changes to Exim
+ NewStuff features that haven't made it to the manual yet,
+ and/or a list of newly-added functionality
+ OptionLists.txt lists of all Exim's options
+ README this document
+ README.SIEVE notes on the Sieve support
+ Exim3.upgrade information about upgrading from release 2.12 to 3.00
+ Exim4.upgrade information about upgrading from release 3.33 to 4.00
+ dbm.discuss.txt discussion of DBM libraries
+ filter.txt specification of filter file contents
+ pcre.txt specification of PCRE regular expression library
+ pcretest.txt specification of the PCRE test program
+ spec.txt main specification of Exim
+
+The .txt files are straight ASCII text; spec.txt and filter.txt have change
+bars on the right for changes from the previous editions.
+
+
+PostScript
+----------
+
+The Exim specifications are also available in PostScript. This is not included
+in the main distribution because not everyone wants it and it doesn't diff
+well, causing patches to be very much larger than necessary.
+
+Wherever you got this distribution from should also have carried another file
+called exim-postscript-<version>.tar.gz which contains the PostScript
+documentation. When de-tarred it creates a directory called
+exim-postscript-<version> into which it places the files doc/filter.ps and
+doc/spec.ps.
+
+
+HTML
+----
+
+A special conversion from the original sources via Texinfo into HTML is done to
+create the online documentation at http://www.exim.org. This set of files is
+also available for installation on other servers. Wherever you got this
+distribution from should also have carried another file called
+exim-html-<version>.tar.gz which contains the HTML documentation. When
+de-tarred it creates a directory called exim-html-<version> into which it
+places a directory called doc/html containing the set of HTML files. The kick
+off points are:
+
+ html/spec.html - specification (framed)
+ html/filter_toc.html - filter docs
+
+
+PDF
+---
+
+The Exim specifications are available in Portable Document Format. Wherever you
+got this distribution from should also have carried another file called
+exim-pdf-<version>.tar.gz which contains the PDF documentation. When de-tarred
+it creates a directory called exim-pdf-<version> into which it places the files
+doc/filter.pdf and doc/spec.pdf.
+
+
+TeXinfo
+-------
+
+A version of the documentation that has been converted to TeXinfo format is
+available in the distribution file exim-texinfo-<version>.gz. When de-tarred it
+creates a directory called exim-texinfo-<version> into which it places the
+files doc/filter.texinfo and doc/spec.texinfo.
+
+The conversion process is automatic (a Perl script) so the result isn't as nice
+as hand-maintained TeXinfo files would be, and some information is lost;
+for example, TeXinfo does not support the use of change bars.
+
+There is cgi-bin perl script called info2www which converts info files to
+html on the fly so that the same info files can be read using the "info"
+program, or from emacs, or from your favourite browser. This is available from
+
+http://www.ericsson.nl/info2www/info2www.html
+
+-- End --
diff --git a/doc/doc-txt/README.SIEVE b/doc/doc-txt/README.SIEVE
new file mode 100644
index 000000000..4d04851e1
--- /dev/null
+++ b/doc/doc-txt/README.SIEVE
@@ -0,0 +1,433 @@
+$Cambridge: exim/doc/doc-txt/README.SIEVE,v 1.1 2004/10/07 15:04:35 ph10 Exp $
+
+ Notes on the Sieve implementation for Exim
+
+Exim Filter Versus Sieve Filter
+
+Exim supports two incompatible filters: The traditional Exim filter and
+the Sieve filter. Since Sieve is a extensible language, it is important
+to understand "Sieve" in this context as "the specific implementation
+of Sieve for Exim".
+
+The Exim filter contains more features, such as variable expansion, and
+better integration with the host environment, like external processes
+and pipes.
+
+Sieve is a standard for interoperable filters, defined in RFC 3028,
+with multiple implementations around. If interoperability is important,
+then there is no way around it.
+
+
+Exim Implementation
+
+The Exim Sieve implementation offers the core as defined by RFC 3028, the
+"envelope" (RFC 3028), the "fileinto" (RFC 3028), the "copy" (RFC 3894)
+and the "vacation" (draft-showalter-sieve-vacation-05.txt) extension,
+the "i;ascii-numeric" comparator, but not the "reject" extension.
+Exim does not support MDMs, so adding it just to the sieve filter makes
+little sense.
+
+The Sieve filter is integrated in Exim and works very similar to the
+Exim filter: Sieve scripts are recognized by the first line containing
+"# sieve filter". When using "keep" or "fileinto" to save a mail into a
+folder, the resulting string is available as the variable $address_file
+in the transport that stores it. A suitable transport could be:
+
+localuser:
+ driver = appendfile
+ file = ${if eq{$address_file}{inbox} \
+ {/var/mail/$local_part} \
+ {${if eq{${substr_0_1:$address_file}}{/} \
+ {$address_file} \
+ {$home/$address_file} \
+ }} \
+ }
+ delivery_date_add
+ envelope_to_add
+ return_path_add
+ mode = 0600
+
+Absolute files are stored where specified, relative files are stored
+relative to $home and "inbox" goes to the standard mailbox location.
+
+To enable "vacation", set sieve_vacation_directory for the router to
+the directory where vacation databases are held (don't put anything
+else in that directory) and point reply_transport to an autoreply
+transport.
+
+
+RFC Compliance
+
+Exim requires the first line to be "# sieve filter". Of course the RFC
+does not enforce that line. Don't expect examples to work without adding
+it, though.
+
+RFC 3028 requires using CRLF to terminate the end of 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 \n as newline character, this implementation
+does, too. You can change this by defining the macro RFC_EOL at compile
+time to enforce CRLF being used.
+
+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.
+
+Sieve scripts can not contain NUL characters in strings, but mail
+headers could contain MIME encoded NUL characters, which could never
+be matched by Sieve scripts using exact comparisons. For that reason,
+this implementation extends the Sieve quoted string syntax with \0
+to describe a NUL character, violating \0 being the same as 0 in
+RFC 3028. Even without using \0, the following tests are all true in
+this implementation. Implementations that use C-style strings will only
+evaulate the first test as true.
+
+Subject: =?iso-8859-1?q?abc=00def
+
+header :contains "Subject" ["abc"]
+header :contains "Subject" ["def"]
+header :matches "Subject" ["abc?def"]
+
+Note that by considering Sieve to be a 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.
+The above example shows why. Good code should still be able to deal
+with it.
+
+RFC 3028 states that if an implementation fails to convert a character
+set to UTF-8, two strings can not be equal if one contains octects greater
+than 127. Assuming that all unknown character sets are one-byte character
+sets with the lower 128 octects being US-ASCII is not sound, so this
+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 specifiy the
+syntax of folders apart from keep being equivalent to fileinto "INBOX".
+This implementation uses "inbox" instead.
+
+Sieve script errors currently cause that messages are 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
+are filed into "inbox" due to an error in the filter.
+
+
+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, e.g. 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.
+
+
+Header Test With Invalid MIME Encoding In Header
+
+Some MUAs process invalid base64 encoded data, generating junk.
+Others ignore junk after seeing an equal sign in base64 encoded data.
+RFC 2047 does not specify how to react in this case, other than stating
+that a client must not forbid to process a message for that reason.
+RFC 2045 specifies that invalid data should be ignored (appearantly
+looking at end of line characters). It also specifies that invalid data
+may lead to rejecting messages containing them (and there it appears to
+talk about true encoding violations), which is a clear contradiction to
+ignoring them.
+
+RFC 3028 does not specify how to process incorrect MIME words.
+This implementation treats them literally, as it does if the word is
+correct, but its character set can not be converted to UTF-8.
+
+
+Address Test For Multiple Addresses Per Header
+
+A header may contain multiple addresses. RFC 3028 does not explicitly
+specify how to deal with them, but since the "address" test checks if
+anything matches anything else, matching one address suffices to
+satify the condition. That makes it impossible to test if a header
+contains a certain set of addresses and no more, but it is more logical
+than letting the test fail if the header contains an additional address
+besides the one the test checks for.
+
+
+Semantics Of Keep
+
+The keep command is equivalent to fileinto "inbox": It saves the
+message and resets the implicit keep flag. It does not set the
+implicit keep flag; there is no command to set it once it has
+been reset.
+
+
+Semantics of Fileinto
+
+RFC 3028 does not specify if "fileinto" tries to create a mail folder,
+in case it does not exist. This implementation allows to configure
+that aspect using the appendfile transport options "create_directory",
+"create_file" and "file_must_exist". See the appendfile transport in
+the Exim specification for details.
+
+
+Semantics of Redirect
+
+Sieve scripts are supposed to be interoperable between servers, so this
+implementation does not allow redirecting mail to unqualified addresses,
+because the domain would depend on the used system and on systems with
+virtual mail domains it is probably not what the user expects it to be.
+
+
+String Arguments
+
+There has been confusion if the string arguments to "require" are to be
+matched case-sensitive 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.
+
+
+Number Units
+
+There is a mistake in RFC 3028: The suffix G denotes gibi-, not tebibyte.
+The mistake os obvious, because RFC 3028 specifies G to denote 2^30
+(which is gibi, not tebi), and that's what this implementation uses as
+scaling factor for the suffix G.
+
+
+Sieve Syntax and Semantics
+
+RFC 3028 confuses syntax and semantics sometimes. It uses a generic
+grammar as syntax for actions and tests and performs many checks during
+semantic analysis. Syntax is specified as grammar rule, semantics
+with natural language, despire the latter often talking about syntax.
+The intention was to provide a framework for the syntax that describes
+current commands as well as future extensions, and describing commands
+by semantics. Since the semantic analysis is not specified by formal
+rules, it is easy to get that phase wrong, as demonstrated by the mistake
+in RFC 3028 to forbid "elsif" being followed by "elsif" (which is allowed
+in Sieve, it's just not specified correctly).
+
+RFC 3028 does not define if semantic checks are strict (always treat
+unknown extensions as errors) or lazy (treat unknown extensions as error,
+if they are executed), and since it employs a very generic grammar,
+it is not unreasonable for an implementation using a parser for the
+generic grammar to indeed process scripts that contain unknown commands
+in dead code. It is just required to treat disabled but known extensions
+the same as unknown extensions.
+
+The following suggestion for section 8.2 gives two grammars, one for
+the framework, and one for specific commands, thus removing most of the
+semantic analysis. Since the parser can not parse unsupported extensions,
+the result is strict error checking. As required in section 2.10.5, known
+but not enabled extensions must behave the same as unknown extensions,
+so those also result strictly in errors (though at the thin semantic
+layer), even if they can be parsed fine.
+
+8.2. Grammar
+
+The atoms of the grammar are lexical tokens. White space or comments may
+appear anywhere between lexical tokens, they are not part of the grammar.
+The grammar is specified in ABNF with two extensions to describe tagged
+arguments that can be reordered and grammar extensions: { } denotes a
+sequence of symbols that may appear in any order. Example:
+
+ start = { a b c }
+
+is equivalent to:
+
+ start = ( a b c ) / ( a c b ) / ( b a c ) / ( b c a ) / ( c a b ) / ( c b a )
+
+The symbol =) is used to append to a rule:
+
+ start = a
+ start =) b
+
+is equivalent to
+
+ start = a b
+
+All Sieve commands, including extensions, MUST be words of the following
+generic grammar with the start symbol "start". They SHOULD be specified
+using a specific grammar, though.
+
+ argument = string-list / number / tag
+ arguments = *argument [test / test-list]
+ block = "{" commands "}"
+ commands = *command
+ string = quoted-string / multi-line
+ string-list = "[" string *("," string) "]" / string
+ test = identifier arguments
+ test-list = "(" test *("," test) ")"
+ command = identifier arguments ( ";" / block )
+ start = command
+
+The basic Sieve commands are specified using the following grammar, which
+language is a subset of the generic grammar above. The start symbol is
+"start".
+
+ address-part = ":localpart" / ":domain" / ":all"
+ comparator = ":comparator" string
+ match-type = ":is" / ":contains" / ":matches"
+ string = quoted-string / multi-line
+ string-list = "[" string *("," string) "]" / string
+ address-test = "address" { [address-part] [comparator] [match-type] }
+ string-list string-list
+ test-list = "(" test *("," test) ")"
+ allof-test = "allof" test-list
+ anyof-test = "anyof" test-list
+ exists-test = "exists" string-list
+ false-test = "false"
+ true=test = "true"
+ header-test = "header" { [comparator] [match-type] }
+ string-list string-list
+ not-test = "not" test
+ relop = ":over" / ":under"
+ size-test = "size" relop number
+ block = "{" commands "}"
+ if-command = "if" test block *( "elsif" test block ) [ "else" block ]
+ stop-command = "stop" { stop-options } ";"
+ stop-options =
+ keep-command = "keep" { keep-options } ";"
+ keep-options =
+ discard-command = "discard" { discard-options } ";"
+ discard-options =
+ redirect-command = "redirect" { redirect-options } string ";"
+ redirect-options =
+ require-command = "require" { require-options } string-list ";"
+ require-options =
+ test = address-test / allof-test / anyof-test / exists-test
+ / false-test / true-test / header-test / not-test
+ / size-test
+ command = if-command / stop-command / keep-command
+ / discard-command / redirect-command
+ commands = *command
+ start = *require-command commands
+
+The extensions "envelope" and "fileinto" are specified using the following
+grammar extension.
+
+ envelope-test = "envelope" { [comparator] [address-part] [match-type] }
+ string-list string-list
+ test =/ envelope-test
+
+ fileinto-command = "fileinto" { fileinto-options } string ";"
+ fileinto-options =
+ command =/ fileinto-command
+
+The extension "copy" is specified as:
+
+ fileinto-options =) ":copy"
+ redirect-options =) ":copy"
+
+
+The i;ascii-numeric Comparator
+
+RFC 2244 describes this comparator and specifies that non-numeric strings
+are considered equal with an ordinal value higher than any numeric string.
+Although not stated explicitly, this includes the empty string. A range
+of at least 2^31 is required. This implementation does not limit the
+range, because it does not convert numbers to binary representation
+before comparing them.
+
+
+The vacation extension
+
+The extension "vacation" is specified using the following grammar
+extension.
+
+ vacation-command = "vacation" { vacation-options } <reason: string>
+ vacation-options = [":days" number]
+ [":addresses" string-list]
+ [":subject" string]
+ [":mime"]
+ command =/ vacation-command
+
+
+Semantics Of ":mime"
+
+RFC 3028 does not specify how strings using MIME parts are used to compose
+messages. The vacation draft refers to RFC 3028 and does not specify it
+either. As a result, different implementations generate different mails.
+The Exim Sieve implementation splits the reason into header and body.
+It adds the header to the mail header and uses the body as mail body.
+Be aware, that other imlementations compose a multipart structure with
+the reason as only part. Both conform to the specification (or lack
+thereof).
+
+
+Semantics Of Not Using ":mime"
+
+Sieve scripts are written in UTF-8, so is the reason string in this
+case. This implementation adds MIME headers to indicate that. This
+is not required by the vacation draft, which does not specify how
+the UTF-8 reason is processed to compose the resulting message.
+
+
+Envelope Sender
+
+The vacation draft does not specify the envelope sender. This
+implementation uses the empty envelope sender to prevent mail loops.
+
+
+Default Subject
+
+The draft specifies that the default message subject is "Re: "
+plus the old subject, stripped by any leading "Re: " strings.
+This string is to be taken literally, unlike some software which
+matches a regular expression like "[rR][eE]: *". Using this
+subject is dangerous, because many mailing lists verify addresses
+by sending a secret key in the subject of a message, asking to
+reply to the message for confirmation. Using the default vacation
+subject confirms any subscription request of this kind, allowing
+to subscribe a third party to any mailing list, either to annoy
+the user or to declare spam as legitimate mail by proving to
+use opt-in. The draft specifies to use "Re: " in front of the
+subject, but this implementation uses "Auto: ", as suggested in
+the current draft concerning automatic mail responses.
+
+
+Rate Limiting Responses
+
+The draft says:
+
+ Vacation responses are not just per address, but are per address
+ per vacation command.
+
+This is badly worded, because commands are not enumerated. It meant
+to say:
+
+ Vacation responses are not just per address, but are per address
+ per reason string and per specified subject and ":mime" option.
+
+Existing implementations work that way and it makes more sense, too.
+Including the ":mime" option is mostly for correctness, as the reason
+strings with and without this option are rarely equal.
+
+This implementation hashes the reason, specified subject and ":mime"
+option and uses the hex string representation as filename within the
+"sieve_vacation_directory" to store the recipient addresses for this
+vacation parameter set.
+
+The draft specifies that sites may define a minimum ":days" value than 1.
+This implementation uses 1. The maximum value MUST greater than 7,
+and SHOULD be greater than 30. This implementation uses a maximum of 31.
+
+Vacation recipient address databases older than 31 days are automatically
+removed. Users do not have to remove them manually when modifying their
+scripts. Don't put anything but vacation databases in that directory
+or you risk that it will be removed, too!
+
+
+Global Reply Address Blacklist
+
+The draft requires that each implementation offers a global black list
+of addresses that will never be replied to. Exim offers this as option
+"never_mail" in the autoreply transport.
+
+
+Interaction With Other Sieve Elements
+
+The draft describes the interaction with vacation, discard, keep,
+fileinto and redirect. It MUST describe compatibility with other
+actions, but doesn't. In this implementation, vacation is compatible
+with any other action.
diff --git a/doc/doc-txt/dbm.discuss.txt b/doc/doc-txt/dbm.discuss.txt
new file mode 100644
index 000000000..7517c4b88
--- /dev/null
+++ b/doc/doc-txt/dbm.discuss.txt
@@ -0,0 +1,322 @@
+$Cambridge: exim/doc/doc-txt/dbm.discuss.txt,v 1.1 2004/10/07 15:04:35 ph10 Exp $
+
+DBM Libraries for use with Exim
+-------------------------------
+
+Background
+----------
+
+Exim uses direct-access (so-called "dbm") files for a number of different
+purposes. These are files arranged so that the data they contain is indexed and
+can quickly be looked up by quoting an appropriate key. They are used as
+follows:
+
+1. Exim keeps its "hints" databases in dbm files.
+
+2. The configuration can specify that certain things (e.g. aliases) be looked
+ up in dbm files.
+
+3. The configuration can contain expansion strings that involve lookups in dbm
+ files.
+
+4. The filter commands "mail" and "vacation" have a facility for replying only
+ once to each incoming address. The record of which addresses have already
+ received replies may be kept in a dbm file, depending on the configuration
+ option once_file_size.
+
+The runtime configuration can be set up without specifying 2 or 3, but Exim
+always requires the availability of a dbm library, for 1 (and 4 if configured
+that way).
+
+
+DBM Libraries
+-------------
+
+The original library that provided the dbm facility in Unix was called "dbm".
+This seems to have been superseded quite some time ago by a new version called
+"ndbm" which permits several dbm files to be open at once. Several operating
+systems, including those from Sun, contain ndbm as standard.
+
+A number of alternative libraries also exist, the most common of which seems to
+be Berkeley DB (just called DB hereinafter). Release 1.85 was around for
+some time, and various releases 2.x began to appear towards the end of 1997. In
+November 1999, version 3.0 was released, and the ending of support for 2.7.7,
+the last 2.x release, was announced for November 2000. (Support for 1.85 has
+already ceased.) There were further 3.x releases, but by the end of 2001, the
+current release was 4.0.14.
+
+There are major differences in implementation and interface between the DB 1.x
+and 2.x/3.x/4.x releases, and they are best considered as two independent dbm
+libraries. Changes to the API were made for 3.0 and again for 3.1.
+
+Another DBM library is the GNU library, gdbm, though this does not seem to be
+very widespread.
+
+Yet another dbm library is tdb (Trivial Data Base) which has come out of the
+Samba project. The first releases seem to have been in mid-2000.
+
+Some older Linux releases contain gdbm as standard, while others contain no dbm
+library. More recent releases contain DB 1.85 or 2.x or later, and presumably
+will track the development of the DB library. Some BSD versions of Unix include
+DB 1.85 or later. All of the non-ndbm libraries except tdb contain
+compatibility interfaces so that programs written to call the ndbm functions
+should, in theory, work with them, but there are some potential pitfalls which
+have caught out Exim users in the past.
+
+Exim has been tested with ndbm, gdbm, DB 1.85, DB 2.x, DB 3.1, DB 4.0.14, and
+tdb 1.0.2, in various different modes in some cases, and is believed to work
+with all of them if it and they are properly configured.
+
+I have considered the possibility of calling different dbm libraries for
+different functions from a single Exim binary. However, because all bar one of
+the libraries provide ndbm compatibility interfaces (and therefore the same
+function names) it would require a lot of complicated, error-prone trickery to
+achieve this. Exim therefore uses a single library for all its dbm activities.
+
+However, Exim does also support cdb (Constant Data Base), an efficient file
+arrangement for indexed data that does not change incrementally (for example,
+alias files). This is independent of any dbm library and can be used alongside
+any of them.
+
+
+Locking
+-------
+
+The configuration option EXIMDB_LOCK_TIMEOUT controls how long Exim waits to
+get a lock on a hints database. From version 1.80 onwards, Exim does not
+attempt to take out a lock on an actual database file (this caused problems in
+the past). Instead, it takes out an fcntl() lock on a separate file whose name
+ends in ".lockfile". This ensures that Exim has exclusive access to the
+database before even attempting to open it. Exim creates the lock file the
+first time it needs it. It should never be removed.
+
+
+Main Pitfall
+------------
+
+The OS-specific configuration files that are used to build Exim specify the use
+of Berkeley DB on those systems where it is known to be standard. In the
+absence of any special configuration options, Exim uses the ndbm set of
+functions to control its dbm databases. This should work with any of the dbm
+libraries because those that are not ndbm have compatibility interfaces.
+However, there is one awful pitfall:
+
+Exim #includes a header file called ndbm.h which defines the functions and the
+interface data block; gdbm and DB 1.x provide their own versions of this header
+file, later DB versions do not. If it should happen that the wrong version of
+nbdm.h is seen by Exim, it may compile without error, but fail to operate
+correctly at runtime.
+
+This situation can easily arise when more than one dbm library is installed on
+a single host. For example, if you decide to use DB 1.x on a system where gdbm
+is the standard library, unless you are careful in setting up the include
+directories for Exim, it may see gdbm's ndbm.h file instead of DB's. The
+situation is even worse with later versions of DB, which do not provide an
+ndbm.h file at all.
+
+One way out of this for gdbm and any of the versions of DB is to configure Exim
+to call the DBM library in its native mode instead of via the ndbm
+compatibility interface, thus avoiding the use of ndbm.h. This is done by
+setting the USE_DB configuration option if you are using Berkeley DB, or
+USE_GDBM if you are using gdbm. This is the recommended approach.
+
+
+NDBM
+----
+
+The ndbm library holds its data in two files, with extensions .dir and .pag.
+This makes atomic updating of, for example, alias files, difficult, because
+simple renaming cannot be used without some risk. However, if your system has
+ndbm installed, Exim should compile and run without any problems.
+
+
+GDBM
+----
+
+The gdbm library, when called via the ndbm compatibility interface, makes two
+hard links to a single file, with extensions .dir and .pag. As mentioned above,
+gdbm provides its own version of the ndbm.h header, and you must ensure that
+this is seen by Exim rather than any other version. This is not likely to be a
+problem if gdbm is the only dbm library on your system.
+
+If gdbm is called via the native interface (by setting USE_GDBM in your
+Local/Makefile), it uses a single file, with no extension on the name, and the
+ndbm.h header is not required.
+
+The gdbm library does its own locking of the single file that it uses. From
+version 1.80 onwards, Exim locks on an entirely separate file before accessing
+a hints database, so gdbm's locking should always succeed.
+
+
+Berkeley DB 1.8x
+----------------
+
+1.85 was the most widespread DB 1.x release; there is also a 1.86 bug-fix
+release, but the belief is that the bugs it fixes will not affect Exim.
+However, maintenance for 1.x releases has been phased out.
+
+This dbm library can be called by Exim in one of two ways: via the ndbm
+compatibility interface, or via its own native interface. There are two
+advantages to doing the latter: (1) you don't run the risk of Exim's seeing the
+"wrong" version of the ndbm.h header, as described above, and (2) the
+performace is better. It is therefore recommended that you set USE_DB=yes in an
+appropriate Local/Makefile-xxx file. (If you are compiling for just one OS, it
+can go in Local/Makefile itself.)
+
+When called via the compatibility interface, DB 1.x creates a single file with
+a .db extension. When called via its native interface, no extension is added to
+the file name handed to it.
+
+DB 1.x does not do any locking of its own.
+
+
+Berkeley DB 2.x
+---------------
+
+DB 2.x was released in 1997. It is a major re-implementation and its native
+interface is incompatible with DB 1.x, though a compatibility interface was
+introduced in DB 2.1.0, and there is also an ndbm.h compatibility interface.
+
+Like 1.x, it can be called from Exim via the ndbm compatibility interface or
+via its native interface, and once again setting USE_DB in order to get the
+native interface is recommended. If USE_DB is *not* set, then you will have to
+provide a suitable version of ndbm.h, because one does not come with the DB 2.x
+distribution. A suitable version is:
+
+ /*************************************************
+ * ndbm.h header for DB 2.x *
+ *************************************************/
+
+ /* This header should replace any other version of ndbm.h when Berkeley DB
+ version 2.x is in use via the ndbm compatibility interface. Otherwise, any
+ extant version of ndbm.h may cause programs to misbehave. There doesn't seem
+ to be a version of ndbm.h supplied with DB 2.x, so I made this for myself.
+
+ Philip Hazel 12/Jun/97
+ */
+
+ #define DB_DBM_HSEARCH
+ #include <db.h>
+
+ /* End */
+
+When called via the compatibility interface, DB 2.x creates a single file with
+a .db extension. When called via its native interface, no extension is added to
+the file name handed to it.
+
+DB 2.x does not do any automatic locking of its own; it does have a set of
+functions for various forms of locking, but Exim does not use them.
+
+
+Berkeley DB 3.x
+---------------
+
+DB 3.0 was released in November 1999 and 3.1 in June 2000. The 3.x series is a
+development of the 2.x series and the above comments apply. Exim can
+automatically distinguish between the different versions, so it copes with the
+changes to the API without needing any special configuration.
+
+When Exim creates a DBM file using DB 3.x (e.g. when creating one of its hints
+databases), it specified the "hash" format. However, when it opens a DB 3 file
+for reading only, it specifies "unknown". This means that it can read DB 3
+files in other formats that are created by other programs.
+
+
+Berkeley DB 4.x
+---------------
+
+The 4.x series is a developement of the 2.x and 3.x series, and the above
+comments apply.
+
+
+tdb
+---
+
+tdb 1.0.2 was released in September 2000. Its origin is the database functions
+that are used by the Samba project.
+
+
+
+Testing Exim's dbm handling
+---------------------------
+
+Because there have been problems with dbm file locking in the past, I built
+some testing code for Exim's dbm functions. This is very much a lash-up, but it
+is documented here so that anybody who wants to check that their configuration
+is locking properly can do so. Now that Exim does the locking on an entirely
+separate file, locking problems are much less likely, but this code still
+exists, just in case. Proceed as follows:
+
+. Build Exim in the normal way. This ensures that all the makesfiles etc. get
+ set up.
+
+. From within the build directory, obey "make test_dbfn". This makes a binary
+ file called test_dbfn. If you are experimenting with different configurations
+ you *must* do "make makefile" after changing anything, before obeying "make
+ test_dbfn" again, because the make target for test_dbfn isn't integrated
+ with the making of the makefile.
+
+. Identify a scratch directory where you have write access. Create a sub-
+ directory called "db" in the scratch directory.
+
+. Type the command "test_dbfn <scratch-directory>". This will output some
+ general information such as
+
+ Exim's db functions tester: interface type is db (v2)
+ DBM library: Berkeley DB: Sleepycat Software: DB 2.1.0: (6/13/97)
+ USE_DB is defined
+
+ It then says
+
+ Test the functions
+ >
+
+. At this point you can type commands to open a dbm file and read and write
+ data in it. First type the command "open <name>", e.g. "open junk". The
+ response should look like this
+
+ opened DB file <scratch-directory>/db/junk: flags=102
+ Locked
+ opened 0
+ >
+
+ The tester will have created a dbm file within the db directory of the
+ scratch directory. It will also have created a file with the extension
+ ".lockfile" in the same directory. Unlike Exim itself, it will not create
+ the db directory for itself if it does not exist.
+
+. To test the locking, don't type anything more for the moment. You now need to
+ set up another process running the same test_dbfn command, e.g. from a
+ different logon to the same host. This time, when you attempt to open the
+ file it should fail after a minute with a timeout error because it is
+ already in use.
+
+. If the second process doesn't produce any error message, but gets back to the
+ > prompt, then the locking is not working properly.
+
+. You can check that the second process gets the lock when the first process
+ releases it by exiting from the first process with ^D, q, or quit; or by
+ typing the command "close".
+
+. There are some other commands available that are not related to locking:
+
+ write <key> <data>
+ e.g.
+ write abcde the quick brown fox
+
+ writes a record to the database,
+
+ read <key>
+ delete <key>
+
+ read and delete a record, respectively, and
+
+ scan
+
+ scans the entire database. Note that the database is purely for testing the
+ dbm functions. It is *not* one of Exim's regular databases, and you should
+ not try running this testing program on any of Exim's real database
+ files.
+
+Philip Hazel
+Last update: June 2002
diff --git a/doc/doc-txt/pcrepattern.txt b/doc/doc-txt/pcrepattern.txt
new file mode 100644
index 000000000..1dc800af4
--- /dev/null
+++ b/doc/doc-txt/pcrepattern.txt
@@ -0,0 +1,1413 @@
+This file contains the PCRE man page that describes the regular expressions
+supported by PCRE version 5.0. Note that not all of the features are relevant
+in the context of Exim. In particular, the version of PCRE that is compiled
+with Exim does not include UTF-8 support, there is no mechanism for changing
+the options with which the PCRE functions are called, and features such as
+callout are not accessible.
+-----------------------------------------------------------------------------
+
+PCRE(3) PCRE(3)
+
+
+
+NAME
+ PCRE - Perl-compatible regular expressions
+
+PCRE REGULAR EXPRESSION DETAILS
+
+ The syntax and semantics of the regular expressions supported by PCRE
+ are described below. Regular expressions are also described in the Perl
+ documentation and in a number of books, some of which have copious
+ examples. Jeffrey Friedl's "Mastering Regular Expressions", published
+ by O'Reilly, covers regular expressions in great detail. This descrip-
+ tion of PCRE's regular expressions is intended as reference material.
+
+ The original operation of PCRE was on strings of one-byte characters.
+ However, there is now also support for UTF-8 character strings. To use
+ this, you must build PCRE to include UTF-8 support, and then call
+ pcre_compile() with the PCRE_UTF8 option. How this affects pattern
+ matching is mentioned in several places below. There is also a summary
+ of UTF-8 features in the section on UTF-8 support in the main pcre
+ page.
+
+ A regular expression is a pattern that is matched against a subject
+ string from left to right. Most characters stand for themselves in a
+ pattern, and match the corresponding characters in the subject. As a
+ trivial example, the pattern
+
+ The quick brown fox
+
+ matches a portion of a subject string that is identical to itself. The
+ power of regular expressions comes from the ability to include alterna-
+ tives and repetitions in the pattern. These are encoded in the pattern
+ by the use of metacharacters, which do not stand for themselves but
+ instead are interpreted in some special way.
+
+ There are two different sets of metacharacters: those that are recog-
+ nized anywhere in the pattern except within square brackets, and those
+ that are recognized in square brackets. Outside square brackets, the
+ metacharacters are as follows:
+
+ \ general escape character with several uses
+ ^ assert start of string (or line, in multiline mode)
+ $ assert end of string (or line, in multiline mode)
+ . match any character except newline (by default)
+ [ start character class definition
+ | start of alternative branch
+ ( start subpattern
+ ) end subpattern
+ ? extends the meaning of (
+ also 0 or 1 quantifier
+ also quantifier minimizer
+ * 0 or more quantifier
+ + 1 or more quantifier
+ also "possessive quantifier"
+ { start min/max quantifier
+
+ Part of a pattern that is in square brackets is called a "character
+ class". In a character class the only metacharacters are:
+
+ \ general escape character
+ ^ negate the class, but only if the first character
+ - indicates character range
+ [ POSIX character class (only if followed by POSIX
+ syntax)
+ ] terminates the character class
+
+ The following sections describe the use of each of the metacharacters.
+
+
+BACKSLASH
+
+ The backslash character has several uses. Firstly, if it is followed by
+ a non-alphanumeric character, it takes away any special meaning that
+ character may have. This use of backslash as an escape character
+ applies both inside and outside character classes.
+
+ For example, if you want to match a * character, you write \* in the
+ pattern. This escaping action applies whether or not the following
+ character would otherwise be interpreted as a metacharacter, so it is
+ always safe to precede a non-alphanumeric with backslash to specify
+ that it stands for itself. In particular, if you want to match a back-
+ slash, you write \\.
+
+ If a pattern is compiled with the PCRE_EXTENDED option, whitespace in
+ the pattern (other than in a character class) and characters between a
+ # outside a character class and the next newline character are ignored.
+ An escaping backslash can be used to include a whitespace or # charac-
+ ter as part of the pattern.
+
+ If you want to remove the special meaning from a sequence of charac-
+ ters, you can do so by putting them between \Q and \E. This is differ-
+ ent from Perl in that $ and @ are handled as literals in \Q...\E
+ sequences in PCRE, whereas in Perl, $ and @ cause variable interpola-
+ tion. Note the following examples:
+
+ Pattern PCRE matches Perl matches
+
+ \Qabc$xyz\E abc$xyz abc followed by the
+ contents of $xyz
+ \Qabc\$xyz\E abc\$xyz abc\$xyz
+ \Qabc\E\$\Qxyz\E abc$xyz abc$xyz
+
+ The \Q...\E sequence is recognized both inside and outside character
+ classes.
+
+ Non-printing characters
+
+ A second use of backslash provides a way of encoding non-printing char-
+ acters in patterns in a visible manner. There is no restriction on the
+ appearance of non-printing characters, apart from the binary zero that
+ terminates a pattern, but when a pattern is being prepared by text
+ editing, it is usually easier to use one of the following escape
+ sequences than the binary character it represents:
+
+ \a alarm, that is, the BEL character (hex 07)
+ \cx "control-x", where x is any character
+ \e escape (hex 1B)
+ \f formfeed (hex 0C)
+ \n newline (hex 0A)
+ \r carriage return (hex 0D)
+ \t tab (hex 09)
+ \ddd character with octal code ddd, or backreference
+ \xhh character with hex code hh
+ \x{hhh..} character with hex code hhh... (UTF-8 mode only)
+
+ The precise effect of \cx is as follows: if x is a lower case letter,
+ it is converted to upper case. Then bit 6 of the character (hex 40) is
+ inverted. Thus \cz becomes hex 1A, but \c{ becomes hex 3B, while \c;
+ becomes hex 7B.
+
+ After \x, from zero to two hexadecimal digits are read (letters can be
+ in upper or lower case). In UTF-8 mode, any number of hexadecimal dig-
+ its may appear between \x{ and }, but the value of the character code
+ must be less than 2**31 (that is, the maximum hexadecimal value is
+ 7FFFFFFF). If characters other than hexadecimal digits appear between
+ \x{ and }, or if there is no terminating }, this form of escape is not
+ recognized. Instead, the initial \x will be interpreted as a basic hex-
+ adecimal escape, with no following digits, giving a character whose
+ value is zero.
+
+ Characters whose value is less than 256 can be defined by either of the
+ two syntaxes for \x when PCRE is in UTF-8 mode. There is no difference
+ in the way they are handled. For example, \xdc is exactly the same as
+ \x{dc}.
+
+ After \0 up to two further octal digits are read. In both cases, if
+ there are fewer than two digits, just those that are present are used.
+ Thus the sequence \0\x\07 specifies two binary zeros followed by a BEL
+ character (code value 7). Make sure you supply two digits after the
+ initial zero if the pattern character that follows is itself an octal
+ digit.
+
+ The handling of a backslash followed by a digit other than 0 is compli-
+ cated. Outside a character class, PCRE reads it and any following dig-
+ its as a decimal number. If the number is less than 10, or if there
+ have been at least that many previous capturing left parentheses in the
+ expression, the entire sequence is taken as a back reference. A
+ description of how this works is given later, following the discussion
+ of parenthesized subpatterns.
+
+ Inside a character class, or if the decimal number is greater than 9
+ and there have not been that many capturing subpatterns, PCRE re-reads
+ up to three octal digits following the backslash, and generates a sin-
+ gle byte from the least significant 8 bits of the value. Any subsequent
+ digits stand for themselves. For example:
+
+ \040 is another way of writing a space
+ \40 is the same, provided there are fewer than 40
+ previous capturing subpatterns
+ \7 is always a back reference
+ \11 might be a back reference, or another way of
+ writing a tab
+ \011 is always a tab
+ \0113 is a tab followed by the character "3"
+ \113 might be a back reference, otherwise the
+ character with octal code 113
+ \377 might be a back reference, otherwise
+ the byte consisting entirely of 1 bits
+ \81 is either a back reference, or a binary zero
+ followed by the two characters "8" and "1"
+
+ Note that octal values of 100 or greater must not be introduced by a
+ leading zero, because no more than three octal digits are ever read.
+
+ All the sequences that define a single byte value or a single UTF-8
+ character (in UTF-8 mode) can be used both inside and outside character
+ classes. In addition, inside a character class, the sequence \b is
+ interpreted as the backspace character (hex 08), and the sequence \X is
+ interpreted as the character "X". Outside a character class, these
+ sequences have different meanings (see below).
+
+ Generic character types
+
+ The third use of backslash is for specifying generic character types.
+ The following are always recognized:
+
+ \d any decimal digit
+ \D any character that is not a decimal digit
+ \s any whitespace character
+ \S any character that is not a whitespace character
+ \w any "word" character
+ \W any "non-word" character
+
+ Each pair of escape sequences partitions the complete set of characters
+ into two disjoint sets. Any given character matches one, and only one,
+ of each pair.
+
+ These character type sequences can appear both inside and outside char-
+ acter classes. They each match one character of the appropriate type.
+ If the current matching point is at the end of the subject string, all
+ of them fail, since there is no character to match.
+
+ For compatibility with Perl, \s does not match the VT character (code
+ 11). This makes it different from the the POSIX "space" class. The \s
+ characters are HT (9), LF (10), FF (12), CR (13), and space (32).
+
+ A "word" character is an underscore or any character less than 256 that
+ is a letter or digit. The definition of letters and digits is con-
+ trolled by PCRE's low-valued character tables, and may vary if locale-
+ specific matching is taking place (see "Locale support" in the pcreapi
+ page). For example, in the "fr_FR" (French) locale, some character
+ codes greater than 128 are used for accented letters, and these are
+ matched by \w.
+
+ In UTF-8 mode, characters with values greater than 128 never match \d,
+ \s, or \w, and always match \D, \S, and \W. This is true even when Uni-
+ code character property support is available.
+
+ Unicode character properties
+
+ When PCRE is built with Unicode character property support, three addi-
+ tional escape sequences to match generic character types are available
+ when UTF-8 mode is selected. They are:
+
+ \p{xx} a character with the xx property
+ \P{xx} a character without the xx property
+ \X an extended Unicode sequence
+
+ The property names represented by xx above are limited to the Unicode
+ general category properties. Each character has exactly one such prop-
+ erty, specified by a two-letter abbreviation. For compatibility with
+ Perl, negation can be specified by including a circumflex between the
+ opening brace and the property name. For example, \p{^Lu} is the same
+ as \P{Lu}.
+
+ If only one letter is specified with \p or \P, it includes all the
+ properties that start with that letter. In this case, in the absence of
+ negation, the curly brackets in the escape sequence are optional; these
+ two examples have the same effect:
+
+ \p{L}
+ \pL
+
+ The following property codes are supported:
+
+ C Other
+ Cc Control
+ Cf Format
+ Cn Unassigned
+ Co Private use
+ Cs Surrogate
+
+ L Letter
+ Ll Lower case letter
+ Lm Modifier letter
+ Lo Other letter
+ Lt Title case letter
+ Lu Upper case letter
+
+ M Mark
+ Mc Spacing mark
+ Me Enclosing mark
+ Mn Non-spacing mark
+
+ N Number
+ Nd Decimal number
+ Nl Letter number
+ No Other number
+
+ P Punctuation
+ Pc Connector punctuation
+ Pd Dash punctuation
+ Pe Close punctuation
+ Pf Final punctuation
+ Pi Initial punctuation
+ Po Other punctuation
+ Ps Open punctuation
+
+ S Symbol
+ Sc Currency symbol
+ Sk Modifier symbol
+ Sm Mathematical symbol
+ So Other symbol
+
+ Z Separator
+ Zl Line separator
+ Zp Paragraph separator
+ Zs Space separator
+
+ Extended properties such as "Greek" or "InMusicalSymbols" are not sup-
+ ported by PCRE.
+
+ Specifying caseless matching does not affect these escape sequences.
+ For example, \p{Lu} always matches only upper case letters.
+
+ The \X escape matches any number of Unicode characters that form an
+ extended Unicode sequence. \X is equivalent to
+
+ (?>\PM\pM*)
+
+ That is, it matches a character without the "mark" property, followed
+ by zero or more characters with the "mark" property, and treats the
+ sequence as an atomic group (see below). Characters with the "mark"
+ property are typically accents that affect the preceding character.
+
+ Matching characters by Unicode property is not fast, because PCRE has
+ to search a structure that contains data for over fifteen thousand
+ characters. That is why the traditional escape sequences such as \d and
+ \w do not use Unicode properties in PCRE.
+
+ Simple assertions
+
+ The fourth use of backslash is for certain simple assertions. An asser-
+ tion specifies a condition that has to be met at a particular point in
+ a match, without consuming any characters from the subject string. The
+ use of subpatterns for more complicated assertions is described below.
+ The backslashed assertions are:
+
+ \b matches at a word boundary
+ \B matches when not at a word boundary
+ \A matches at start of subject
+ \Z matches at end of subject or before newline at end
+ \z matches at end of subject
+ \G matches at first matching position in subject
+
+ These assertions may not appear in character classes (but note that \b
+ has a different meaning, namely the backspace character, inside a char-
+ acter class).
+
+ A word boundary is a position in the subject string where the current
+ character and the previous character do not both match \w or \W (i.e.
+ one matches \w and the other matches \W), or the start or end of the
+ string if the first or last character matches \w, respectively.
+
+ The \A, \Z, and \z assertions differ from the traditional circumflex
+ and dollar (described in the next section) in that they only ever match
+ at the very start and end of the subject string, whatever options are
+ set. Thus, they are independent of multiline mode. These three asser-
+ tions are not affected by the PCRE_NOTBOL or PCRE_NOTEOL options, which
+ affect only the behaviour of the circumflex and dollar metacharacters.
+ However, if the startoffset argument of pcre_exec() is non-zero, indi-
+ cating that matching is to start at a point other than the beginning of
+ the subject, \A can never match. The difference between \Z and \z is
+ that \Z matches before a newline that is the last character of the
+ string as well as at the end of the string, whereas \z matches only at
+ the end.
+
+ The \G assertion is true only when the current matching position is at
+ the start point of the match, as specified by the startoffset argument
+ of pcre_exec(). It differs from \A when the value of startoffset is
+ non-zero. By calling pcre_exec() multiple times with appropriate argu-
+ ments, you can mimic Perl's /g option, and it is in this kind of imple-
+ mentation where \G can be useful.
+
+ Note, however, that PCRE's interpretation of \G, as the start of the
+ current match, is subtly different from Perl's, which defines it as the
+ end of the previous match. In Perl, these can be different when the
+ previously matched string was empty. Because PCRE does just one match
+ at a time, it cannot reproduce this behaviour.
+
+ If all the alternatives of a pattern begin with \G, the expression is
+ anchored to the starting match position, and the "anchored" flag is set
+ in the compiled regular expression.
+
+
+CIRCUMFLEX AND DOLLAR
+
+ Outside a character class, in the default matching mode, the circumflex
+ character is an assertion that is true only if the current matching
+ point is at the start of the subject string. If the startoffset argu-
+ ment of pcre_exec() is non-zero, circumflex can never match if the
+ PCRE_MULTILINE option is unset. Inside a character class, circumflex
+ has an entirely different meaning (see below).
+
+ Circumflex need not be the first character of the pattern if a number
+ of alternatives are involved, but it should be the first thing in each
+ alternative in which it appears if the pattern is ever to match that
+ branch. If all possible alternatives start with a circumflex, that is,
+ if the pattern is constrained to match only at the start of the sub-
+ ject, it is said to be an "anchored" pattern. (There are also other
+ constructs that can cause a pattern to be anchored.)
+
+ A dollar character is an assertion that is true only if the current
+ matching point is at the end of the subject string, or immediately
+ before a newline character that is the last character in the string (by
+ default). Dollar need not be the last character of the pattern if a
+ number of alternatives are involved, but it should be the last item in
+ any branch in which it appears. Dollar has no special meaning in a
+ character class.
+
+ The meaning of dollar can be changed so that it matches only at the
+ very end of the string, by setting the PCRE_DOLLAR_ENDONLY option at
+ compile time. This does not affect the \Z assertion.
+
+ The meanings of the circumflex and dollar characters are changed if the
+ PCRE_MULTILINE option is set. When this is the case, they match immedi-
+ ately after and immediately before an internal newline character,
+ respectively, in addition to matching at the start and end of the sub-
+ ject string. For example, the pattern /^abc$/ matches the subject
+ string "def\nabc" (where \n represents a newline character) in multi-
+ line mode, but not otherwise. Consequently, patterns that are anchored
+ in single line mode because all branches start with ^ are not anchored
+ in multiline mode, and a match for circumflex is possible when the
+ startoffset argument of pcre_exec() is non-zero. The PCRE_DOL-
+ LAR_ENDONLY option is ignored if PCRE_MULTILINE is set.
+
+ Note that the sequences \A, \Z, and \z can be used to match the start
+ and end of the subject in both modes, and if all branches of a pattern
+ start with \A it is always anchored, whether PCRE_MULTILINE is set or
+ not.
+
+
+FULL STOP (PERIOD, DOT)
+
+ Outside a character class, a dot in the pattern matches any one charac-
+ ter in the subject, including a non-printing character, but not (by
+ default) newline. In UTF-8 mode, a dot matches any UTF-8 character,
+ which might be more than one byte long, except (by default) newline. If
+ the PCRE_DOTALL option is set, dots match newlines as well. The han-
+ dling of dot is entirely independent of the handling of circumflex and
+ dollar, the only relationship being that they both involve newline
+ characters. Dot has no special meaning in a character class.
+
+
+MATCHING A SINGLE BYTE
+
+ Outside a character class, the escape sequence \C matches any one byte,
+ both in and out of UTF-8 mode. Unlike a dot, it can match a newline.
+ The feature is provided in Perl in order to match individual bytes in
+ UTF-8 mode. Because it breaks up UTF-8 characters into individual
+ bytes, what remains in the string may be a malformed UTF-8 string. For
+ this reason, the \C escape sequence is best avoided.
+
+ PCRE does not allow \C to appear in lookbehind assertions (described
+ below), because in UTF-8 mode this would make it impossible to calcu-
+ late the length of the lookbehind.
+
+
+SQUARE BRACKETS AND CHARACTER CLASSES
+
+ An opening square bracket introduces a character class, terminated by a
+ closing square bracket. A closing square bracket on its own is not spe-
+ cial. If a closing square bracket is required as a member of the class,
+ it should be the first data character in the class (after an initial
+ circumflex, if present) or escaped with a backslash.
+
+ A character class matches a single character in the subject. In UTF-8
+ mode, the character may occupy more than one byte. A matched character
+ must be in the set of characters defined by the class, unless the first
+ character in the class definition is a circumflex, in which case the
+ subject character must not be in the set defined by the class. If a
+ circumflex is actually required as a member of the class, ensure it is
+ not the first character, or escape it with a backslash.
+
+ For example, the character class [aeiou] matches any lower case vowel,
+ while [^aeiou] matches any character that is not a lower case vowel.
+ Note that a circumflex is just a convenient notation for specifying the
+ characters that are in the class by enumerating those that are not. A
+ class that starts with a circumflex is not an assertion: it still con-
+ sumes a character from the subject string, and therefore it fails if
+ the current pointer is at the end of the string.
+
+ In UTF-8 mode, characters with values greater than 255 can be included
+ in a class as a literal string of bytes, or by using the \x{ escaping
+ mechanism.
+
+ When caseless matching is set, any letters in a class represent both
+ their upper case and lower case versions, so for example, a caseless
+ [aeiou] matches "A" as well as "a", and a caseless [^aeiou] does not
+ match "A", whereas a caseful version would. When running in UTF-8 mode,
+ PCRE supports the concept of case for characters with values greater
+ than 128 only when it is compiled with Unicode property support.
+
+ The newline character is never treated in any special way in character
+ classes, whatever the setting of the PCRE_DOTALL or PCRE_MULTILINE
+ options is. A class such as [^a] will always match a newline.
+
+ The minus (hyphen) character can be used to specify a range of charac-
+ ters in a character class. For example, [d-m] matches any letter
+ between d and m, inclusive. If a minus character is required in a
+ class, it must be escaped with a backslash or appear in a position
+ where it cannot be interpreted as indicating a range, typically as the
+ first or last character in the class.
+
+ It is not possible to have the literal character "]" as the end charac-
+ ter of a range. A pattern such as [W-]46] is interpreted as a class of
+ two characters ("W" and "-") followed by a literal string "46]", so it
+ would match "W46]" or "-46]". However, if the "]" is escaped with a
+ backslash it is interpreted as the end of range, so [W-\]46] is inter-
+ preted as a class containing a range followed by two other characters.
+ The octal or hexadecimal representation of "]" can also be used to end
+ a range.
+
+ Ranges operate in the collating sequence of character values. They can
+ also be used for characters specified numerically, for example
+ [\000-\037]. In UTF-8 mode, ranges can include characters whose values
+ are greater than 255, for example [\x{100}-\x{2ff}].
+
+ If a range that includes letters is used when caseless matching is set,
+ it matches the letters in either case. For example, [W-c] is equivalent
+ to [][\\^_`wxyzabc], matched caselessly, and in non-UTF-8 mode, if
+ character tables for the "fr_FR" locale are in use, [\xc8-\xcb] matches
+ accented E characters in both cases. In UTF-8 mode, PCRE supports the
+ concept of case for characters with values greater than 128 only when
+ it is compiled with Unicode property support.
+
+ The character types \d, \D, \p, \P, \s, \S, \w, and \W may also appear
+ in a character class, and add the characters that they match to the
+ class. For example, [\dABCDEF] matches any hexadecimal digit. A circum-
+ flex can conveniently be used with the upper case character types to
+ specify a more restricted set of characters than the matching lower
+ case type. For example, the class [^\W_] matches any letter or digit,
+ but not underscore.
+
+ The only metacharacters that are recognized in character classes are
+ backslash, hyphen (only where it can be interpreted as specifying a
+ range), circumflex (only at the start), opening square bracket (only
+ when it can be interpreted as introducing a POSIX class name - see the
+ next section), and the terminating closing square bracket. However,
+ escaping other non-alphanumeric characters does no harm.
+
+
+POSIX CHARACTER CLASSES
+
+ Perl supports the POSIX notation for character classes. This uses names
+ enclosed by [: and :] within the enclosing square brackets. PCRE also
+ supports this notation. For example,
+
+ [01[:alpha:]%]
+
+ matches "0", "1", any alphabetic character, or "%". The supported class
+ names are
+
+ alnum letters and digits
+ alpha letters
+ ascii character codes 0 - 127
+ blank space or tab only
+ cntrl control characters
+ digit decimal digits (same as \d)
+ graph printing characters, excluding space
+ lower lower case letters
+ print printing characters, including space
+ punct printing characters, excluding letters and digits
+ space white space (not quite the same as \s)
+ upper upper case letters
+ word "word" characters (same as \w)
+ xdigit hexadecimal digits
+
+ The "space" characters are HT (9), LF (10), VT (11), FF (12), CR (13),
+ and space (32). Notice that this list includes the VT character (code
+ 11). This makes "space" different to \s, which does not include VT (for
+ Perl compatibility).
+
+ The name "word" is a Perl extension, and "blank" is a GNU extension
+ from Perl 5.8. Another Perl extension is negation, which is indicated
+ by a ^ character after the colon. For example,
+
+ [12[:^digit:]]
+
+ matches "1", "2", or any non-digit. PCRE (and Perl) also recognize the
+ POSIX syntax [.ch.] and [=ch=] where "ch" is a "collating element", but
+ these are not supported, and an error is given if they are encountered.
+
+ In UTF-8 mode, characters with values greater than 128 do not match any
+ of the POSIX character classes.
+
+
+VERTICAL BAR
+
+ Vertical bar characters are used to separate alternative patterns. For
+ example, the pattern
+
+ gilbert|sullivan
+
+ matches either "gilbert" or "sullivan". Any number of alternatives may
+ appear, and an empty alternative is permitted (matching the empty
+ string). The matching process tries each alternative in turn, from
+ left to right, and the first one that succeeds is used. If the alterna-
+ tives are within a subpattern (defined below), "succeeds" means match-
+ ing the rest of the main pattern as well as the alternative in the sub-
+ pattern.
+
+
+INTERNAL OPTION SETTING
+
+ The settings of the PCRE_CASELESS, PCRE_MULTILINE, PCRE_DOTALL, and
+ PCRE_EXTENDED options can be changed from within the pattern by a
+ sequence of Perl option letters enclosed between "(?" and ")". The
+ option letters are
+
+ i for PCRE_CASELESS
+ m for PCRE_MULTILINE
+ s for PCRE_DOTALL
+ x for PCRE_EXTENDED
+
+ For example, (?im) sets caseless, multiline matching. It is also possi-
+ ble to unset these options by preceding the letter with a hyphen, and a
+ combined setting and unsetting such as (?im-sx), which sets PCRE_CASE-
+ LESS and PCRE_MULTILINE while unsetting PCRE_DOTALL and PCRE_EXTENDED,
+ is also permitted. If a letter appears both before and after the
+ hyphen, the option is unset.
+
+ When an option change occurs at top level (that is, not inside subpat-
+ tern parentheses), the change applies to the remainder of the pattern
+ that follows. If the change is placed right at the start of a pattern,
+ PCRE extracts it into the global options (and it will therefore show up
+ in data extracted by the pcre_fullinfo() function).
+
+ An option change within a subpattern affects only that part of the cur-
+ rent pattern that follows it, so
+
+ (a(?i)b)c
+
+ matches abc and aBc and no other strings (assuming PCRE_CASELESS is not
+ used). By this means, options can be made to have different settings
+ in different parts of the pattern. Any changes made in one alternative
+ do carry on into subsequent branches within the same subpattern. For
+ example,
+
+ (a(?i)b|c)
+
+ matches "ab", "aB", "c", and "C", even though when matching "C" the
+ first branch is abandoned before the option setting. This is because
+ the effects of option settings happen at compile time. There would be
+ some very weird behaviour otherwise.
+
+ The PCRE-specific options PCRE_UNGREEDY and PCRE_EXTRA can be changed
+ in the same way as the Perl-compatible options by using the characters
+ U and X respectively. The (?X) flag setting is special in that it must
+ always occur earlier in the pattern than any of the additional features
+ it turns on, even when it is at top level. It is best to put it at the
+ start.
+
+
+SUBPATTERNS
+
+ Subpatterns are delimited by parentheses (round brackets), which can be
+ nested. Turning part of a pattern into a subpattern does two things:
+
+ 1. It localizes a set of alternatives. For example, the pattern
+
+ cat(aract|erpillar|)
+
+ matches one of the words "cat", "cataract", or "caterpillar". Without
+ the parentheses, it would match "cataract", "erpillar" or the empty
+ string.
+
+ 2. It sets up the subpattern as a capturing subpattern. This means
+ that, when the whole pattern matches, that portion of the subject
+ string that matched the subpattern is passed back to the caller via the
+ ovector argument of pcre_exec(). Opening parentheses are counted from
+ left to right (starting from 1) to obtain numbers for the capturing
+ subpatterns.
+
+ For example, if the string "the red king" is matched against the pat-
+ tern
+
+ the ((red|white) (king|queen))
+
+ the captured substrings are "red king", "red", and "king", and are num-
+ bered 1, 2, and 3, respectively.
+
+ The fact that plain parentheses fulfil two functions is not always
+ helpful. There are often times when a grouping subpattern is required
+ without a capturing requirement. If an opening parenthesis is followed
+ by a question mark and a colon, the subpattern does not do any captur-
+ ing, and is not counted when computing the number of any subsequent
+ capturing subpatterns. For example, if the string "the white queen" is
+ matched against the pattern
+
+ the ((?:red|white) (king|queen))
+
+ the captured substrings are "white queen" and "queen", and are numbered
+ 1 and 2. The maximum number of capturing subpatterns is 65535, and the
+ maximum depth of nesting of all subpatterns, both capturing and non-
+ capturing, is 200.
+
+ As a convenient shorthand, if any option settings are required at the
+ start of a non-capturing subpattern, the option letters may appear
+ between the "?" and the ":". Thus the two patterns
+
+ (?i:saturday|sunday)
+ (?:(?i)saturday|sunday)
+
+ match exactly the same set of strings. Because alternative branches are
+ tried from left to right, and options are not reset until the end of
+ the subpattern is reached, an option setting in one branch does affect
+ subsequent branches, so the above patterns match "SUNDAY" as well as
+ "Saturday".
+
+
+NAMED SUBPATTERNS
+
+ Identifying capturing parentheses by number is simple, but it can be
+ very hard to keep track of the numbers in complicated regular expres-
+ sions. Furthermore, if an expression is modified, the numbers may
+ change. To help with this difficulty, PCRE supports the naming of sub-
+ patterns, something that Perl does not provide. The Python syntax
+ (?P<name>...) is used. Names consist of alphanumeric characters and
+ underscores, and must be unique within a pattern.
+
+ Named capturing parentheses are still allocated numbers as well as
+ names. The PCRE API provides function calls for extracting the name-to-
+ number translation table from a compiled pattern. There is also a con-
+ venience function for extracting a captured substring by name. For fur-
+ ther details see the pcreapi documentation.
+
+
+REPETITION
+
+ Repetition is specified by quantifiers, which can follow any of the
+ following items:
+
+ a literal data character
+ the . metacharacter
+ the \C escape sequence
+ the \X escape sequence (in UTF-8 mode with Unicode properties)
+ an escape such as \d that matches a single character
+ a character class
+ a back reference (see next section)
+ a parenthesized subpattern (unless it is an assertion)
+
+ The general repetition quantifier specifies a minimum and maximum num-
+ ber of permitted matches, by giving the two numbers in curly brackets
+ (braces), separated by a comma. The numbers must be less than 65536,
+ and the first must be less than or equal to the second. For example:
+
+ z{2,4}
+
+ matches "zz", "zzz", or "zzzz". A closing brace on its own is not a
+ special character. If the second number is omitted, but the comma is
+ present, there is no upper limit; if the second number and the comma
+ are both omitted, the quantifier specifies an exact number of required
+ matches. Thus
+
+ [aeiou]{3,}
+
+ matches at least 3 successive vowels, but may match many more, while
+
+ \d{8}
+
+ matches exactly 8 digits. An opening curly bracket that appears in a
+ position where a quantifier is not allowed, or one that does not match
+ the syntax of a quantifier, is taken as a literal character. For exam-
+ ple, {,6} is not a quantifier, but a literal string of four characters.
+
+ In UTF-8 mode, quantifiers apply to UTF-8 characters rather than to
+ individual bytes. Thus, for example, \x{100}{2} matches two UTF-8 char-
+ acters, each of which is represented by a two-byte sequence. Similarly,
+ when Unicode property support is available, \X{3} matches three Unicode
+ extended sequences, each of which may be several bytes long (and they
+ may be of different lengths).
+
+ The quantifier {0} is permitted, causing the expression to behave as if
+ the previous item and the quantifier were not present.
+
+ For convenience (and historical compatibility) the three most common
+ quantifiers have single-character abbreviations:
+
+ * is equivalent to {0,}
+ + is equivalent to {1,}
+ ? is equivalent to {0,1}
+
+ It is possible to construct infinite loops by following a subpattern
+ that can match no characters with a quantifier that has no upper limit,
+ for example:
+
+ (a?)*
+
+ Earlier versions of Perl and PCRE used to give an error at compile time
+ for such patterns. However, because there are cases where this can be
+ useful, such patterns are now accepted, but if any repetition of the
+ subpattern does in fact match no characters, the loop is forcibly bro-
+ ken.
+
+ By default, the quantifiers are "greedy", that is, they match as much
+ as possible (up to the maximum number of permitted times), without
+ causing the rest of the pattern to fail. The classic example of where
+ this gives problems is in trying to match comments in C programs. These
+ appear between /* and */ and within the comment, individual * and /
+ characters may appear. An attempt to match C comments by applying the
+ pattern
+
+ /\*.*\*/
+
+ to the string
+
+ /* first comment */ not comment /* second comment */
+
+ fails, because it matches the entire string owing to the greediness of
+ the .* item.
+
+ However, if a quantifier is followed by a question mark, it ceases to
+ be greedy, and instead matches the minimum number of times possible, so
+ the pattern
+
+ /\*.*?\*/
+
+ does the right thing with the C comments. The meaning of the various
+ quantifiers is not otherwise changed, just the preferred number of
+ matches. Do not confuse this use of question mark with its use as a
+ quantifier in its own right. Because it has two uses, it can sometimes
+ appear doubled, as in
+
+ \d??\d
+
+ which matches one digit by preference, but can match two if that is the
+ only way the rest of the pattern matches.
+
+ If the PCRE_UNGREEDY option is set (an option which is not available in
+ Perl), the quantifiers are not greedy by default, but individual ones
+ can be made greedy by following them with a question mark. In other
+ words, it inverts the default behaviour.
+
+ When a parenthesized subpattern is quantified with a minimum repeat
+ count that is greater than 1 or with a limited maximum, more memory is
+ required for the compiled pattern, in proportion to the size of the
+ minimum or maximum.
+
+ If a pattern starts with .* or .{0,} and the PCRE_DOTALL option (equiv-
+ alent to Perl's /s) is set, thus allowing the . to match newlines, the
+ pattern is implicitly anchored, because whatever follows will be tried
+ against every character position in the subject string, so there is no
+ point in retrying the overall match at any position after the first.
+ PCRE normally treats such a pattern as though it were preceded by \A.
+
+ In cases where it is known that the subject string contains no new-
+ lines, it is worth setting PCRE_DOTALL in order to obtain this opti-
+ mization, or alternatively using ^ to indicate anchoring explicitly.
+
+ However, there is one situation where the optimization cannot be used.
+ When .* is inside capturing parentheses that are the subject of a
+ backreference elsewhere in the pattern, a match at the start may fail,
+ and a later one succeed. Consider, for example:
+
+ (.*)abc\1
+
+ If the subject is "xyz123abc123" the match point is the fourth charac-
+ ter. For this reason, such a pattern is not implicitly anchored.
+
+ When a capturing subpattern is repeated, the value captured is the sub-
+ string that matched the final iteration. For example, after
+
+ (tweedle[dume]{3}\s*)+
+
+ has matched "tweedledum tweedledee" the value of the captured substring
+ is "tweedledee". However, if there are nested capturing subpatterns,
+ the corresponding captured values may have been set in previous itera-
+ tions. For example, after
+
+ /(a|(b))+/
+
+ matches "aba" the value of the second captured substring is "b".
+
+
+ATOMIC GROUPING AND POSSESSIVE QUANTIFIERS
+
+ With both maximizing and minimizing repetition, failure of what follows
+ normally causes the repeated item to be re-evaluated to see if a dif-
+ ferent number of repeats allows the rest of the pattern to match. Some-
+ times it is useful to prevent this, either to change the nature of the
+ match, or to cause it fail earlier than it otherwise might, when the
+ author of the pattern knows there is no point in carrying on.
+
+ Consider, for example, the pattern \d+foo when applied to the subject
+ line
+
+ 123456bar
+
+ After matching all 6 digits and then failing to match "foo", the normal
+ action of the matcher is to try again with only 5 digits matching the
+ \d+ item, and then with 4, and so on, before ultimately failing.
+ "Atomic grouping" (a term taken from Jeffrey Friedl's book) provides
+ the means for specifying that once a subpattern has matched, it is not
+ to be re-evaluated in this way.
+
+ If we use atomic grouping for the previous example, the matcher would
+ give up immediately on failing to match "foo" the first time. The nota-
+ tion is a kind of special parenthesis, starting with (?> as in this
+ example:
+
+ (?>\d+)foo
+
+ This kind of parenthesis "locks up" the part of the pattern it con-
+ tains once it has matched, and a failure further into the pattern is
+ prevented from backtracking into it. Backtracking past it to previous
+ items, however, works as normal.
+
+ An alternative description is that a subpattern of this type matches
+ the string of characters that an identical standalone pattern would
+ match, if anchored at the current point in the subject string.
+
+ Atomic grouping subpatterns are not capturing subpatterns. Simple cases
+ such as the above example can be thought of as a maximizing repeat that
+ must swallow everything it can. So, while both \d+ and \d+? are pre-
+ pared to adjust the number of digits they match in order to make the
+ rest of the pattern match, (?>\d+) can only match an entire sequence of
+ digits.
+
+ Atomic groups in general can of course contain arbitrarily complicated
+ subpatterns, and can be nested. However, when the subpattern for an
+ atomic group is just a single repeated item, as in the example above, a
+ simpler notation, called a "possessive quantifier" can be used. This
+ consists of an additional + character following a quantifier. Using
+ this notation, the previous example can be rewritten as
+
+ \d++foo
+
+ Possessive quantifiers are always greedy; the setting of the
+ PCRE_UNGREEDY option is ignored. They are a convenient notation for the
+ simpler forms of atomic group. However, there is no difference in the
+ meaning or processing of a possessive quantifier and the equivalent
+ atomic group.
+
+ The possessive quantifier syntax is an extension to the Perl syntax. It
+ originates in Sun's Java package.
+
+ When a pattern contains an unlimited repeat inside a subpattern that
+ can itself be repeated an unlimited number of times, the use of an
+ atomic group is the only way to avoid some failing matches taking a
+ very long time indeed. The pattern
+
+ (\D+|<\d+>)*[!?]
+
+ matches an unlimited number of substrings that either consist of non-
+ digits, or digits enclosed in <>, followed by either ! or ?. When it
+ matches, it runs quickly. However, if it is applied to
+
+ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+
+ it takes a long time before reporting failure. This is because the
+ string can be divided between the internal \D+ repeat and the external
+ * repeat in a large number of ways, and all have to be tried. (The
+ example uses [!?] rather than a single character at the end, because
+ both PCRE and Perl have an optimization that allows for fast failure
+ when a single character is used. They remember the last single charac-
+ ter that is required for a match, and fail early if it is not present
+ in the string.) If the pattern is changed so that it uses an atomic
+ group, like this:
+
+ ((?>\D+)|<\d+>)*[!?]
+
+ sequences of non-digits cannot be broken, and failure happens quickly.
+
+
+BACK REFERENCES
+
+ Outside a character class, a backslash followed by a digit greater than
+ 0 (and possibly further digits) is a back reference to a capturing sub-
+ pattern earlier (that is, to its left) in the pattern, provided there
+ have been that many previous capturing left parentheses.
+
+ However, if the decimal number following the backslash is less than 10,
+ it is always taken as a back reference, and causes an error only if
+ there are not that many capturing left parentheses in the entire pat-
+ tern. In other words, the parentheses that are referenced need not be
+ to the left of the reference for numbers less than 10. See the subsec-
+ tion entitled "Non-printing characters" above for further details of
+ the handling of digits following a backslash.
+
+ A back reference matches whatever actually matched the capturing sub-
+ pattern in the current subject string, rather than anything matching
+ the subpattern itself (see "Subpatterns as subroutines" below for a way
+ of doing that). So the pattern
+
+ (sens|respons)e and \1ibility
+
+ matches "sense and sensibility" and "response and responsibility", but
+ not "sense and responsibility". If caseful matching is in force at the
+ time of the back reference, the case of letters is relevant. For exam-
+ ple,
+
+ ((?i)rah)\s+\1
+
+ matches "rah rah" and "RAH RAH", but not "RAH rah", even though the
+ original capturing subpattern is matched caselessly.
+
+ Back references to named subpatterns use the Python syntax (?P=name).
+ We could rewrite the above example as follows:
+
+ (?<p1>(?i)rah)\s+(?P=p1)
+
+ There may be more than one back reference to the same subpattern. If a
+ subpattern has not actually been used in a particular match, any back
+ references to it always fail. For example, the pattern
+
+ (a|(bc))\2
+
+ always fails if it starts to match "a" rather than "bc". Because there
+ may be many capturing parentheses in a pattern, all digits following
+ the backslash are taken as part of a potential back reference number.
+ If the pattern continues with a digit character, some delimiter must be
+ used to terminate the back reference. If the PCRE_EXTENDED option is
+ set, this can be whitespace. Otherwise an empty comment (see "Com-
+ ments" below) can be used.
+
+ A back reference that occurs inside the parentheses to which it refers
+ fails when the subpattern is first used, so, for example, (a\1) never
+ matches. However, such references can be useful inside repeated sub-
+ patterns. For example, the pattern
+
+ (a|b\1)+
+
+ matches any number of "a"s and also "aba", "ababbaa" etc. At each iter-
+ ation of the subpattern, the back reference matches the character
+ string corresponding to the previous iteration. In order for this to
+ work, the pattern must be such that the first iteration does not need
+ to match the back reference. This can be done using alternation, as in
+ the example above, or by a quantifier with a minimum of zero.
+
+
+ASSERTIONS
+
+ An assertion is a test on the characters following or preceding the
+ current matching point that does not actually consume any characters.
+ The simple assertions coded as \b, \B, \A, \G, \Z, \z, ^ and $ are
+ described above.
+
+ More complicated assertions are coded as subpatterns. There are two
+ kinds: those that look ahead of the current position in the subject
+ string, and those that look behind it. An assertion subpattern is
+ matched in the normal way, except that it does not cause the current
+ matching position to be changed.
+
+ Assertion subpatterns are not capturing subpatterns, and may not be
+ repeated, because it makes no sense to assert the same thing several
+ times. If any kind of assertion contains capturing subpatterns within
+ it, these are counted for the purposes of numbering the capturing sub-
+ patterns in the whole pattern. However, substring capturing is carried
+ out only for positive assertions, because it does not make sense for
+ negative assertions.
+
+ Lookahead assertions
+
+ Lookahead assertions start with (?= for positive assertions and (?! for
+ negative assertions. For example,
+
+ \w+(?=;)
+
+ matches a word followed by a semicolon, but does not include the semi-
+ colon in the match, and
+
+ foo(?!bar)
+
+ matches any occurrence of "foo" that is not followed by "bar". Note
+ that the apparently similar pattern
+
+ (?!foo)bar
+
+ does not find an occurrence of "bar" that is preceded by something
+ other than "foo"; it finds any occurrence of "bar" whatsoever, because
+ the assertion (?!foo) is always true when the next three characters are
+ "bar". A lookbehind assertion is needed to achieve the other effect.
+
+ If you want to force a matching failure at some point in a pattern, the
+ most convenient way to do it is with (?!) because an empty string
+ always matches, so an assertion that requires there not to be an empty
+ string must always fail.
+
+ Lookbehind assertions
+
+ Lookbehind assertions start with (?<= for positive assertions and (?<!
+ for negative assertions. For example,
+
+ (?<!foo)bar
+
+ does find an occurrence of "bar" that is not preceded by "foo". The
+ contents of a lookbehind assertion are restricted such that all the
+ strings it matches must have a fixed length. However, if there are sev-
+ eral alternatives, they do not all have to have the same fixed length.
+ Thus
+
+ (?<=bullock|donkey)
+
+ is permitted, but
+
+ (?<!dogs?|cats?)
+
+ causes an error at compile time. Branches that match different length
+ strings are permitted only at the top level of a lookbehind assertion.
+ This is an extension compared with Perl (at least for 5.8), which
+ requires all branches to match the same length of string. An assertion
+ such as
+
+ (?<=ab(c|de))
+
+ is not permitted, because its single top-level branch can match two
+ different lengths, but it is acceptable if rewritten to use two top-
+ level branches:
+
+ (?<=abc|abde)
+
+ The implementation of lookbehind assertions is, for each alternative,
+ to temporarily move the current position back by the fixed width and
+ then try to match. If there are insufficient characters before the cur-
+ rent position, the match is deemed to fail.
+
+ PCRE does not allow the \C escape (which matches a single byte in UTF-8
+ mode) to appear in lookbehind assertions, because it makes it impossi-
+ ble to calculate the length of the lookbehind. The \X escape, which can
+ match different numbers of bytes, is also not permitted.
+
+ Atomic groups can be used in conjunction with lookbehind assertions to
+ specify efficient matching at the end of the subject string. Consider a
+ simple pattern such as
+
+ abcd$
+
+ when applied to a long string that does not match. Because matching
+ proceeds from left to right, PCRE will look for each "a" in the subject
+ and then see if what follows matches the rest of the pattern. If the
+ pattern is specified as
+
+ ^.*abcd$
+
+ the initial .* matches the entire string at first, but when this fails
+ (because there is no following "a"), it backtracks to match all but the
+ last character, then all but the last two characters, and so on. Once
+ again the search for "a" covers the entire string, from right to left,
+ so we are no better off. However, if the pattern is written as
+
+ ^(?>.*)(?<=abcd)
+
+ or, equivalently, using the possessive quantifier syntax,
+
+ ^.*+(?<=abcd)
+
+ there can be no backtracking for the .* item; it can match only the
+ entire string. The subsequent lookbehind assertion does a single test
+ on the last four characters. If it fails, the match fails immediately.
+ For long strings, this approach makes a significant difference to the
+ processing time.
+
+ Using multiple assertions
+
+ Several assertions (of any sort) may occur in succession. For example,
+
+ (?<=\d{3})(?<!999)foo
+
+ matches "foo" preceded by three digits that are not "999". Notice that
+ each of the assertions is applied independently at the same point in
+ the subject string. First there is a check that the previous three
+ characters are all digits, and then there is a check that the same
+ three characters are not "999". This pattern does not match "foo" pre-
+ ceded by six characters, the first of which are digits and the last
+ three of which are not "999". For example, it doesn't match "123abc-
+ foo". A pattern to do that is
+
+ (?<=\d{3}...)(?<!999)foo
+
+ This time the first assertion looks at the preceding six characters,
+ checking that the first three are digits, and then the second assertion
+ checks that the preceding three characters are not "999".
+
+ Assertions can be nested in any combination. For example,
+
+ (?<=(?<!foo)bar)baz
+
+ matches an occurrence of "baz" that is preceded by "bar" which in turn
+ is not preceded by "foo", while
+
+ (?<=\d{3}(?!999)...)foo
+
+ is another pattern that matches "foo" preceded by three digits and any
+ three characters that are not "999".
+
+
+CONDITIONAL SUBPATTERNS
+
+ It is possible to cause the matching process to obey a subpattern con-
+ ditionally or to choose between two alternative subpatterns, depending
+ on the result of an assertion, or whether a previous capturing subpat-
+ tern matched or not. The two possible forms of conditional subpattern
+ are
+
+ (?(condition)yes-pattern)
+ (?(condition)yes-pattern|no-pattern)
+
+ If the condition is satisfied, the yes-pattern is used; otherwise the
+ no-pattern (if present) is used. If there are more than two alterna-
+ tives in the subpattern, a compile-time error occurs.
+
+ There are three kinds of condition. If the text between the parentheses
+ consists of a sequence of digits, the condition is satisfied if the
+ capturing subpattern of that number has previously matched. The number
+ must be greater than zero. Consider the following pattern, which con-
+ tains non-significant white space to make it more readable (assume the
+ PCRE_EXTENDED option) and to divide it into three parts for ease of
+ discussion:
+
+ ( \( )? [^()]+ (?(1) \) )
+
+ The first part matches an optional opening parenthesis, and if that
+ character is present, sets it as the first captured substring. The sec-
+ ond part matches one or more characters that are not parentheses. The
+ third part is a conditional subpattern that tests whether the first set
+ of parentheses matched or not. If they did, that is, if subject started
+ with an opening parenthesis, the condition is true, and so the yes-pat-
+ tern is executed and a closing parenthesis is required. Otherwise,
+ since no-pattern is not present, the subpattern matches nothing. In
+ other words, this pattern matches a sequence of non-parentheses,
+ optionally enclosed in parentheses.
+
+ If the condition is the string (R), it is satisfied if a recursive call
+ to the pattern or subpattern has been made. At "top level", the condi-
+ tion is false. This is a PCRE extension. Recursive patterns are
+ described in the next section.
+
+ If the condition is not a sequence of digits or (R), it must be an
+ assertion. This may be a positive or negative lookahead or lookbehind
+ assertion. Consider this pattern, again containing non-significant
+ white space, and with the two alternatives on the second line:
+
+ (?(?=[^a-z]*[a-z])
+ \d{2}-[a-z]{3}-\d{2} | \d{2}-\d{2}-\d{2} )
+
+ The condition is a positive lookahead assertion that matches an
+ optional sequence of non-letters followed by a letter. In other words,
+ it tests for the presence of at least one letter in the subject. If a
+ letter is found, the subject is matched against the first alternative;
+ otherwise it is matched against the second. This pattern matches
+ strings in one of the two forms dd-aaa-dd or dd-dd-dd, where aaa are
+ letters and dd are digits.
+
+
+COMMENTS
+
+ The sequence (?# marks the start of a comment that continues up to the
+ next closing parenthesis. Nested parentheses are not permitted. The
+ characters that make up a comment play no part in the pattern matching
+ at all.
+
+ If the PCRE_EXTENDED option is set, an unescaped # character outside a
+ character class introduces a comment that continues up to the next new-
+ line character in the pattern.
+
+
+RECURSIVE PATTERNS
+
+ Consider the problem of matching a string in parentheses, allowing for
+ unlimited nested parentheses. Without the use of recursion, the best
+ that can be done is to use a pattern that matches up to some fixed
+ depth of nesting. It is not possible to handle an arbitrary nesting
+ depth. Perl provides a facility that allows regular expressions to
+ recurse (amongst other things). It does this by interpolating Perl code
+ in the expression at run time, and the code can refer to the expression
+ itself. A Perl pattern to solve the parentheses problem can be created
+ like this:
+
+ $re = qr{\( (?: (?>[^()]+) | (?p{$re}) )* \)}x;
+
+ The (?p{...}) item interpolates Perl code at run time, and in this case
+ refers recursively to the pattern in which it appears. Obviously, PCRE
+ cannot support the interpolation of Perl code. Instead, it supports
+ some special syntax for recursion of the entire pattern, and also for
+ individual subpattern recursion.
+
+ The special item that consists of (? followed by a number greater than
+ zero and a closing parenthesis is a recursive call of the subpattern of
+ the given number, provided that it occurs inside that subpattern. (If
+ not, it is a "subroutine" call, which is described in the next sec-
+ tion.) The special item (?R) is a recursive call of the entire regular
+ expression.
+
+ For example, this PCRE pattern solves the nested parentheses problem
+ (assume the PCRE_EXTENDED option is set so that white space is
+ ignored):
+
+ \( ( (?>[^()]+) | (?R) )* \)
+
+ First it matches an opening parenthesis. Then it matches any number of
+ substrings which can either be a sequence of non-parentheses, or a
+ recursive match of the pattern itself (that is a correctly parenthe-
+ sized substring). Finally there is a closing parenthesis.
+
+ If this were part of a larger pattern, you would not want to recurse
+ the entire pattern, so instead you could use this:
+
+ ( \( ( (?>[^()]+) | (?1) )* \) )
+
+ We have put the pattern into parentheses, and caused the recursion to
+ refer to them instead of the whole pattern. In a larger pattern, keep-
+ ing track of parenthesis numbers can be tricky. It may be more conve-
+ nient to use named parentheses instead. For this, PCRE uses (?P>name),
+ which is an extension to the Python syntax that PCRE uses for named
+ parentheses (Perl does not provide named parentheses). We could rewrite
+ the above example as follows:
+
+ (?P<pn> \( ( (?>[^()]+) | (?P>pn) )* \) )
+
+ This particular example pattern contains nested unlimited repeats, and
+ so the use of atomic grouping for matching strings of non-parentheses
+ is important when applying the pattern to strings that do not match.
+ For example, when this pattern is applied to
+
+ (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()
+
+ it yields "no match" quickly. However, if atomic grouping is not used,
+ the match runs for a very long time indeed because there are so many
+ different ways the + and * repeats can carve up the subject, and all
+ have to be tested before failure can be reported.
+
+ At the end of a match, the values set for any capturing subpatterns are
+ those from the outermost level of the recursion at which the subpattern
+ value is set. If you want to obtain intermediate values, a callout
+ function can be used (see the next section and the pcrecallout documen-
+ tation). If the pattern above is matched against
+
+ (ab(cd)ef)
+
+ the value for the capturing parentheses is "ef", which is the last
+ value taken on at the top level. If additional parentheses are added,
+ giving
+
+ \( ( ( (?>[^()]+) | (?R) )* ) \)
+ ^ ^
+ ^ ^
+
+ the string they capture is "ab(cd)ef", the contents of the top level
+ parentheses. If there are more than 15 capturing parentheses in a pat-
+ tern, PCRE has to obtain extra memory to store data during a recursion,
+ which it does by using pcre_malloc, freeing it via pcre_free after-
+ wards. If no memory can be obtained, the match fails with the
+ PCRE_ERROR_NOMEMORY error.
+
+ Do not confuse the (?R) item with the condition (R), which tests for
+ recursion. Consider this pattern, which matches text in angle brack-
+ ets, allowing for arbitrary nesting. Only digits are allowed in nested
+ brackets (that is, when recursing), whereas any characters are permit-
+ ted at the outer level.
+
+ < (?: (?(R) \d++ | [^<>]*+) | (?R)) * >
+
+ In this pattern, (?(R) is the start of a conditional subpattern, with
+ two different alternatives for the recursive and non-recursive cases.
+ The (?R) item is the actual recursive call.
+
+
+SUBPATTERNS AS SUBROUTINES
+
+ If the syntax for a recursive subpattern reference (either by number or
+ by name) is used outside the parentheses to which it refers, it oper-
+ ates like a subroutine in a programming language. An earlier example
+ pointed out that the pattern
+
+ (sens|respons)e and \1ibility
+
+ matches "sense and sensibility" and "response and responsibility", but
+ not "sense and responsibility". If instead the pattern
+
+ (sens|respons)e and (?1)ibility
+
+ is used, it does match "sense and responsibility" as well as the other
+ two strings. Such references must, however, follow the subpattern to
+ which they refer.
+
+
+CALLOUTS
+
+ Perl has a feature whereby using the sequence (?{...}) causes arbitrary
+ Perl code to be obeyed in the middle of matching a regular expression.
+ This makes it possible, amongst other things, to extract different sub-
+ strings that match the same pair of parentheses when there is a repeti-
+ tion.
+
+ PCRE provides a similar feature, but of course it cannot obey arbitrary
+ Perl code. The feature is called "callout". The caller of PCRE provides
+ an external function by putting its entry point in the global variable
+ pcre_callout. By default, this variable contains NULL, which disables
+ all calling out.
+
+ Within a regular expression, (?C) indicates the points at which the
+ external function is to be called. If you want to identify different
+ callout points, you can put a number less than 256 after the letter C.
+ The default value is zero. For example, this pattern has two callout
+ points:
+
+ (?C1)abc(?C2)def
+
+ If the PCRE_AUTO_CALLOUT flag is passed to pcre_compile(), callouts are
+ automatically installed before each item in the pattern. They are all
+ numbered 255.
+
+ During matching, when PCRE reaches a callout point (and pcre_callout is
+ set), the external function is called. It is provided with the number
+ of the callout, the position in the pattern, and, optionally, one item
+ of data originally supplied by the caller of pcre_exec(). The callout
+ function may cause matching to proceed, to backtrack, or to fail alto-
+ gether. A complete description of the interface to the callout function
+ is given in the pcrecallout documentation.
+
+Last updated: 09 September 2004
+Copyright (c) 1997-2004 University of Cambridge.
diff --git a/doc/doc-txt/pcretest.txt b/doc/doc-txt/pcretest.txt
new file mode 100644
index 000000000..9e9b70ef4
--- /dev/null
+++ b/doc/doc-txt/pcretest.txt
@@ -0,0 +1,455 @@
+This file contains the PCRE man page that described the pcretest program. Note
+that not all of the features of PCRE are available in the limited version that
+is built with Exim.
+-------------------------------------------------------------------------------
+
+PCRETEST(1) PCRETEST(1)
+
+
+
+NAME
+ pcretest - a program for testing Perl-compatible regular expressions.
+
+SYNOPSIS
+
+ pcretest [-C] [-d] [-i] [-m] [-o osize] [-p] [-t] [source]
+ [destination]
+
+ pcretest was written as a test program for the PCRE regular expression
+ library itself, but it can also be used for experimenting with regular
+ expressions. This document describes the features of the test program;
+ for details of the regular expressions themselves, see the pcrepattern
+ documentation. For details of the PCRE library function calls and their
+ options, see the pcreapi documentation.
+
+
+OPTIONS
+
+ -C Output the version number of the PCRE library, and all avail-
+ able information about the optional features that are
+ included, and then exit.
+
+ -d Behave as if each regex had the /D (debug) modifier; the
+ internal form is output after compilation.
+
+ -i Behave as if each regex had the /I modifier; information
+ about the compiled pattern is given after compilation.
+
+ -m Output the size of each compiled pattern after it has been
+ compiled. This is equivalent to adding /M to each regular
+ expression. For compatibility with earlier versions of
+ pcretest, -s is a synonym for -m.
+
+ -o osize Set the number of elements in the output vector that is used
+ when calling pcre_exec() to be osize. The default value is
+ 45, which is enough for 14 capturing subexpressions. The vec-
+ tor size can be changed for individual matching calls by
+ including \O in the data line (see below).
+
+ -p Behave as if each regex has /P modifier; the POSIX wrapper
+ API is used to call PCRE. None of the other options has any
+ effect when -p is set.
+
+ -t Run each compile, study, and match many times with a timer,
+ and output resulting time per compile or match (in millisec-
+ onds). Do not set -m with -t, because you will then get the
+ size output a zillion times, and the timing will be dis-
+ torted.
+
+
+DESCRIPTION
+
+ If pcretest is given two filename arguments, it reads from the first
+ and writes to the second. If it is given only one filename argument, it
+ reads from that file and writes to stdout. Otherwise, it reads from
+ stdin and writes to stdout, and prompts for each line of input, using
+ "re>" to prompt for regular expressions, and "data>" to prompt for data
+ lines.
+
+ The program handles any number of sets of input on a single input file.
+ Each set starts with a regular expression, and continues with any num-
+ ber of data lines to be matched against the pattern.
+
+ Each data line is matched separately and independently. If you want to
+ do multiple-line matches, you have to use the \n escape sequence in a
+ single line of input to encode the newline characters. The maximum
+ length of data line is 30,000 characters.
+
+ An empty line signals the end of the data lines, at which point a new
+ regular expression is read. The regular expressions are given enclosed
+ in any non-alphanumeric delimiters other than backslash, for example
+
+ /(a|bc)x+yz/
+
+ White space before the initial delimiter is ignored. A regular expres-
+ sion may be continued over several input lines, in which case the new-
+ line characters are included within it. It is possible to include the
+ delimiter within the pattern by escaping it, for example
+
+ /abc\/def/
+
+ If you do so, the escape and the delimiter form part of the pattern,
+ but since delimiters are always non-alphanumeric, this does not affect
+ its interpretation. If the terminating delimiter is immediately fol-
+ lowed by a backslash, for example,
+
+ /abc/\
+
+ then a backslash is added to the end of the pattern. This is done to
+ provide a way of testing the error condition that arises if a pattern
+ finishes with a backslash, because
+
+ /abc\/
+
+ is interpreted as the first line of a pattern that starts with "abc/",
+ causing pcretest to read the next line as a continuation of the regular
+ expression.
+
+
+PATTERN MODIFIERS
+
+ A pattern may be followed by any number of modifiers, which are mostly
+ single characters. Following Perl usage, these are referred to below
+ as, for example, "the /i modifier", even though the delimiter of the
+ pattern need not always be a slash, and no slash is used when writing
+ modifiers. Whitespace may appear between the final pattern delimiter
+ and the first modifier, and between the modifiers themselves.
+
+ The /i, /m, /s, and /x modifiers set the PCRE_CASELESS, PCRE_MULTILINE,
+ PCRE_DOTALL, or PCRE_EXTENDED options, respectively, when pcre_com-
+ pile() is called. These four modifier letters have the same effect as
+ they do in Perl. For example:
+
+ /caseless/i
+
+ The following table shows additional modifiers for setting PCRE options
+ that do not correspond to anything in Perl:
+
+ /A PCRE_ANCHORED
+ /C PCRE_AUTO_CALLOUT
+ /E PCRE_DOLLAR_ENDONLY
+ /N PCRE_NO_AUTO_CAPTURE
+ /U PCRE_UNGREEDY
+ /X PCRE_EXTRA
+
+ Searching for all possible matches within each subject string can be
+ requested by the /g or /G modifier. After finding a match, PCRE is
+ called again to search the remainder of the subject string. The differ-
+ ence between /g and /G is that the former uses the startoffset argument
+ to pcre_exec() to start searching at a new point within the entire
+ string (which is in effect what Perl does), whereas the latter passes
+ over a shortened substring. This makes a difference to the matching
+ process if the pattern begins with a lookbehind assertion (including \b
+ or \B).
+
+ If any call to pcre_exec() in a /g or /G sequence matches an empty
+ string, the next call is done with the PCRE_NOTEMPTY and PCRE_ANCHORED
+ flags set in order to search for another, non-empty, match at the same
+ point. If this second match fails, the start offset is advanced by
+ one, and the normal match is retried. This imitates the way Perl han-
+ dles such cases when using the /g modifier or the split() function.
+
+ There are yet more modifiers for controlling the way pcretest operates.
+
+ The /+ modifier requests that as well as outputting the substring that
+ matched the entire pattern, pcretest should in addition output the
+ remainder of the subject string. This is useful for tests where the
+ subject contains multiple copies of the same substring.
+
+ The /L modifier must be followed directly by the name of a locale, for
+ example,
+
+ /pattern/Lfr_FR
+
+ For this reason, it must be the last modifier. The given locale is set,
+ pcre_maketables() is called to build a set of character tables for the
+ locale, and this is then passed to pcre_compile() when compiling the
+ regular expression. Without an /L modifier, NULL is passed as the
+ tables pointer; that is, /L applies only to the expression on which it
+ appears.
+
+ The /I modifier requests that pcretest output information about the
+ compiled pattern (whether it is anchored, has a fixed first character,
+ and so on). It does this by calling pcre_fullinfo() after compiling a
+ pattern. If the pattern is studied, the results of that are also out-
+ put.
+
+ The /D modifier is a PCRE debugging feature, which also assumes /I. It
+ causes the internal form of compiled regular expressions to be output
+ after compilation. If the pattern was studied, the information returned
+ is also output.
+
+ The /F modifier causes pcretest to flip the byte order of the fields in
+ the compiled pattern that contain 2-byte and 4-byte numbers. This
+ facility is for testing the feature in PCRE that allows it to execute
+ patterns that were compiled on a host with a different endianness. This
+ feature is not available when the POSIX interface to PCRE is being
+ used, that is, when the /P pattern modifier is specified. See also the
+ section about saving and reloading compiled patterns below.
+
+ The /S modifier causes pcre_study() to be called after the expression
+ has been compiled, and the results used when the expression is matched.
+
+ The /M modifier causes the size of memory block used to hold the com-
+ piled pattern to be output.
+
+ The /P modifier causes pcretest to call PCRE via the POSIX wrapper API
+ rather than its native API. When this is done, all other modifiers
+ except /i, /m, and /+ are ignored. REG_ICASE is set if /i is present,
+ and REG_NEWLINE is set if /m is present. The wrapper functions force
+ PCRE_DOLLAR_ENDONLY always, and PCRE_DOTALL unless REG_NEWLINE is set.
+
+ The /8 modifier causes pcretest to call PCRE with the PCRE_UTF8 option
+ set. This turns on support for UTF-8 character handling in PCRE, pro-
+ vided that it was compiled with this support enabled. This modifier
+ also causes any non-printing characters in output strings to be printed
+ using the \x{hh...} notation if they are valid UTF-8 sequences.
+
+ If the /? modifier is used with /8, it causes pcretest to call
+ pcre_compile() with the PCRE_NO_UTF8_CHECK option, to suppress the
+ checking of the string for UTF-8 validity.
+
+
+DATA LINES
+
+ Before each data line is passed to pcre_exec(), leading and trailing
+ whitespace is removed, and it is then scanned for \ escapes. Some of
+ these are pretty esoteric features, intended for checking out some of
+ the more complicated features of PCRE. If you are just testing "ordi-
+ nary" regular expressions, you probably don't need any of these. The
+ following escapes are recognized:
+
+ \a alarm (= BEL)
+ \b backspace
+ \e escape
+ \f formfeed
+ \n newline
+ \r carriage return
+ \t tab
+ \v vertical tab
+ \nnn octal character (up to 3 octal digits)
+ \xhh hexadecimal character (up to 2 hex digits)
+ \x{hh...} hexadecimal character, any number of digits
+ in UTF-8 mode
+ \A pass the PCRE_ANCHORED option to pcre_exec()
+ \B pass the PCRE_NOTBOL option to pcre_exec()
+ \Cdd call pcre_copy_substring() for substring dd
+ after a successful match (number less than 32)
+ \Cname call pcre_copy_named_substring() for substring
+ "name" after a successful match (name termin-
+ ated by next non alphanumeric character)
+ \C+ show the current captured substrings at callout
+ time
+ \C- do not supply a callout function
+ \C!n return 1 instead of 0 when callout number n is
+ reached
+ \C!n!m return 1 instead of 0 when callout number n is
+ reached for the nth time
+ \C*n pass the number n (may be negative) as callout
+ data; this is used as the callout return value
+ \Gdd call pcre_get_substring() for substring dd
+ after a successful match (number less than 32)
+ \Gname call pcre_get_named_substring() for substring
+ "name" after a successful match (name termin-
+ ated by next non-alphanumeric character)
+ \L call pcre_get_substringlist() after a
+ successful match
+ \M discover the minimum MATCH_LIMIT setting
+ \N pass the PCRE_NOTEMPTY option to pcre_exec()
+ \Odd set the size of the output vector passed to
+ pcre_exec() to dd (any number of digits)
+ \P pass the PCRE_PARTIAL option to pcre_exec()
+ \S output details of memory get/free calls during matching
+ \Z pass the PCRE_NOTEOL option to pcre_exec()
+ \? pass the PCRE_NO_UTF8_CHECK option to
+ pcre_exec()
+ \>dd start the match at offset dd (any number of digits);
+ this sets the startoffset argument for pcre_exec()
+
+ A backslash followed by anything else just escapes the anything else.
+ If the very last character is a backslash, it is ignored. This gives a
+ way of passing an empty line as data, since a real empty line termi-
+ nates the data input.
+
+ If \M is present, pcretest calls pcre_exec() several times, with dif-
+ ferent values in the match_limit field of the pcre_extra data struc-
+ ture, until it finds the minimum number that is needed for pcre_exec()
+ to complete. This number is a measure of the amount of recursion and
+ backtracking that takes place, and checking it out can be instructive.
+ For most simple matches, the number is quite small, but for patterns
+ with very large numbers of matching possibilities, it can become large
+ very quickly with increasing length of subject string.
+
+ When \O is used, the value specified may be higher or lower than the
+ size set by the -O command line option (or defaulted to 45); \O applies
+ only to the call of pcre_exec() for the line in which it appears.
+
+ If the /P modifier was present on the pattern, causing the POSIX wrap-
+ per API to be used, only \B and \Z have any effect, causing REG_NOTBOL
+ and REG_NOTEOL to be passed to regexec() respectively.
+
+ The use of \x{hh...} to represent UTF-8 characters is not dependent on
+ the use of the /8 modifier on the pattern. It is recognized always.
+ There may be any number of hexadecimal digits inside the braces. The
+ result is from one to six bytes, encoded according to the UTF-8 rules.
+
+
+OUTPUT FROM PCRETEST
+
+ When a match succeeds, pcretest outputs the list of captured substrings
+ that pcre_exec() returns, starting with number 0 for the string that
+ matched the whole pattern. Otherwise, it outputs "No match" or "Partial
+ match" when pcre_exec() returns PCRE_ERROR_NOMATCH or PCRE_ERROR_PAR-
+ TIAL, respectively, and otherwise the PCRE negative error number. Here
+ is an example of an interactive pcretest run.
+
+ $ pcretest
+ PCRE version 5.00 07-Sep-2004
+
+ re> /^abc(\d+)/
+ data> abc123
+ 0: abc123
+ 1: 123
+ data> xyz
+ No match
+
+ If the strings contain any non-printing characters, they are output as
+ \0x escapes, or as \x{...} escapes if the /8 modifier was present on
+ the pattern. If the pattern has the /+ modifier, the output for sub-
+ string 0 is followed by the the rest of the subject string, identified
+ by "0+" like this:
+
+ re> /cat/+
+ data> cataract
+ 0: cat
+ 0+ aract
+
+ If the pattern has the /g or /G modifier, the results of successive
+ matching attempts are output in sequence, like this:
+
+ re> /\Bi(\w\w)/g
+ data> Mississippi
+ 0: iss
+ 1: ss
+ 0: iss
+ 1: ss
+ 0: ipp
+ 1: pp
+
+ "No match" is output only if the first match attempt fails.
+
+ If any of the sequences \C, \G, or \L are present in a data line that
+ is successfully matched, the substrings extracted by the convenience
+ functions are output with C, G, or L after the string number instead of
+ a colon. This is in addition to the normal full list. The string length
+ (that is, the return from the extraction function) is given in paren-
+ theses after each string for \C and \G.
+
+ Note that while patterns can be continued over several lines (a plain
+ ">" prompt is used for continuations), data lines may not. However new-
+ lines can be included in data by means of the \n escape.
+
+
+CALLOUTS
+
+ If the pattern contains any callout requests, pcretest's callout func-
+ tion is called during matching. By default, it displays the callout
+ number, the start and current positions in the text at the callout
+ time, and the next pattern item to be tested. For example, the output
+
+ --->pqrabcdef
+ 0 ^ ^ \d
+
+ indicates that callout number 0 occurred for a match attempt starting
+ at the fourth character of the subject string, when the pointer was at
+ the seventh character of the data, and when the next pattern item was
+ \d. Just one circumflex is output if the start and current positions
+ are the same.
+
+ Callouts numbered 255 are assumed to be automatic callouts, inserted as
+ a result of the /C pattern modifier. In this case, instead of showing
+ the callout number, the offset in the pattern, preceded by a plus, is
+ output. For example:
+
+ re> /\d?[A-E]\*/C
+ data> E*
+ --->E*
+ +0 ^ \d?
+ +3 ^ [A-E]
+ +8 ^^ \*
+ +10 ^ ^
+ 0: E*
+
+ The callout function in pcretest returns zero (carry on matching) by
+ default, but you can use an \C item in a data line (as described above)
+ to change this.
+
+ Inserting callouts can be helpful when using pcretest to check compli-
+ cated regular expressions. For further information about callouts, see
+ the pcrecallout documentation.
+
+
+SAVING AND RELOADING COMPILED PATTERNS
+
+ The facilities described in this section are not available when the
+ POSIX inteface to PCRE is being used, that is, when the /P pattern mod-
+ ifier is specified.
+
+ When the POSIX interface is not in use, you can cause pcretest to write
+ a compiled pattern to a file, by following the modifiers with > and a
+ file name. For example:
+
+ /pattern/im >/some/file
+
+ See the pcreprecompile documentation for a discussion about saving and
+ re-using compiled patterns.
+
+ The data that is written is binary. The first eight bytes are the
+ length of the compiled pattern data followed by the length of the
+ optional study data, each written as four bytes in big-endian order
+ (most significant byte first). If there is no study data (either the
+ pattern was not studied, or studying did not return any data), the sec-
+ ond length is zero. The lengths are followed by an exact copy of the
+ compiled pattern. If there is additional study data, this follows imme-
+ diately after the compiled pattern. After writing the file, pcretest
+ expects to read a new pattern.
+
+ A saved pattern can be reloaded into pcretest by specifing < and a file
+ name instead of a pattern. The name of the file must not contain a <
+ character, as otherwise pcretest will interpret the line as a pattern
+ delimited by < characters. For example:
+
+ re> </some/file
+ Compiled regex loaded from /some/file
+ No study data
+
+ When the pattern has been loaded, pcretest proceeds to read data lines
+ in the usual way.
+
+ You can copy a file written by pcretest to a different host and reload
+ it there, even if the new host has opposite endianness to the one on
+ which the pattern was compiled. For example, you can compile on an i86
+ machine and run on a SPARC machine.
+
+ File names for saving and reloading can be absolute or relative, but
+ note that the shell facility of expanding a file name that starts with
+ a tilde (~) is not available.
+
+ The ability to save and reload files in pcretest is intended for test-
+ ing and experimentation. It is not intended for production use because
+ only a single pattern can be written to a file. Furthermore, there is
+ no facility for supplying custom character tables for use with a
+ reloaded pattern. If the original pattern was compiled with custom
+ tables, an attempt to match a subject string using a reloaded pattern
+ is likely to cause pcretest to crash. Finally, if you attempt to load
+ a file that is not in the correct format, the result is undefined.
+
+
+AUTHOR
+
+ Philip Hazel <ph10@cam.ac.uk>
+ University Computing Service,
+ Cambridge CB2 3QG, England.
+
+Last updated: 10 September 2004
+Copyright (c) 1997-2004 University of Cambridge.