                 UNIVERSITY OF CAMBRIDGE COMPUTING SERVICE

              SPECIFICATION OF THE EXIM MAIL TRANSPORT AGENT

                                    by

                               Philip Hazel

Computer Laboratory
New Museums Site
Pembroke Street
Cambridge CB2 3QG
United Kingdom

phone:  +44 1223 334600
fax:    +44 1223 334679
email:  P.Hazel@ucs.cam.ac.uk

Edition for Exim 0.51, May 1996

                Copyright (c) University of Cambridge 1996



                           CONTENTS

1. Introduction
  1.1 Limitations
  1.2 Features
  1.3 Interface
  1.4 Terminology

2. Incorporated code

3. How Exim delivers mail

4. Building and installing Exim
  4.1 Unpacking
  4.2 Multiple machine architectures and operating systems
  4.3 Pre-building configuration
  4.4 The building process
  4.5 Overriding build-time options
  4.6 Installing commands and scripts
  4.7 Setting up the spool directory
  4.8 Testing
  4.9 Switching Exim on

5. Exim's command-line options

6. The Exim configuration file
  6.1 Common option syntax
  6.2 Integer
  6.3 Time interval
  6.4 Strings
  6.5 Expanded strings
  6.6 User and group names
  6.7 String lists
  6.8 Domain lists
  6.9 Net lists

7. Regular expression syntax

8. String expansions
  8.1 Expansion items
  8.2 Expansion operators
  8.3 Expansion conditions
  8.4 Expansion variables
  8.5 Expansion string examples

9. Main configuration

10. Driver specifications

11. Generic transport options

12. The appendfile transport

13. The autoreply transport

14. The debug transport

15. The pipe transport

16. The smtp transport

17. Generic director options

18. The aliasfile director

19. The forwardfile director

20. The localuser director

21. The smartuser director

22. Generic router options

23. The domainlist router

24. The iplookup router

25. The lookuphost router

26. The queryprogram router

27. Retry configuration

28. Address rewriting

29. Log files
  29.1 Message reception
  29.2 Deliveries
  29.3 Deferred deliveries
  29.4 Delivery failures
  29.5 Completion
  29.6 Message log

30. Message processing
  30.1 The Bcc header
  30.2 The Date header
  30.3 The Delivery-date header
  30.4 The From header
  30.5 The Message-id header
  30.6 The Received header
  30.7 The Return-path header
  30.8 The Sender header
  30.9 The To header
  30.10 Constructed addresses
  30.11 Case of local parts
  30.12 Rewriting addresses

31. The default configuration file
  31.1 Main configuration settings
  31.2 Transport configuration settings
  31.3 Director configuration settings
  31.4 Router configuration settings
  31.5 Retry rules
  31.6 Rewriting configuration

32. Day-to-day management
  32.1 The reject log
  32.2 Log cycling
  32.3 Statistics
  32.4 What is Exim doing?
  32.5 Changing the configuration
  32.6 Watching the queue

33. Intermittently connected hosts

34. Automatic mail processing
  34.1 System-wide automatic processing
  34.2 Users' automatic processing

35. Using Exim to handle mailing lists

36. Virtual domains
  36.1 All mail to a given host
  36.2 Virtual domain not preserving envelope
  36.3 Virtual domain preserving envelope

37. Exim utilities
  37.1 Querying Exim processes
  37.2 Extracting log information
  37.3 Cycling log files
  37.4 Making DBM files
  37.5 Individual retry times
  37.6 Database maintenance
  37.7 Mail statistics

38. The Exim monitor

39. SMTP processing
  39.1 Outgoing SMTP over TCP/IP
  39.2 Incoming SMTP over TCP/IP
  39.3 Unqualified addresses
  39.4 Sender verification
  39.5 Receiver verification
  39.6 Outgoing batched SMTP
  39.7 Incoming batched SMTP

40. Security considerations
  40.1 Root privilege
  40.2 Reading forward files
  40.3 Delivering to local files
  40.4 Trusted and admin users
  40.5 Spool files

41. Format of spool files

42. Adding new drivers to Exim




                              1. INTRODUCTION


  "If I have seen further it is by standing on the shoulders of giants."
                                                             (Isaac Newton)


Exim is a mail transfer agent for Unix systems connected to the Internet.
Configuration files currently exist for the following operating systems:
BSDI, FreeBSD, HP-UX, IRIX, Linux, NetBSD, DEC OSF1, SunOS4, SunOS5, and
Ultrix.

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.

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 mailer. Many of the ideas and user
interfaces are taken from Smail 3, though the actual code of Exim is
entirely new.

I am indebted to my colleague Piete Brooks for suggesting and implementing
the scheme for building Exim for multiple architectures and operating
systems, for porting Exim to several different versions of Unix, for
numerous suggestions, for pointing out where I had got things wrong, and
for extensive testing. A number of other 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.

This edition of the Exim specification applies to version 0.51 of Exim.
Changes from the 0.50 edition are marked by bars in the right margin. As
the program is still developing, there may be features in later versions of
the program that have not yet made it into this document. However, all
changes are noted briefly in the file called doc/ChangeLog which is
distributed with the source.

There is a mailing list for users of Exim called exim-
users@lists.cam.ac.uk. Requests to be added or deleted should be sent to
exim-users-request@lists.cam.ac.uk. By courtesy of Martin Hamilton, there
is an archive of this list in plain text form at
http://www.roads.lut.ac.uk/lists/exim-users/exim-users.archive and in HTML
via Hypermail at http://www.roads.lut.ac.uk/lists/exim-users/.


1.1 Limitations

 .   Exim is written in ANSI C. This should not be much of a limitation
     these days. However, to help with systems that lack a true ANSI C
     library, Exim avoids making any use of the value returned by the
     sprintf() function, which is one of the main incompatibilities. It has
     its own version of strerror() for use with SunOS4 and any other system
     that lacks this function, and a macro can be defined to turn memmove()
     into bcopy() if necessary.

 .   Exim uses file names that are longer than 14 characters.

 .   Exim is intended for use as an Internet mailer, and therefore handles
     addresses in RFC 822 domain format only. It cannot handle 'bang
     paths', though simple two-component bang paths can be converted by a
     straightforward rewriting configuration.

 .   Exim insists that every address it handles has a domain attached. For
     incoming local messages, domainless addresses are automatically quali-
     fied with a configured domain value. Configuration options specify
     from which remote systems unqualified addresses are acceptable.

 .   The only external transport currently implemented is an SMTP transport
     over a TCP/IP network (using sockets), suitable for machines on the
     Internet. However, a pipe transport is available, and there are
     facilities for writing messages to files in "batched SMTP" format;
     these can be used to send messages to some other transport mechanism.
     Batched SMTP input is also catered for.


1.2 Features

These are some of the main features of Exim:

 .   Exim follows the same general approach of decentralized control that
     Smail does. There is no central process doing overall management of
     mail delivery. However, unlike Smail, the independent delivery pro-
     cesses share data in the form of 'hints', which makes delivery more
     efficient in some cases.

 .   Exim has more flexible retry algorithms than Smail, applicable to
     directing and routing as well as to delivery.

 .   Exim contains header and envelope rewriting facilities.

 .   Unqualified addresses are accepted only from specified hosts or
     networks.

 .   Exim can perform multiple deliveries down the same SMTP channel after
     deliveries have been delayed.

 .   Exim can be configured to do local deliveries immediately but to leave
     remote (SMTP) deliveries until the message is picked up by a queue-
     runner process. This increases the likelihood of multiple messages
     being sent down a single SMTP connection.

 .   Incoming SMTP messages start delivery as soon as they are received,
     without waiting for the SMTP call to close.

 .   Regular expressions are available in a number of configuration
     parameters.

 .   Domain lists can include file lookups, making it possible to support
     very large numbers of local domains.

 .   Exim supports optional checking of incoming return path (sender) and
     receiver addresses as they are received by SMTP.

 .   SMTP calls from specific machines, optionally from specific idents,
     can be locked out, and incoming SMTP messages from specific senders
     can also be locked out.

 .   Messages on the queue can be 'frozen' and 'thawed' by the
     administrator.

 .   Exim can handle a number of independent local domains on the same
     machine; each domain can have its own alias files, etc.

 .   Exim stats a user's home directory before looking for a .forward file,
     in order to detect the case of a missing NFS mount.

 .   Exim contains an optional built-in mail filtering facility.

 .   Periodic warnings are automatically sent to messages' senders when
     delivery is delayed - the time between warnings is configurable.

 .   A queue run can be manually started to deliver just a particular
     portion of the queue, or those messages with a recipient whose address
     contains a given string.

 .   Exim can be configured to run as root all the time, except when
     performing local deliveries, which it always does in a separate
     process under an appropriate uid and gid. Alternatively, it can be
     configured to run as root only when needed; in particular, it need not
     run as root when receiving incoming messages or when sending out
     messages over SMTP. See chapter 40 for a discussion of security
     issues.

 .   I have tried to make the wording of delivery failure messages clearer
     and simpler, for the benefit of those less-experienced people who are
     now using email.

 .   The Exim Monitor is an optional extra; it displays information about
     Exim's processing in an X window, and an administrator can perform a
     number of control actions from the window interface.


1.3 Interface

Like many MTAs, Exim has adopted the Sendmail interface so that it can be a
straight replacement for /usr/lib/sendmail. All the relevant Sendmail
options are implemented. There are also some additional options that are
compatible with Smail 3, and some further options that are new to Exim.

The configuration interface is via a single text file which 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 configur-
ation file which is suitable for simple installations is provided.

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 contains interfaces
to the command line options.


1.4 Terminology

The term "local part", which is taken from RFC 822, 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".

The word "domain" is sometimes used to mean all but the first component of
a machine's name. It is not used in this sense here.

The term "mailmaster" is used to refer to the person in charge of
maintaining the mail software on a given computer. Commonly this will be
the same person who fulfils the postmaster role, but this may not always be
the case.



                            2. INCORPORATED CODE


Three pieces of external code are included in the Exim distribution.

 .   Regular expressions are supported in the main Exim program and in the
     Exim monitor using Henry Spencer's freely-distributable set of func-
     tions, copyright (c) 1986 University of Toronto. No modifications have
     been made to the source, which is distributed in the directory called
     regexp.

 .   RFC 1413 callbacks are supported in the main Exim program using the
     libident library made freely available by Peter Eriksson at
     ftp.lysator.liu.se. No modifications have been made to the source,
     which is distributed in the directory called src/libident.

 .   The Exim Monitor program, which is an X-Window application, includes a
     modified version of the Athena stripchart widget. This code is
     copyright by DEC and MIT, and their permission notice appears below,
     in accordance with the conditions expressed therein.

___________________________________________________________________________

Copyright 1987, 1988 by Digital Equipment Corporation, Maynard,
Massachusetts, and the Massachusetts Institute of Technology, Cambridge,
Massachusetts.

                            All Rights Reserved

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 documen-
tation, 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.
___________________________________________________________________________



                         3. HOW EXIM DELIVERS MAIL


When Exim receives a message, it writes two files in its spool directory.
The first contains the "envelope" information, the current status of the
message, and the headers, while the second contains the body of the
message. The envelope information consists of the address of the message's
sender and the address(es) of the recipient(s). This information is
entirely separate from any addresses contained in the headers. The status
of the message includes a list of recipients that have already received the
message.

The format of the first spool file is described in chapter 41. It gets
updated during the course of delivery, to record those addresses to which
the message has already been delivered. Updating is done by writing a new
file and renaming it, to minimize the possibility of data loss.

Every message handled by Exim is given a unique "message id" which is 16
characters long. It is divided into three parts, separated by hyphens. Each
part is a number, expressed in base 62:

     The first six characters are the time the message was received, as a
     number in seconds - the normal Unix way of representing a time of day.

     After the first hyphen, the next six characters are the id of the
     process that received the message.

     The final two characters, after the second hyphen, are used to ensure
     the id is unique, and are 00 except when a process receives more than
     one message in a single second.

The names of the two spool files consist of the message id, followed by -H
for the file containing the envelope and headers, and -D for the data file.

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.

An administrator can thaw such messages when the problem has been correc-
ted, and can also freeze individual messages by hand if necessary. In
addition, an administrator can force a delivery error, causing an error
message to be sent.

As delivery proceeds, Exim writes timestamped information about each
address to a per-message log file; this includes any delivery error
messages. This log is solely for the benefit of the administrator. All the
information Exim itself needs for delivery is kept in the first spool file.
The message log file is normally deleted with the spool files when
processing of a message is completed, but Exim can be configured to retain
it (a dangerous option, as the files can accumulate rapidly on a busy
system). Exim also writes delivery messages to its main log file, whose
contents are described in chapter 29.

The main delivery processing elements of Exim are called directors,
routers, and transports, and collectively these are known as drivers. Code
for a number of them is provided, and compile-time options specify which
ones are actually included in the binary. Directors handle addresses that
include one of the local domains, routers handle remote addresses, and
transports do actual deliveries.

When a message is to be delivered, the sequence of events is roughly as
follows:

 .   Each address is parsed and a check is made to see if it is local or
     not, by comparing the domain with the list of local domains (which can
     be wildcarded, or even read from a file).

 .   If an address is local, it is passed to each configured director in
     turn until one is able to handle it. If none can, the address is
     failed. Directors can be targeted at particular local domains, so
     several local domains can be processed independently of each other.

 .   A director that accepts an address may set up a local or a remote
     transport for it, or it may generate one or more new addresses (from
     alias, forward, or filter files). New addresses are fed back into this
     process from the top, but in order to avoid loops, a director ignores
     any address which has an identically-named ancestor that was processed
     by itself.

 .   If an address is not local, it is passed to each router in turn until
     one is able to handle it. If none can, the address is failed.

 .   A router that accepts an address may set up a transport for it, or may
     pass an altered address to subsequent routers, or it may discover that
     the address is a local address after all. This typically happens when
     a partial domain name is used and (for example) the DNS lookup is
     configured to try to extend such names. In this case, the address is
     passed back to the directors.

 .   Routers normally set up remote transports for messages that are to be
     delivered to other machines. However, a router can pass a message to a
     local transport, and by this means messages can be routed to other
     transport mechanisms.

 .   When all the directing and routing is 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, but can be
     configured to restrict multiple addresses to the same domain, if
     necessary. Each local transport runs in a separate process under a
     non-privileged uid, and remote transports can optionally be run under
     a uid that is private to Exim, instead of running as root, but they
     all run in the main Exim process.

 .   Before running any local transport, Exim checks its retry database to
     see if there has been a previous temporary delivery failure for the
     address. If so, it does not attempt a new delivery until the retry
     time for the address is reached. 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 failures and no host has reached its retry time, no
     delivery is attempted. See chapter 27 for details of retry strategies.

 .   If there were any errors, a 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 error
     messages to other addresses.

 .   If one or more addresses suffered a temporary failure, the message is
     left on the queue, to be tried again later. Otherwise the spool files
     and message log are deleted, though the message log can optionally be
     preserved if required.

When a message cannot be delivered to some or all of its intended
recipients, a delivery failure report is generated. All the addresses that
failed in a given delivery attempt are listed in a single failure report.
If a 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 failure report for a single message.

A failure report 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 FROM 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 it is common to direct failure reports to the manager of the
list.

If a failure report itself suffers a delivery failure, the message is left
on the queue, but is 'frozen', awaiting the attention of an administrator.

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 probably the most common. Local
deliveries may also be delayed if NFS files are unavailable, or if a
mailbox is on a filing system where the user is over quota.

Temporary failures may be detected during routing and directing as well as
during the transport stage. Delivery is said to be "deferred" when the
message remains on the queue for a subsequent delivery attempt. Exim uses a
set of configured rules to determine when next to process the failing
address (see chapter 27). These rules also specify when Exim should give up
trying to deliver to the address, at which point it generates a failure
report.

A machine that is connected to the Internet can normally deliver most mail
straight away. In its default configuration, Exim starts a delivery process
whenever it receives a message, and usually this completes the entire
delivery. This is a lightweight approach, avoiding the need for any
centralized queue managing software. There are those who argue that a
central message manager would be able to batch up messages for the same
host and send them in a single SMTP call. I do not myself believe this
would occur much in general, unless messages were significantly delayed in
order to create a batch.

However, 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, 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.



                      4. BUILDING AND INSTALLING EXIM


4.1 Unpacking

Exim is distributed as a tar file which, when upacked, creates a directory
with the name of the current release (e.g. exim-0.43) into which the
following files are placed:

  LICENCE       the GNU General Public Licence
  Makefile      top-level make file
  NOTICE        conditions for the use of Exim
  README        list of files and directories & simple build instructions

It also creates the following subdirectories:

  OS            OS-specific files
  doc           documentation files
  exim_monitor  source files for the Exim monitor
  regexp        source files for the regular expression routines
  scripts       scripts used in the build process
  src           remaining source files
  util          independent utilities

Some utilities are contained in the src directory, and are built with the
Exim binary; those in the util directory are things like a log file
analyser, which do not depend on any compile-time configuration.


4.2 Multiple machine architectures and operating systems

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. 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.


4.3 Pre-building configuration

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. Default values are supplied for all of them except for those that
specify the locations of the runtime configuration file, the directory for
holding Exim binaries, and Exim's spool directory. These must all be given,
as Exim will not build without them.

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 in exim_monitor/EDITME, then
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. See section 4.5 below for details of how to
do this.


4.4 The building process

Once Local/Makefile (and Local/eximon.conf) 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 2, the directory build-SunOS5-sparc is
created. Symbolic links to relevant source files are installed in the build
directory.

If this is the first time "make" has been run, it calls a script which
builds a make file inside the build directory, using the configuration
files from the Local directory. To be on the safe side, it does not run
this new make file automatically, but asks you to type "make" again.

The second run of "make" does the real work, building a number of utility
scripts, and then compiling and linking the binaries for Exim itself, the
Exim monitor (if configured), and a number of utility binary commands.


4.5 Overriding build-time options

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:

  OS/Makefile-Default
  OS/Makefile-<ostype>
  Local/Makefile
  Local/Makefile-<ostype>
  Local/Makefile-<archtype>
  Local/Makefile-<ostype>-<archtype>
  OS/Makefile-Base

where <ostype> is the operating system type and <archtype> is the architec-
ture 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
typically 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 OSTYPE or ARCHTYPE is set, their values are used,
thereby providing a means of forcing particular settings. Otherwise, the
scripts try various ad hoc methods of determining these values.

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.

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, do so by putting
the new values in an appropriate Local file. For example, to specify that
the C compiler is called cc rather than gcc when compiling in the OSF1
operating system, and that it is to be to be called with the flag -std1,
create a file called Local/Makefile-OSF1 containing the lines

  CC=cc
  CFLAGS=-std1

Exim contains support for doing NIS lookups, but not all systems support
NIS. There is a configuration option called HAVE_NIS which defaults to the
value 'yes' in OS/Makefile-Default, but is set to 'no' for the BSDI and
FreeBSD operating systems. When it is not set to 'yes', the code for making
NIS calls is not compiled, and attempts to configure Exim to use NIS cause
configuration errors.

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. The following three variables are set in OS/Makefile-Default:

  X11=/usr/X11R5
  XINCLUDE=-I$(X11)/include
  XLFLAGS=-L$(X11)/lib

These are overridden in some of the operating-system configuration files.
For example, in OS/Makefile-SunOS5 there is

  X11=/usr/openwin
  XINCLUDE=-I$(X11)/include
  XLFLAGS=-L$(X11)/lib -R$(X11)/lib

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.

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. There is also EXTRALIBS_EXIMON, which appears
only on the link step for the Exim monitor binary, and which can be used,
for example, to include additional X11 libraries.

Another variable which is not normally defined is STDERR_FILE. This defines
a file to which debugging output is written if the -df flag is set, and is
of use when running Exim under inetd.

Yet another variable which should not normally be set is ERRNO_QUOTA. Exim
needs to know which error the operating system gives when writing to a file
fails because the user is over quota. POSIX specifies an error called
EDQUOT and this is present in the latest versions of all the systems Exim
has been ported to at the time of writing. However, it is not present in
earlier versions of SunOS5, which use ENOSPC instead. The code of Exim
defaults to using EDQUOT if it is defined, and ENOSPC otherwise. You should
set ERRNO_QUOTA only if your system uses some completely different error
code.

A similar process is used for overriding things when building the Exim
monitor, where the files that are involved are

  OS/eximon.conf-Default
  OS/eximon.conf-<ostype>
  Local/eximon.conf
  Local/eximon.conf-<ostype>
  Local/eximon.conf-<archtype>
  Local/eximon.conf-<ostype>-<archtype>

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.

The make file copes with rebuilding exim correctly if any of the configur-
ation files is edited. However, if an optional configuration file is
deleted, it is necessary to touch the associated non-optional file (i.e.
Local/Makefile or Local/eximon.conf) before rebuilding.


4.6 Installing commands and scripts

The script scripts/exim_install copies binaries and utility scripts into
the directory whose name is specified by the BIN_DIRECTORY setting in
Local/Makefile. Files are copied only if they are newer than any versions
already in the binary directory, and old versions are renamed by adding the
suffix .O to their names.

The command "make install" runs the exim_install script with no arguments.
It can be run independently with arguments specifying which files are to be
copied, from within a build directory. For example,

  (cd build-SunOS5-sparc; ../scripts/exim_install exim)

copies just the main binary file. The main exim binary is required to be
owned by root and setuid. The script sets this up, and should therefore
normally be run as root. If you want to see what the script will do before
running it for real, use the -n option (for which root is not needed):

  (cd build-SunOS5-sparc; ../scripts/exim_install -n)

Exim's runtime configuration file is named by the CONFIGURE_FILE setting in
Local/Makefile. If this file does not exist, then the default configuration
file src/configure.default is copied there by the installation script. If
there already is a runtime configuration file, it is left alone.


4.7 Setting up the spool directory

When it starts up, Exim tries to create its spool directory if it does not
exist. If a specific Exim uid and gid are specified, these are used for the
owner and group of the spool directory. Sub-directories are automatically
created in the spool directory as necessary.


4.8 Testing

Having installed Exim and set up its runtime configuration file, some
simple tests can be done by using the address testing option. For example,

  exim -v -bt <local username>

should verify that it recognizes a local mailbox, and

  exim -v -bt <remote address>

a remote one. Then try getting it to deliver mail, both locally and
remotely.

One thing that cannot be tested on a system that is already running a
mailer 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.

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 runtime configuration, all other system file and
directory names that Exim uses can be altered, in order to keep it entirely
clear of the production version.

For debugging purposes, code for a transport called debug is supplied, but
is not by default included in the binary. It is recommended that this never
be included as a matter of course, because it makes it possible to subvert
mail deliveries. When this code is available, the debug_transport runtime
configuration option can be set, and this suppresses normal mail delivery.
Instead, information about each delivery is written to a file named by the
debug_transport option. Further details are given in chapter 14.


4.9 Switching Exim on

Building and installing Exim does not of itself put it in general use. The
name by which the system message transfer agent is called by mail user
agents is /usr/lib/sendmail, and it is necessary to make this name point at
the exim binary in order to get them to use it. This is normally done by
renaming any existing file and making /usr/lib/sendmail a symbolic link to
the exim binary. It is then necessary to stop and restart the mailer
daemon, if one is running.



                       5. EXIM'S COMMAND-LINE OPTIONS


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.

If Exim is called under the name mailq, it behaves as if the option -bp
were present before any other options. This is for compatibility with some
systems that contain a command of that name in one of the standard
libraries, symbolically linked to /usr/lib/sendmail.

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.

Some Exim options are available only to "trusted users" and others are
available only to "admin users".

 .   A trusted user is root or the Exim user (if defined) or any user
     listed in the trusted_users configuration option, or any user, if the
     currently set group is one of those listed in the trusted_groups
     configuration option. Trusted users are permitted to use the -f option
     to specify the senders of messages that are passed to Exim through the
     local interface, and also to specify host names, host addresses,
     protocol names, and ident values. Thus they are able to insert
     messages into Exim's queue locally that have the characteristics of
     messages received from a remote host.

 .   An admin user is root or the Exim user (if defined) or any user that
     is a member of the Exim group (if defined). The current group does not
     have to be the Exim group. Admin users are permitted to operate on
     messages in the queue, 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.

Exim's command options are as follows:

-bd    Run Exim as a daemon, awaiting incoming SMTP connections. If either
       of the -d or -dm options are set, the daemon does not disconnect
       from the controlling terminal. By default, the standard SMTP port is
       used, but this can be varied for testing by means of the -oX option.
       Most commonly, the -bd option is combined with the -q option, to
       cause periodic queue runs to happen as well. The process id of the
       daemon is written to a file called exim-daemon.pid in Exim's spool
       directory, unless the -oX option is used, in which case the file
       name is exim-daemon.<port-number>.pid.

       The SIGHUP signal can be used to cause the daemon to re-exec itself.
       This should be done whenever Exim's configuration file is changed,
       or a new version of Exim is installed. It is not necessary to do
       this when other files (e.g. alias files) are changed.

-bm    Accept an incoming, locally-generated message on the current input,
       and deliver it to the addresses given as the command arguments
       (except when -t is also given - see below). Each argument can be a
       comma-separated list of RFC 822 addresses. This is the default
       option, and is assumed if no other conflicting option is present.
       The message may or may not be delivered immediately, depending on
       the setting of the -od option and the queue_only and queue_smtp
       configuration options.

       The format of the message must be as defined in RFC 822, except
       that, for compatibility with sendmail and smail, a line of the form

         From sender Fri Jan  5 12:55 GMT 1996

       is permitted to appear at the start of the message. The Solaris 2
       version of the "mail" command inserts such a line, though there is
       no mention of it in the sendmail man page. The sender specified in
       this line is treated as if it were given as the argument to the -f
       option.

-bp    List the contents of the mail queue on the current output. Each
       message on the queue is displayed as in the following example:

         25m 0t5C6f-0000c8-00 <alice@wonderland.fict.book>
             red.king@looking-glass.fict.book
             <other addresses>

       The first line contains the amount of time the message has been on
       the queue (in this case 25 minutes), the unique identifier for the
       message, and the message sender, as contained in the envelope. If
       the message is a delivery error message, the sender address is
       empty, and appears as <>. 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 an asterisk.
       If an original address gets expanded into several addresses via an
       alias or forward file, the original is displayed with an asterisk
       when deliveries for all of its child addresses are completed.

-bP    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:

         exim -bP qualify_domain local_domains

       If configure_file is given, the name of the runtime configuration
       file is output. If one of the words director, router, or transport
       is given, followed by the name of an appropriate driver instance,
       the option settings for that driver are output. For example:

         exim -bP transport local_delivery

       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
       director_list, router_list, or transport_list, and a complete list
       of all drivers with their option settings can be obtained by using
       directors, routers, or drivers.

-bS    This option is used for batched SMTP input, where messages have been
       received from some external source by an alternative transport
       mechanism. It causes Exim to accept one or more messages by reading
       SMTP on the standard input, but to generate no responses. All errors
       are reported by sending mail. If the caller is trusted, then the
       senders in the MAIL FROM 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. Receiver verification and administrative rejection is not
       done, even if configured. HELO and EHLO act as RSET; VRFY, EXPN,
       HELP, and DEBUG act as NOOP; QUIT quits.

-bs    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. Some user agents use this interface as a way of
       passing locally-generated messages to the MTA. The option can also
       be used to run Exim from inetd, as an alternative to using a
       listening daemon, in which case the standard input is the connected
       socket. Exim distinguishes between the two cases by attempting to
       read the IP address of the peer connected to the standard input. If
       it is not a socket, the call to getpeername() fails, and Exim
       assumes it is dealing with a local message.

       If the caller of Exim is trusted, then the senders of messages are
       taken from the SMTP MAIL FROM commands. Otherwise the content of
       these commands is ignored and the sender is set up as the logged in
       user.

-bt    Run in address testing mode, in which each argument is taken as an
       address to be tested. The results are written to the standard
       output. If no arguments are given, Exim runs in an interactive
       manner, prompting with > for addresses to be tested. Each address is
       handled as if it were the recipient address on a message and passed
       to the appropriate directors or routers.

-bV    Write the current version number, compilation number, and compi-
       lation date of the exim binary to the standard output.

-bv    Verify the addresses that are given as the arguments to the command,
       and write the results to the standard output. Verification differs
       from address testing (the -bt option) in that directors and routers
       that have no_verify set are skipped, and if the address is accepted
       by a director or router that has fail_verify set, verification
       fails. This is the same logic that is used when verifying addresses
       on incoming messages (see the sender_verify and receiver_verify
       options).

       If the -v (or -d) 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
       aliases or forwarding, the generated addresses are also considered.

-C <filename>
       Read the runtime configuration from the given file instead of from
       the default file specified by the CONFIGURE_FILE compile-time set-
       ting. When this option is used, Exim gives up its root privilege
       immediately, and runs with the real and effective uid and gid set to
       those of the caller, to avoid any security exposure. The facility is
       useful for ensuring that configuration files are syntactically
       correct, but cannot be used for test deliveries. No check is made on
       the owner or group of the file specified by this option.

-d<number>
       Sets a debug level, causing debugging information to be written to
       the standard error file. Whitespace between -d and the number is
       optional. If no number is given, 1 is assumed, and the higher the
       number, the more output is produced. A value of zero turns debugging
       output off. A value of 9 gives the maximum amount of general
       information, 10 gives in addition details of the interpretation of
       filter files, and 11 or higher also turns on the debugging option
       for DNS lookups.

-df    If this option is set and STDERR_FILE was defined when Exim was
       built, debugging information is written to the file defined by that
       variable instead of to the standard error file. This option provides
       a way of obtaining debugging information when Exim is run from
       inetd.

-dm    This option causes information about memory allocation and freeing
       operations to be written to the standard error file.

-E     This option specifies that an incoming message is a locally-
       generated delivery failure message. It is used internally by Exim
       when handling delivery failures. Its only effect is to stop Exim
       generating certain messages to the mailmaster, as otherwise message
       cascades could occur in some situations.

-ex    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 -ex as synonymous with the corresponding -oex
       options.

-F <string>
       Set 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 file 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.

-f <address>
       Set the address of the sender of a locally-generated message. This
       option can normally be used only by root or the Exim user or by one
       of the configured trusted users. In other cases, the sender of a
       local message is always set up as the user who ran the exim command,
       and -f is ignored, with one exception. If the special setting -f <>
       is used by an untrusted user, it does not affect the sender for the
       purposes of managing the Sender: and From: headers, but it does have
       the effect of causing any SMTP transmissions to be sent out with

         MAIL FROM: <>

       and local deliveries not to contain a Return-path: header. The
       filtering code treats such a message as an error message, and won't
       generate messages as a result of reading it.

       White space between -f and the <string> is optional. The sender of a
       locally-generated message can also be set by an initial 'From' line
       - see the description of -bm above.

-h <number>
       This option is accepted for compatibility with sendmail, but at
       present has no effect. (In sendmail it overrides the 'hop count'
       obtained by counting Received headers.)

-i     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.

-M     The arguments are interpreted as a list of message ids, and Exim
       runs a delivery attempt on each message in turn. Retry hints for any
       of the addresses are overridden - this option forces Exim to try to
       deliver even if the normal retry time has not yet been reached.

-Mar <message-id> <address> <address> ...
       The first argument must be a message id, and the remaining ones must
       be email addresses. Exim adds the addresses to the list of recipi-
       ents of the message. 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.

-Meb <message-id>
       This runs, under /bin/sh, the command defined in the shell variable
       VISUAL or, if that is not defined, EDITOR or, if that is not
       defined, the command vi, on the spool file containing the body of
       message (eb = Edit Body). The thinking behind providing this feature
       is that an administrator who has had to mess around with the
       addresses to get a message delivered might want to add some
       (grumbly) comment at the start of the message text.

-Mes <message-id> <address>
       There must be exactly two arguments. The first argument must be a
       message id, and the second one an email address. Exim changes the
       sender address in the message to the given address, which must be a
       fully qualified address, or '<>'. 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.

-Mmd <message-id> <address> <address> ...
       The first argument must be a message id, and the remaining ones must
       be email addresses. Exim marks the given addresses as already
       delivered. 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.

-MC <transport> <hostname> <sequence number> <message id>
       This option is not intended for use by outside callers. It is used
       internally by Exim to invoke another instance of itself to deliver a
       waiting message using an existing SMTP channel, which is passed as
       the standard input and output. Details are given in chapter 39. This
       must be the final option, and the caller must be root or the Exim
       user in order to use it.

-Mc    The arguments are interpreted as a list of message ids, and Exim
       runs 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 (except
       for testing). It is provided for internal use by Exim when it needs
       to re-invoke itself in order to regain root privilege for a delivery
       (see chapter 40).

-Mf    The arguments are interpreted as a list of message ids, and each
       message is marked 'frozen', which prevents any delivery attempts
       from taking place. However, if any of the messages is active (in the
       middle of a delivery attempt), its status is not altered. This
       option can be used only by an admin user.

-Mg    The arguments are interpreted as a list of message ids, and Exim
       gives up trying to deliver those messages. A delivery error message
       is sent, containing the text 'cancelled by administrator'. However,
       if any of the messages is active, its status is not altered. This
       option can be used only by an admin user.

-Mt    The arguments are interpreted as a list of message ids, and each
       message that was 'frozen' is now 'thawed', so that delivery attempts
       can resume. However, if any of the messages is active, its status is
       not altered. This option can be used only by an admin user.

-Mrm   The arguments are interpreted as a list of message ids, and each
       message is completely removed from Exim's queue, and forgotten.
       However, if any of the messages is active, its 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.

-m     This is apparently a synonym for -om that is accepted by sendmail,
       so Exim treats it that way too.

-N     This is a debugging option that inhibits delivery of a message at
       the transport level. It implies at least -d1. 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. The
       log, for example, will contain entries as if the message had been
       delivered. Only root or the exim user are allowed to use -N with
       -bd, -q, or -M. In other words, an ordinary user can use it only
       when supplying an incoming message.

-odb   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 another delivery process for each message
       received. Exim does not wait for such processes to complete (it can
       take some time to perform SMTP deliveries). This is the default
       action if none of the -od options are present.

-odf   This option (compatible with smail) requests 'foreground' (syn-
       chronous) delivery when Exim has accepted a locally-generated mess-
       age. For the daemon it is exactly the same as -odb. For a single
       message received on the standard input, if the protection regime
       permits it (see chapter 40), Exim converts the reception process
       into a delivery process. In other cases, it creates a new delivery
       process, and then waits for it to complete before proceeding.

-odi   This option is synonymous with -odf. It is provided for compati-
       bility with sendmail.

-odq   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 attempt
       for each message received. Messages are placed on the queue, and
       remain there until a subsequent queue-running process encounters
       them. The queue_only configuration option has the same effect.

-odqs  This option is a hybrid between -odb and -odq. A delivery process is
       started for each incoming message, the addresses are all processed,
       and local deliveries are done in the normal way. However, if any
       SMTP deliveries are required, they are not done at this time. Such
       messages remain on the queue until a subsequent queue-running
       process encounters them. Because routing was done, Exim knows which
       messages are waiting for which hosts, and so a number of messages
       for the same host will get sent in a single SMTP connection.

-oem   If an error is detected while a non-SMTP message is being received
       (e.g. a malformed address), the error is reported to the sender in a
       mail message. This is the default option. After a message has been
       successfully received, any subsequent delivery errors are always
       reported in this way.

-oep   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).

-oeq   This option is supported for compatibility with sendmail, but has
       the same effect as -oep.

-oew   This option is supported for compatibility with sendmail, but has
       the same effect as -oem.

-oi    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.

-oMa <host address>
       This option sets the sender host address value, and can be used only
       by a trusted caller. The value is used in log entries and can appear
       in Received headers. The option is intended for use when handing to
       Exim messages received by other means.

-oMr <protocol name>
       This option sets the received protocol value, and can be used only
       by a trusted caller. The value is used in log entries and can appear
       in Received headers. The option is intended for use when handing to
       Exim messages received by other means.

-oMs <host name>
       This option sets the sender host name value, and can be used only by
       a trusted caller. The value is used in log entries and can appear in
       Received headers. The option is intended for use when handing to
       Exim messages received by other means.

-oMt <ident string>
       This option sets the sender ident value, and can be used only by a
       trusted caller. The value is used in log entries and can appear in
       Received headers. The option is intended for use when handing to
       Exim messages received by other means.

-om    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.

-or <time>
       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 using the accept_timeout configuration vari-
       able. The format used for specifying times is described in section
       6.3.

-oX <number>
       This option is relevant only when the -bd option is also given. It
       specifies an alternative TCP/IP port number for the listening
       daemon, and is useful for testing. When used, the process number of
       the daemon is written to a file whose name is exim-
       daemon.<number>.pid in Exim's spool directory.

-q     If the -q option is not followed by a time value, it requests a
       single queue run operation. Exim starts up a delivery process for
       each (inactive) message on the queue, and waits for it to finish
       before starting the next one. It is possible to start this operation
       at a particular place in the queue by following the -q option with a
       starting message id. For example:

         exim -q 0t5C6f-0000c8-00

       This causes Exim to skip any messages whose ids are lexically less
       than the given id. A second id can also be given to stop the queue
       run before the end of the queue.

       If no message ids are given, Exim arranges that queue runs are done
       in an unpredictable order. It isn't truly 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.

-q <time>
       This version of the -q option causes Exim to run as a daemon,
       starting a queue-running process at intervals specified by the given
       time value (whose format is described in section 6.3). 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 used a command such as

         /opt/exim/bin/exim -bd -q30m

       The process id of the daemon is written to a file called exim-
       daemon.pid in Exim's spool directory, unless the -oX option has been
       used, in which case the file is called exim-daemon.<port-
       number>.pid.

-R <string>
       This option is similar to -q with no time value, except that, when
       scanning the messages on the queue, Exim skips those with no
       undelivered addresses containing the given string. In addition, for
       the first message containing a matching address that it tries to
       deliver, Exim overrides any retry information and forces a delivery
       attempt. This makes it possible to initiate delivery for all
       messages to a given domain after a host has been down for some time.

-r     This is a documented obsolete alternative name for -f.

-t     When Exim is receiving a locally-generated, non-SMTP message on the
       current input, the -t option causes the recipients of the message to
       be obtained from the To, Cc, and Bcc headers in the message instead
       of from the command arguments. If there are any arguments, they
       specify addresses to which the message is not to be delivered. That
       is, the argument addresses are removed from the recipients list
       obtained from the headers. If a Bcc header is present, it is removed
       from the message unless there is no To header, in which case a Bcc
       header with no data is created, in accordance with RFC 822.

-v     This option has exactly the same effect as -d1; it causes Exim to be
       'verbose' and produce some output describing what it is doing on the
       standard error file. In particular, if an SMTP connection is made,
       the SMTP dialogue is shown.



                       6. THE EXIM CONFIGURATION FILE


Exim uses a single runtime configuration file which it reads when it is
starting up. The name of the file is compiled into the binary for security
reasons, and is specified by the CONFIGURE_FILE compilation option.

Some sites may wish to use the same Exim binary on different machines that
share a filing system, but to use different configuration files on each
machine. If CONFIGURE_FILE_USE_NODE is defined in Local/Makefile, then 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.

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.

The runtime configuration file must be owned by root or by the user that is
specified at compile time by the EXIM_USER option, and it must not be
world-writeable or group-writeable, unless its group is the one specified
at compile time by the EXIM_GROUP option.

A one-off alternative configuration file can be specified by the -C command
line option, but if this is done, Exim immediately gives up its root
privilege, so this option 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.

A default configuration file, which will work correctly in simple situ-
ations, is provided in the file src/configure.default. The installation
process copies this into CONFIGURE_FILE if there is no previously-existing
configuration file.

If a syntax error is detected while reading the configuration file, Exim
writes a message on the standard error, and exists with a non-zero return
code. The message is also written to the panic log.

Exim's configuration file is in six parts, which must appear in the correct
order in the file, separated by a line containing just the word 'end'.
These parts contain:

 .   Main configuration settings.

 .   Configuration settings for the transport drivers.

 .   Configuration settings for the director drivers.

 .   Configuration settings for the router drivers.

 .   Retry rules, for use when a message cannot be immediately delivered.

 .   Header re-writing rules.

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.

Blank lines in the file are ignored, and lines starting with a # character
are treated as comments and are also ignored. The retry and rewriting rules
have their own syntax which is described in chapters 27 and 28 below. The
remaining parts have some syntactic items in common, and these are
described here.


6.1 Common option syntax

Each option 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:

  exim_user = exim

Options whose type is given as boolean are on/off switches that are not
always followed by a data value. If the option name is specified on its
own, the switch is turned on; if it is preceded by 'no_' or 'not_' then the
switch is turned off. However, boolean options may alternatively be
followed by an equals sign and one of the words 'true', 'false', 'yes', or
'no'. For example:

  sender_verify
  no_smtp_verify
  queue_only = true

The types of data that may be required by non-boolean options are described
in the following sections.


6.2 Integer

If a numerical 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. No negative values
are involved. 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 option settings are output, some are always shown in
octal, and for others, values which are an exact multiple of 1024 or
1024x1024 are printed using the letters K and M. The printing style is
independent of the actual input format that was used.


6.3 Time interval

A time interval is specified as a sequence of numbers, each followed by one
of the following letters, and with no intervening white space:

  s   seconds
  m   minutes
  h   hours
  d   days
  w   weeks

For example, '3h50m' specifies 3 hours and 50 minutes. The values of time
options are output in the same format.


6.4 Strings

If a string data item does not start with a double-quote character, then it
is taken as consisting of the remainder of the line, starting at the first
non-whitespace character, with trailing whitespace characters removed, and
with no interpretation of the characters therein.

If a string does start with a double-quote, then it continues to a closing
double-quote, with the backslash character (\) being interpreted as an
escape character. If a backslash occurs at the end of an input line, the
string is continued on the following line, with any leading whitespace
being removed. For example, the following two settings are equivalent:

  local_domains = "wonderland.fict.book:\
                   lookingglass.fict.book"
  local_domains = wonderland.fict.book:lookingglass.fict.book

If a backslash occurs in the middle of a line, the following escapes are
recognized:

  \\               single backslash
  \n               newline
  \r               carriage return
  \t               tab
  \<octal digits>  up to 3 octal digits specify one character
  \x<hex digits>   up to 2 hexadecimal digits specify one character

If a backslash is followed by some other character, including a double-
quote character, then that character replaces the pair.


6.5 Expanded strings

Some strings in the configuration file subjected to string expansion, by
which means various parts of the string may be changed according to the
circumstances. The input syntax for such strings is as just described; the
expansion process is described in chapter 8.


6.6 User and group names

User and group names are specified as strings, using the syntax described
above, but the strings are interpreted specially. In the main section of
the configuration file, 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.

However, when a user or group is specified as an option for a transport or
director driver, it may alternatively be a string that gets expanded each
time the user or group value is required. The presence of a $ character in
the string causes this action to happen. Each time the string is expanded,
the result must either be a digit string, or a name that can be looked up
using getpwnam() or getgrnam(), as appropriate.


6.7 String lists

Some configuration settings accept a colon-separated list of strings. In
these cases the entire list is treated as a single string as far as the
input syntax is concerned. The local_domains setting in section 6.4 above
is an example. There is a limit of 1023 on the number of items in a string
list.


6.8 Domain lists

Domain lists are colon-separated string lists containing a number of domain
patterns that are to be matched against the domain given in a mail address.
Several different kinds of matching are provided:

 .   If the pattern starts with an asterisk, then the remaining characters
     of the pattern are compared with the terminating characters of the
     domain.

 .   If the pattern starts with a circumflex character, then 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. The syntax of regular expressions is
     described in chapter 7, but note that if a backslash is required in
     the regular expression, it must be given as two backslashes in the
     string.

 .   If the pattern starts with one of the strings 'dbm;' or 'lsearch;'
     then the remainder of the pattern must be an absolute file name. In
     the first case, a DBM lookup is done on the file using the domain name
     as the key; in the second case a linear search is performed for a line
     starting with the domain name, which must be followed by a colon if
     there is other data on the line (i.e. it is in the format of an alias
     file). The data from a DBM lookup or the rest of a linear search line
     is not used.

 .   If the pattern starts with the string 'nis;' then the remainder of the
     pattern must be the name of a NIS map, and a NIS lookup is done using
     the domain name as the key. The data from the lookup is not used. The
     NIS facility is new to Exim 0.43 and has not yet been extensively
     used.

 .   If none of the above cases apply, a straight textual comparison is
     made between the pattern and the domain.

Here is an example which uses all four kinds of pattern:

  local_domains = "lib.unseen.edu:\
                   *.foundation.fict.book:\
                   ^[1-2][0-9][0-9][0-9]\\.fict\\.book$:\
                   dbm;/opt/data/penguin/book"

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 lookup is expensive,
but may be the only option if hundreds of names are required. The patterns
are tested in order, so it makes sense to put the most commonly matched
patterns earlier in the string.


6.9 Net lists

Net lists are colon-separated string lists in which each item identifies an
IP network. Each item consists of an IP (sub-)network number and a net
mask, both specified in 'dotted quad' notation, and separated by a slash.
For example:

  receiver_unqualified_nets = 131.111.14.0/255.255.255.0

An IP address is compared with the network number using the given mask.



                        7. REGULAR EXPRESSION SYNTAX


Exim uses Henry Spencer's freely distributable regular expression library.
The syntax of the regular expressions that it supports is as follows:

A regular expression is zero or more branches, separated by '|'. It matches
anything that matches one of the branches. A branch is zero or more pieces,
concatenated. It matches a match for the first, followed by a match for the
second, etc. A piece is an atom possibly followed by '*', '+', or '?'.

An atom followed by '*' matches a sequence of 0 or more matches of the
atom. An atom followed by '+' matches a sequence of 1 or more matches of
the atom. An atom followed by '?' matches a match of the atom, or the null
string.

An atom is a regular expression in parentheses (matching a match for the
regular expression), a range (see below), '.' (matching any single charac-
ter), '^' (matching the null string at the beginning of the input string),
'$' (matching the null string at the end of the input string), a '\'
followed by a single character (matching that character), or a single
character with no other significance (matching that character).

A range is a sequence of characters enclosed in '[]'. It normally matches
any single character from the sequence. If the sequence begins with '^', it
matches any single character not from the rest of the sequence. If two
characters in the sequence are separated by '-', this is shorthand for the
full list of ASCII characters between them (e.g. '[0-9]' matches any
decimal digit). To include a literal ']' in the sequence, make it the first
character (following a possible '^'). To include a literal '-', make it the
first or last character.



                            8. STRING EXPANSIONS


A number of configuration strings are expanded before use. Some of them are
expanded every time they are used; others are expanded only once.

Expanded strings are copied verbatim except when a dollar character is
encountered. This specifies the start of a portion of the string which is
interpreted and replaced as described below.

An uninterpreted dollar can be included in the string by putting a
backslash in front of it - if the string appears in quotes, two backslashes
are required because the quotes themselves cause some interpretation when
the string is read in. A backslash can in fact be used to prevent any
character being treated specially in an expansion.


8.1 Expansion items

The following items are recognized in expanded strings:

$<variable name> or ${<variable name>}

   Substitute the contents of the named variable; the latter form can be
   used to separate the name from subsequent alphameric characters. The
   names of the variables are given in section 4 below.

$header_<header name>: or $h_<header name>:

   Substitute the contents of the named message header, for example

     $header_reply-to:

   This particular expansion is intended mainly for use in user's filter
   files. The header names follow the syntax of RFC 822, which states that
   they may contain any printing characters except space and colon.
   Consequently, curly brackets do not terminate header names. Upper and
   lower case letters are synonymous in header names. If the following
   character is white space, the terminating colon may be omitted. If the
   message does not contain the given header, the expansion item is
   replaced by an empty string. If there is more than one header with the
   same name, they are all concatenated to form the substitution string,
   with a newline character between them.

${<op>:<string>}

   The string is first itself expanded, and then the operation specified by
   <op> is applied to it. A list of operators is given in section 2 below.

${if <condition> {<string1>}{<string2>}}

   If <condition> is true, <string1> is expanded and replaces the whole
   item; otherwise <string2> is used. 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 fails if the condition is not true. The available
   conditions are described in section 3 below.

${lookup{<key>} <search type> {<file>} {<string1>} {<string2>}}

   The <key> and <file> strings are first expanded. The key is then looked
   up in the file, using the given search type, which can be one of

     dbm       do a DBM lookup
     lsearch   do a linear search
     nis       search a NIS map

   For a linear search, a line beginning with the key followed by a colon
   is searched for, and the data is the remainder of the line and any
   continuations, in the format of an alias file. For a NIS search, <file>
   is the name of the NIS map. The NIS facility is new in Exim 0.43 and has
   not been used extensively.

   If the key is found, then <string1> is expanded and replaces the entire
   item. During its expansion, a variable called value is available,
   containing the data returned by the file lookup. If the key is not
   found, then <string2> is expanded and replaces the entire item. It may
   be omitted, in which case the replacement is null.

   Instead of {<string2>} the word 'fail' can appear, and in this case, if
   the key is not found in the file, the string expansion fails in a way
   that can be detected by the caller. The consequences of this depend on
   the circumstances.

${lookup{<key:subkey>} <search type> {<file>} {<string1>} {<string2>}}

   This searches for <key> in the file as described above; if it succeeds,
   it extracts from the data a subfield which is identified by the
   <subkey>. The data related to the main key must be of the form:

     <subkey1> = <value1>  <subkey2> = <value2> ...

   where the equals signs 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 6.4. For example, if a line in a linearly searched file
   contains

     alice: uid=1984 gid=2001

   then expanding the string

     ${lookup{alice:uid}lsearch{<file name>}{$value}}

   yields the string '1984'. If the subkey is not found in <string1>, then
   <string2> is expanded and replaces the entire item.

${extract{<key>}{<string>}}

   The key and the string are first expanded. Then the subfield identified
   by the key is extracted from the string, exactly as just described for
   lookup items with subkeys. If the key is not found in the string, the
   item is replaced by nothing.


8.2 Expansion operators

A string can be forced into lower case by the lc operator, for example

  ${lc:$local_part}

The length operator can be used to extract the initial portion of a string.
It is followed by an underscore and the number of characters required. For
example

  ${length_50:$message_body}

The result of this operator is either the first n characters or the whole
string, whichever is the shorter. The abbreviation l can be used instead of
length.


8.3 Expansion conditions

The following conditions are available for testing while expanding strings:

  !<condition>

This negates the result of the condition.

  def:<variable>

This condition is true if the named expansion variable does not contain the
empty string.

  exists:<file name>

This condition is true if the named file (or directory) exists. The
existence test is done by calling the stat() function.

  eq {string1}{string2}

This condition is true if the two strings are identical, including the case
of letters.

  or {{cond1}{cond2}...}

This condition is true if any one of the sub-conditions is true.

  and {{cond1}{cond2}...}

This condition is true if all of the sub-conditions are true.


8.4 Expansion variables

The variables that are available for use in expansion strings are:

caller_gid: The group id under which the process that called Exim was
running.

caller_uid: The user id under which the process that called Exim was
running.

compile_date: The date on which the Exim binary was compiled.

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.

domain: When an address is being directed, routed, or a local delivery is
taking place, this variable contains the domain. When a remote delivery is
taking place, if all the addresses that are being handled simultaneously
contain the same domain, then it is placed in the domain variable.
Otherwise this variable is empty. Remote transports should be restricted to
handling only one domain at once if its value is required at transport
time.

home: The forwardfile director sets this variable to the value of the
directory which contains the file (normally the user's home directory)
while processing a filter file. A home directory may also be set during a
local delivery, either by the transport or by the director that handled the
address. When this is the case, the home variable contains its value. When
running a filter test via the -bf option, home is set to the value of the
environment variable HOME.

host: When a local transport is run as a result of routing a remote
address, the expansion variable host is available to access the host that
the router defined. A DNS lookup may set up many hosts; in this case host
refers to the first one. It is expected that this usage will be mainly via
the domainlist router, setting up a single host for batched SMTP output.

local_part: When an address is being directed, routed, or delivered
locally, this variable contains the local part.

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 used is set by
the message_body_visible configuration option; the default is 500.

message_id: When a message is being received or delivered, this variable
contains the message's id.

message_size: When a message is being received or delivered, this variable
contains its size in bytes.

primary_hostname: The value set in the configuration file, or read by the
uname() function.

received_protocol: When a message is being processed, this variable con-
tains the protocol by which it was received.

reply_address: When a message is being processed, this variable contains
the contents of the Reply-to: header if one exists, or otherwise the
contents of the From: header.

return_path: When a message is being delivered, this variable contains the
return path - the sender field that is sent as part of the envelope. In
many cases, this has the same value as sender_address, but if, for example,
an incoming message to a mailing list has been expanded by a director which
specifies a specific address for delivery error messages, then return_path
contains the new errors address, while sender_address contains the original
sender address that was received with the message.

sender_address: When a message is being processed, this variable contains
the sender's address that was received in the message's envelope.

sender_fullhost: When a message has been received from a remote host, this
variable contains the host name and IP address, as a concatenated string,
with the IP address in square brackets. In the case of incoming SMTP
messages, the host name is the data receceived in the HELO or EHLO command.

sender_host_address: When a message has been received from a remote host,
this variable contains the host's IP address.

sender_host_name: When a message has been received from a remote host, this
variable contains the host's name (from the HELO or EHLO command, in the
case of SMTP).

sender_ident: When a message has been 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.

spool_directory: The name of Exim's spool directory.

tod_bsdinbox: The time of day and date, in the format required for BSD-
style mailbox files, for example: Thu Oct 17 17:14:09 1995.

tod_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,
which is: 1995-10-12 15:32:29.

value: This variable contains the result of an expansion lookup operation,
as described above. If used in other circumstances, its contents are null.

version_number: The version number of Exim.


8.5 Expansion string examples

A typical setting for defining a local mailbox to the appendfile trans-
port is

  file = /var/spool/mail/${local_part}

The default setting for the Received header is as follows:

  received_header_text = "Received: \
       ${if def:sender_fullhost {from ${sender_fullhost} \
       ${if def:sender_ident {(${sender_ident})}}\n\t}\
       {${if def:sender_ident {from ${sender_ident} }}}}\
       by ${primary_hostname} \
       ${if def:received_protocol {with ${received_protocol}}} \
       (Exim ${version_number} #${compile_number})\n\t\
       id ${message_id}"



                           9. MAIN CONFIGURATION


The first part of the configuration file contains the main configuration
settings. Each setting occupies one line of the file, except that string
values can be continued onto multiple lines as described in section 6.4.
The available options are as follows:

accept_timeout

    Type:    time
    Default: 0

    This 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 option.

address_file_transport

    Type:    string
    Default: "address_file"

    This sets the name of the transport driver that is to be used when the
    expansion of the local part of an address by an aliasing or forwarding
    director results in a file name.

address_pipe_transport

    Type:    string
    Default: "address_pipe"

    This sets the name of the transport driver that is to be used when the
    expansion of the local part of an address by an aliasing or forwarding
    director results in a pipe command.

address_reply_transport

    Type:    string
    Default: "address_reply"

    This sets the name of the transport driver that is to be used when the
    expansion of the local part of an address by a forwarding director
    results in the generation of an automatic reply.

auto_thaw

    Type:    time
    Default: 0s

    If this option is set to a non-zero time, a new delivery is attempted
    on frozen messages if this much time has passed since the message was
    frozen.

debug_transport

    Type:    string
    Default: unset

    This option can be set only when Exim has been compiled to include the
    debug transport. It causes all deliveries to be subverted by substitut-
    ing a call to the debug transport. This appends information about the
    address, and a copy of the message, to the file whose name is specified
    by this option. No locking is used. When local deliveries are being
    subverted in this way, the file must be set up as writeable by the user
    under whose uid the delivery process will run. It is recommended that
    Exim not be compiled with the debug option as a matter of course.

delay_warning

    Type:    time
    Default: 24h

    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 amount of
    time, no warnings are sent.

delivery_date_remove

    Type:    boolean
    Default: true

    Exim's local transports (appendfile and pipe) 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 outgoing
    messages, and this option causes them to be removed, to avoid any
    problems that might occur when a delivered message is send on to some
    other recipient.

errors_address

    Type:    string
    Default: "postmaster"

    The mail address to which Exim will send certain error reports. As the
    default is specified without a domain, it will be sent to the domain
    specified by the qualify_recipient option. If this address is specified
    with a domain, it must be a fully qualified domain.

errors_copy

    Type:    string
    Default: unset

    Setting this option causes Exim to send bcc copies of delivery failure
    reports to other addresses. The value is a colon-separated list of
    items; each item consists of a pattern and an address list, separated
    by white space. If the pattern matches the recipient of the delivery
    error report, the message is copied to the addresses on the list. For
    example:

      errors_copy = "someuser@mydomain   postmaster@mydomain"

    The pattern can be a single regular expression, indicated by starting
    it with a ^ character; alternatively, either portion (local part,
    domain) can start with an asterisk. A regular expression is matched
    against the entire (fully qualified) recipient; non-regular expressions
    must contain both a local part and domain, separated by @. The address
    list is a string which is expanded, and must end up as a comma-
    separated list of addresses. It is used to construct a Bcc header which
    is added to the error message. The expansion variables local_part and
    domain are set from the original recipient of the error message.

errors_reply_to

    Type:    string
    Default: unset

    Exim's delivery error messages contain the header

      From: Mail Delivery System <Mailer-Daemon@${qualify_domain}>

    (where string expansion notation is used to show a variable substitu-
    tion). Experience shows that a large number of people reply to such
    messages. If the errors_reply_to option is set, a Reply-to header is
    added. The option must specify the complete header body.

exim_group

    Type:    string
    Default: compile-time configured (can be unset)

    This option sets the gid under which Exim runs when it gives up root
    privilege. It 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 40 for a
    discussion of security issues.

exim_path

    Type:    string
    Default: see below

    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 Exim is
    run from some other place.

exim_user

    Type:    string
    Default: compile-time configured (can be unset)

    This option sets the uid under which Exim runs when it gives up root
    privilege. 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. If the resulting uid is the root uid, it has
    the effect of unsetting this option. See chapter 40 for a discussion of
    security issues. Note that the ownership of the runtime configuration
    file is checked against the compile-time setting of this parameter, not
    what is set here.

finduser_retries

    Type:    integer
    Default: 0

    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 dis-
    tinguished from genuine 'not found' errors. If finduser_retries is set
    greater than zero, Exim will try that many times to find a user or a
    group, waiting for one second between tries.

freeze_tell_mailmaster

    Type:    boolean
    Default: false

    On encountering certain errors, Exim freezes a message, which means
    that no further delivery attempts take place until an administrator
    thaws it. If this option is set, a message is sent to errors_address
    every time a message is frozen, unless the message is itself a delivery
    error message. (Without this exception there is the possibility of
    looping.) If several of the message's addresses cause freezing, only a
    single message is sent to the mail administrator. The reason(s) for
    freezing will be found in the message log.

gecos_name

    Type:    string
    Default: unset

    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. Otherwise, gecos_pattern is
    treated as a regular expression that is to be applied to the field, and
    if it matches, gecos_name is expanded and used as the user's 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.

gecos_pattern

    Type:    string
    Default: unset

    See gecos_name above.

local_domains

    Type:    domain-list
    Default: see below

    This specifies a list of domains which are recognized as 'local', that
    is, their final delivery (as far as the Internet is concerned) is
    handled by this MTA. If this option is not set, it defaults to the
    value of qualify_recipient. The name of the local host is not by
    default recognized as a local mail domain; either it must be included
    in local_domains, or the local_domains_include_host option must be set.
    It is possible to specify no local domains by specifying no data for
    this option, for example,

      local_domains =

    If there are very many local domains, then they can be stored in a file
    and looked up whenever this string is searched. See the discussion of
    domain lists in section 6.8.

local_domains_include_host

    Type:    boolean
    Default: false

    If this option is set, the value of primary_hostname is added to the
    value of local_domains. This makes it possible to use the same
    configuration file on a number of different hosts.

log_received_recipients

    Type:    boolean
    Default: false

    When this option is set, the recipients of a message are listed on 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.

message_body_visible

    Type:    integer
    Default: 500

    This option specifies how much of a message's body is to be included in
    the message_body expansion variable.

message_id_header_text

    Type:    string
    Default: 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 an incoming message
    does not have one. The text of this header is required by RFC 822 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 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 constructions like ${tod_log} can be
    used, as the spaces and colons will become hyphens.

message_size_limit

    Type:    integer
    Default: 0

    This option limits the maximum size of message that Exim will process.
    Zero means no limit. It should be set somewhat larger than
    return_size_limit if the latter is non-zero. 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, in the normal way. Rejection
    of an oversized message is logged on both the main and the reject logs.

never_users

    Type:    string-list
    Default: unset

    Local mail deliveries are run in processes that are setuid to the
    recipient. However, it is usually desirable to lock out root from this,
    as a safety precaution. If a message is to be delivered to any of the
    users on the never_users list, the process is run as 'nobody' instead
    (see nobody_user below). A common example is

      never_users = root:daemon:bin:exim

    This option overrides the pipe_as_creator option of the pipe transport
    driver.

nobody_group

    Type:    string
    Default: unset

    This specifies the group to use when a process is to be run as
    'nobody'. If it is unset, the value of the 'nobody' user's default
    group is used.

nobody_user

    Type:    string
    Default: unset

    This specifies the user to use when a process is to be run as 'nobody'.
    If it is unset, Exim looks up the user 'nobody' using getpwnam(). If
    this fails, Exim panics, writing a message to the panic log and exiting
    immediately.

percent_hack_domains

    Type:    domain-list
    Default: unset

    The 'percent hack' is the convention whereby a local part containing a
    percent sign is re-interpreted as a remote address, with the percent
    replaced by @. This is also known as 'source routing', though that term
    is also applied to RFC 822 addresses that begin with an @ character. If
    this option is set, Exim implements the percent facility only for those
    local domains listed. If it is not set, percent can be used for all
    local domains.

preserve_message_logs

    Type:    boolean
    Default: false

    If this option is set, message log files are not deleted when messages
    are completed. Instead, they are moved to a subdirectory of the spool
    directory called msglog.OLD, where they remain available for statisti-
    cal or debugging purposes. This is a dangerous option to set on systems
    with any appreciable volume of mail. Use with care!

primary_hostname

    Type:    string
    Default: see below

    This specifies the name of the current host. This is used in the HELO
    command for outgoing SMTP messages, 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() in order
    to obtain the fully-qualified version.

qualify_domain

    Type:    string
    Default: see below

    This 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 one of the receiver_unqualified or
    sender_unqualified options. If qualify_domain is not set, it defaults
    to the primary_hostname value.

qualify_recipient

    Type:    string
    Default: 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 addresses, unless the
    sending host matches one of the receiver_unqualified or
    sender_unqualified options (see below). If qualify_recipient is not
    set, it defaults to the qualify_domain value.

queue_only

    Type:    boolean
    Default: false

    If queue_only is set (which is equivalent to the -odq command line
    option), a delivery process is not automatically started whenever a
    message has been received. Instead, the message waits on the queue for
    the next queue run. Even if queue_only is false, incoming SMTP messages
    may not get delivered immediately if a lot of them arrive at once - see
    the smtp_accept_queue option.

queue_run_max

    Type:    integer
    Default: 5

    This controls the maximum number of queue-running processes that the
    Exim daemon will run simultaneously. It does not, however, interlock
    with other processes, so additional queue-runners can be started by
    other means, or by killing and restarting the daemon.

queue_smtp

    Type:    boolean
    Default: false

    If queue_smtp is set (which is equivalent to the -odqs command line
    option), a delivery process is started whenever a message has been
    received, but only local deliveries take place. If any SMTP deliveries
    are required, 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.

received_header_text

    Type:    string
    Default: 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, and the default is

      received_header_text = "Received: \
           ${if def:sender_fullhost {from ${sender_fullhost} \
           ${if def:sender_ident {(${sender_ident})}}\n\t}\
           {${if def:sender_ident {from ${sender_ident} }}}}\
           by ${primary_hostname} \
           ${if def:received_protocol {with ${received_protocol}}} \
           (Exim ${version_number} #${compile_number})\n\t\
           id ${message_id}"

    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:

      Received: from scrooge.carol.book [240.1.12.25] (root)
              by marley.carol.book with smtp (Exim 0.25 #9)
              id E0tS3Ga-0005C5-00; Mon, 25 Dec 1995 14:43:44 +0000
      Received: by scrooge.carol.book with local (Exim 0.25 #9)
              id E0tS3GW-0005C2-00; Mon, 25 Dec 1995 14:43:41 +0000

    Note the automatic addition of the date and time in the required
    format.

received_headers_max

    Type:    integer
    Default: 30

    When a message is to be delivered to a remote machine, 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
    a delivery error message is generated.

receiver_try_verify

    Type:    boolean
    Default: false

    See receiver_verify.

receiver_unqualified_hosts

    Type:    domain-list
    Default: unset

    This option lists those hosts from which Exim is prepared to accept
    unqualified receiver addresses. The addresses are made fully qualified
    by the addition of the qualify_recipient value. Typically the hosts are
    local ones, but if you want to imitate the behaviour of mailers that
    accept unqualified addresses from anywhere, specify

      receiver_unqualified_hosts = *

receiver_unqualified_nets

    Type:    net-list
    Default: unset

    This option lists those IP networks from any host on which Exim is
    prepared to accept unqualified receiver addresses. The addresses are
    made fully qualified by the addition of the qualify_domain. Typically
    local networks are specified. This is a more efficient option than
    using a wildcarded partial entry in receiver_unqualified_hosts, because
    no DNS lookup is required.

receiver_verify

    Type:    boolean
    Default: false

    When this option is set, the addresses of recipients received from a
    remote host are verified as they are received. If an address is
    invalid, an incoming SMTP call gets an error response to the RCPT TO
    command. If an address cannot immediately be verified, a temporary
    error code is given. The receiver_try_verify option is less severe: it
    operates in the same way, except that an address is accepted if it
    cannot immediately be verified. Verification failures are logged.

retry_interval_max

    Type:    time
    Default: 24h

    Chapter 27 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.

return_path_remove

    Type:    boolean
    Default: true

    RFC 822 states that the Return-path header is 'added by the final
    transport system that delivers the message to its recipient' (section
    4.3.1), which implies that this header should not be present in
    incoming messages. If this option is true, Return-path headers are
    removed from messages as they are read. Exim's local transports
    (appendfile and pipe) have options for adding Return-path headers at
    the time of local delivery.

return_size_limit

    Type:    int
    Default: 100K

    This option sets limit in bytes on the size of messages that are
    returned to sender. If it is set to zero there is no limit. If the body
    of any message that is to be included in an error 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. The idea is just to save bandwidth on those undeliverable
    15-megabyte messages. If message_size_limit is set, the value of
    return_size_limit should be somewhat smaller.

rfc1413_except_hosts

    Type:    domain-list
    Default: unset

    If this option is set, RFC 1413 identification calls are not made to
    the listed hosts.

rfc1413_except_nets

    Type:    net-list
    Default: unset

    If this option is set, RFC 1413 identification calls are not made to
    any host on the listed networks.

rfc1413_query_timeout

    Type:    time
    Default: 60s

    This sets the timeout on RFC 1413 identification calls. If it is set to
    zero, no RFC 1413 calls are ever made. This is more efficient than
    setting a global pattern in one of the except options.

security

    Type:    string
    Default: see below

    When exim_user is set non-zero in the runtime configuration or an Exim
    uid is compiled into the binary, Exim gives up root privilege for some
    of the time. As there are trade-offs between increased security and
    efficiency, this option is provided to control exactly how this is
    done. The option can be set to one of the strings 'seteuid', 'setuid',
    or 'setuid+seteuid', provided that a uid for Exim is defined. Otherwise
    it must be left unset. A full description of what these values mean is
    given in chapter 40. The default for this option is unset if no special
    Exim uid is defined, otherwise it is either 'setuid+seteuid' or
    'setuid', depending on whether the seteuid() function is configured as
    being available or not.

sender_host_accept

    Type:    domain-list
    Default: unset

    If this option is set, incoming SMTP calls are accepted only from the
    hosts listed, possibly also qualified by an RFC 1413 identification.
    (Calls from networks listed in sender_net_accept are also accepted.)
    However, if a call arrives from a host (and identification) which is
    also listed in sender_host_reject or from a network listed in
    sender_net_reject, the call is rejected. Chapter 39 contains details of
    this facility; see also sender_reject.

sender_host_reject

    Type:    domain-list
    Default: unset

    If this option is set, incoming SMTP calls from the hosts listed,
    possibly also qualified by an RFC 1413 identification, are rejected.
    Chapter 39 contains details of this facility.

sender_net_accept

    Type:    net-list
    Default: unset

    If this option is set, incoming SMTP calls are accepted only from the
    IP networks specified (and from any hosts listed in
    sender_host_accept). However, if a call arrives from a host (and
    identification) which is also listed in sender_host_reject or from a
    network listed in sender_net_reject, the call is rejected. Chapter 39
    contains details of this facility; see also sender_reject.

sender_net_reject

    Type:    net-list
    Default: unset

    If this option is set, incoming SMTP calls from the listed networks are
    rejected. Chapter 39 contains details of this facility.

sender_reject

    Type:    string
    Default: unset

    This option can be set in order to reject mail from certain senders.
    This should be used only after due consideration, but can be of use
    against spammers; I've provided this facility as a result of some real
    incidents. The check is done on the sender's address as given in the
    MAIL FROM command in SMTP, but not for local senders where the logged-
    in user's address is going to override anyway. The check is not done
    for batch SMTP input. The value of the option is a colon-separated list
    of strings. If a string starts with ^ then a regular expression match
    is done against the sender's address. Otherwise, if there is no @ in
    the string, it is matched against the sender's domain for all local
    parts. If there is an @ in the string, then the local part is first
    compared. It may start with an asterisk. If the local parts match, then
    the domains are compared in exactly the same way as entries in domain
    lists (see section 6.8) are compared. So a typical example might be:

      sender_reject = "spamuser@some.domain:spam.domain"

    Note that this check operates on sender domains independently of the
    sending host; sender_reject_hosts and sender_reject_nets can be used to
    block all mail from particular hosts or nets.

sender_try_verify

    Type:    boolean
    Default: false

    See sender_verify.

sender_unqualified_hosts

    Type:    domain-list
    Default: unset

    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 the qualify_domain. Typically the hosts are local ones,
    but if you want to imitate the behaviour of mailers that accept
    unqualified addresses from anywhere, specify

      sender_unqualified_hosts = *

sender_unqualified_nets

    Type:    net-list
    Default: unset

    This option lists those IP networks from any host on which Exim is
    prepared to accept unqualified sender addresses. The addresses are made
    fully qualified by the addition of the qualify_domain. Typically local
    networks are specified. This is a more efficient option than using a
    wildcarded partial entry in sender_unqualified_hosts, because no DNS
    lookup is required.

sender_verify

    Type:    boolean
    Default: false

    If this option is true, the envelope sender addresses on incoming SMTP
    messages are checked to ensure that they are valid. Messages with
    invalid envelope senders are rejected with a permanent error code if
    sender_verify_reject is set (the default). Otherwise a warning is
    logged. See chapter 39 for details. If a sender cannot immediately be
    verified, a temporary error code is returned. The sender_try_verify
    option is less severe: it operates in exactly the same way as
    sender_verify except that if an address cannot immediately be verified,
    it is accepted instead of being temporarily rejected.

sender_verify_except_hosts

    Type:    domain-list
    Default: unset

    If sender_verify is true, this option specifies a list of hosts and RFC
    1413 identifications which are exempt from sender verification. See
    chapter 39 for details.

sender_verify_except_nets

    Type:    net-list
    Default: unset

    If sender_verify is true, this option specifies a list of IP networks
    which are exempt from sender checking. See chapter 39 for details.

sender_verify_fixup

    Type:    boolean
    Default: false

    Experience shows that many messages are sent out onto the Internet with
    invalid sender addresses in the envelopes (i.e. in the MAIL FROM
    command of the SMTP dialogue), but with valid addresses in the Sender,
    From, or Reply-to header fields. If sender_verify is true and this
    option is also true, an invalid envelope sender is replaced by a valid
    value from the headers. See chapter 39 for details.

sender_verify_log_details

    Type:    boolean
    Default: false

    Setting this option causes additional information about sender verifi-
    cation to be written to the reject log. It is intended to help sort out
    problems concerned with sender verification.

sender_verify_reject

    Type:    boolean
    Default: true

    When this is set, a message is rejected if sender verification fails.
    If it is not set, a warning message is written to the main and reject
    logs, and the message is accepted (unless some other error occurs).

smtp_accept_max

    Type:    integer
    Default: 20

    This 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. On some operating
    systems at busy times the SIGCHLD signal that Exim uses to keep count
    of its subprocesses can get lost. If an Exim daemon appears not to be
    accepting as many calls as it should, sending it a SIGCHLD signal
    should cause it to notice all its subprocesses that have completed.

smtp_accept_queue

    Type:    integer
    Default: 0

    If the number of simultaneous incoming SMTP calls handled via the
    listening daemon exceeds this value, then messages received are simply
    placed on the queue, and no delivery processes are started automati-
    cally. 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 the queue_smtp option and the various -od
    command line options.

smtp_accept_reserve

    Type:    integer
    Default: 0

    When smtp_accept_max is set greater than zero, this option specifies a
    number of SMTP connections that are reserved for connections from
    specific hosts or networks. For example, if smtp_accept_max is set to
    50 and smtp_accept_reserve is set to 5, then once there are 45 active
    connections, new ones are accepted only from hosts listed in
    smtp_reserve_hosts or from networks listed in smtp_reserve_nets.

smtp_banner

    Type:    string
    Default: see below

    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:

      smtp_banner = "${primary_hostname} Exim ${version_number} \
        #${compile_number} ready at ${tod_full}"

    Failure to expand the string causes a panic error.

smtp_connect_backlog

    Type:    integer
    Default: 5

    This 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.

smtp_receive_timeout

    Type:    time
    Default: 5m

    This sets a timeout value for SMTP reception. 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 abandoned.

smtp_reserve_hosts

    Type:    domain-list
    Default: unset

    This option lists hosts for which SMTP connections are reserved; see
    smtp_accept_reserve above.

smtp_reserve_nets

    Type:    net-list
    Default: unset

    This option lists IP networks for which SMTP connections are reserved;
    see smtp_accept_reserve above.

smtp_verify

    Type:    boolean
    Default: false

    If this option is true, the SMTP command VRFY is supported on incoming
    SMTP connections; otherwise it is not.

spool_directory

    Type:    string
    Default: see below

    The default value is taken from the compile-time configuration setting.
    This option makes it possible to run testing versions of Exim without
    using the standard spool.

trusted_groups

    Type:    string-list
    Default: unset

    If this option is set, then any process that is running in one of the
    listed groups may pass a message to Exim and specify the sender's
    address using the -f command line option, without Exim's adding a
    Sender header. If neither trusted_groups nor trusted_users is set, then
    only root and the Exim user can do this.

trusted_users

    Type:    string-list
    Default: unset

    If this option is set, then any process that is running as one of the
    listed users may pass a message to Exim and specify the sender's
    address using the -f command line option, without Exim's adding a
    Sender header. If neither trusted_users nor trusted_groups is set, then
    only root and the Exim user can do this.

unknown_login

    Type:    string
    Default: 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.

unknown_username

    Type:    string
    Default: unset

    See unknown_login.



                         10. DRIVER SPECIFICATIONS


The second, third, and fourth parts of Exim's configuration file specify
which transport, director, and router drivers are to be used, respectively.
The format of the entries is the same in each case, and is as follows:

  <name:>
    <generic option>,
    ...
    <generic option>;
    <private option>,
    ...
    <private option>

The name identifies a particular instance of a driver; the same driver code
can be used more than once, with different instance names and different
option settings each time. Comment lines may appear in the middle of driver
specifications. The full set of option values set for any particular driver
instance, including all the defaults, can be extracted by making use of the
-bP command line option (see chapter 5).

The generic options are those that apply to all drivers of the same type
(i.e. all directors, or all routers, or all transports). Note that a comma
is used to terminate each option, and a semicolon is used to terminate the
list of generic options. There is always at least one generic option,
giving the name of the underlying driver. The private options are particu-
lar to each driver, and none need appear. A comma is used to separate them.

The order of driver specifications in the configuration file matters for
the directors and the routers, since an address is passed to each of them
in turn until one is able to handle it. The order of transport specifi-
cations does not matter.

Subsequent chapters describe the generic options for each type of driver,
followed by descriptions of each of the available drivers of each type.



                       11. GENERIC TRANSPORT OPTIONS


There is only one generic option for transports.

driver

    Type:    string
    Default: unset

    This specifies which of the available drivers is to be used. For
    example:

      driver = smtp;

    There is no default, and this option must be set for all transports.



                        12. THE APPENDFILE TRANSPORT


The appendfile transport delivers a message by appending it to a file in
the local filing system. It is typically used for local deliveries to
users' mailboxes, and also for copying messages to files whose names are
obtained from alias or forwarding expansions. Appendfile can also be used
as a pseudo-remote transport for putting messages into files for remote
delivery by some means other than Exim.

As appendfile is a local transport, it is always run in a separate process,
under a non-privileged uid and gid, which are set by setuid(). In the
common local delivery case, these are the uid and gid belonging to the user
to whom the mail is being delivered.

If the transport fails for any reason, the message remains on the input
queue so that there can be another delivery attempt later. After most
errors, except those that occur while actually writing to the file, the
message is frozen for human attention. If there is an error while writing
to the file (e.g. quota exceeded, partition filled), Exim attempts to reset
the file's length and last modification time back to what they were before.

Before writing to the 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, which are as follows:

bsmtp

    Type:    string
    Default: "none"

    This option is used to set up an appendfile transport as a pseudo-
    remote transport for delivering messages into local files in batch SMTP
    format for onward transmission by some non-Exim means. The value of the
    option must be one of the strings 'none', 'one', 'domain', or 'all'.
    The first of these turns the feature off. A full description of the
    batch SMTP mechanism is given in chapter 39.

check_group

    Type:    boolean
    Default: false

    The group owner of the file is checked only when this option is set.
    The default setting is unset because the default file mode is 0600,
    which means that the group is irrelevant.

create_directory

    Type:    boolean
    Default: true

    See the directory option below.

create_file

    Type:    string
    Default: anywhere

    This option constrains the location of files that are created by this
    transport. It 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 up for the address by the director that handled it. This
    option isn't useful when an explicit file name is given for normal
    mailbox deliveries; it is intended for the case when file names have
    been generated from user's .forward files, which are usually handled by
    an appendfile transport called address_file. See also file_must_exist.

delivery_date_add

    Type:    boolean
    Default: true

    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 incoming messages, so that delivered mess-
    ages can safely be resent to other recipients.

directory

    Type:    string
    Default: unset

    This option is mutually exclusive with the file option. If directory is
    set, the message is delivered into a new file in the given directory
    (whose name is expanded), instead of being appended to a single mailbox
    file. The file names created in the directory all start with the letter
    'q' for compatibility with smail. Messages are written using a tempor-
    ary name, and then renamed when complete. For example, when delivering
    messages into files using the bsmtp option (see section 39.6 for more
    details) a setting such as

      directory = /var/bsmtp/${host}

    might be used. If the create_directory option is set (the default), an
    attempt is made to create the directory if it does not exist; if it is
    created then its mode is given by the directory_mode option. If
    creation fails, or if the create_directory option is not set, then the
    delivery is just deferred. No locking is performed while writing the
    message, as each delivery creates a new file, so the various locking
    options of the transport are ignored.

directory_mode

    Type:    integer
    Default: 0700

    See the directory option above.

file

    Type:    string
    Default: unset

    This option need not be set when appendfile is being used to deliver to
    files whose names are obtained from forwarding or aliasing address
    expansions (usually under the instance name address_file). In other
    cases, the option must be set unless the directory option is set. The
    string is expanded for each delivery, and must yield an absolute path.
    If the expansion contains a reference to the local_part variable, this
    is checked to ensure that it does not contain a '/' character - to
    prevent an unexpected change of directory. The most common settings of
    this option are variations on one of these examples:

      file = /var/spool/mail/${local_part}
      file = /home/${local_part}/inbox

    If there is no file name, or the expansion fails, or a local part
    contains a '/' character, a delivery error occurs.

file_must_exist

    Type:    boolean
    Default: false

    If this option is true, the file specified by the file option must
    exist, and an error occurs if it does not.

from_hack

    Type:    boolean
    Default: true

    If this option is true, lines in the body of the message that start
    with the string 'From ' are modified by adding the character '>' at
    their start. This is necessary for traditional BSD-format mailboxes,
    where such lines might otherwise indicate the start of a new message.

group

    Type:    string
    Default: unset

    If this option is set, it specifies the group under whose gid the
    delivery process is to be run. If it is not set, a value associated
    with a user may be used (see below); otherwise a value must have been
    associated with the address by the director which handled it. If the
    string contains no $ characters, it is resolved when Exim starts up.
    Otherwise, the string is expanded at the time the transport is run, and
    must yield either a digit string or a name which can be looked up using
    getgrnam().

lock_interval

    Type:    time
    Default: 3s

    This specifies the time to wait between attempts to lock the file.

lock_retries

    Type:    integer
    Default: 5

    This specifies the maximum number of attempts to lock the file.

lockfile_mode

    Type:    integer
    Default: 0600

    This specifies the mode of the created lock file, when a lock file is
    being used (see use_lockfile).

lockfile_timeout

    Type:    time
    Default: 30m

    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.

mode

    Type:    integer
    Default: 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.

notify_comsat

    Type:    boolean
    Default: 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.

prefix

    Type:    string
    Default: see below

    The string specified here is expanded and output at the start of every
    message. The default is

      prefix = "From ${return_path} ${tod_bsdinbox}\n"

require_lockfile

    Type:    boolean
    Default: true

    When a lock file is being used (see use_lockfile) and require_lockfile
    is true, a lock file must be created before delivery can proceed. If
    the option is not true, failure to create a lock file is not treated as
    an error, though failure of the fcntl() locking function is.

return_path_add

    Type:    boolean
    Default: true

    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 822 states that the Return-path header is 'added by the final
    transport system that delivers the message to its recipient' (section
    4.3.1), which 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.

suffix

    Type:    string
    Default: "\n"

    The string specified here is expanded and output at the end of every
    message.

use_lockfile

    Type:    boolean
    Default: true

    If this option is turned off, Exim does not attempt to create a lock
    file when appending to a file. Thus 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. See also the require_lockfile option.

user

    Type:    string
    Default: unset

    If this option is set, it specifies the user under whose uid the
    delivery process is to be run. If it is not set, a value must have been
    associated with the address by the director that handled it. If the
    string contains no $ characters, it is resolved when Exim starts up.
    Otherwise, the string is expanded at the time the transport is run, and
    must yield either a digit string or a name which can be looked up using
    getpwnam(). When getpwnam() is used, either at start-up time or later,
    the group id value associated with the user is taken as the value to be
    used if the group option is not set.

Before writing to a file, Exim proceeds as follows:

 .   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 incorrect, delivery is deferred, and the message is frozen.

 .   If the file's permissions are more generous than specified, they are
     reduced. If they are insufficient, delivery is deferred, and the
     message is frozen.

 .   The file's inode number is saved, and it is then opened for appending.
     If this fails because the file has vanished, behave as if it hadn't
     existed (see below). If the open failure was EWOULDBLOCK, just defer
     delivery; otherwise defer and freeze the message.

 .   If the file was 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 and
     freeze the message.

 .   If the file did not exist originally, open it for writing as a new
     file (with the O_EXCL and O_CREAT options). If this 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.

 .   If the open failed with the EWOULDBLOCK error, just defer delivery;
     otherwise freeze the message for any other opening error.

Once the file is open, it is locked. If use_lockfile is set, a lock file is
built in a way that will work over NFS, and then a fcntl() locking call is
also used. Building the lock file proceeds as follows:

 .   Create a 'hitching post' file whose name is that of the lock file with
     the current time and process id added, by opening for writing as a new
     file. If this fails with an access error, the message is frozen unless
     the option not to use lock files is set. It if fails for any other
     reason, delivery is deferred.

 .   Close the hitching post file, and hard link it to the lock file name,
     ignoring failure.

 .   Use the stat() command to get information about the hitching post
     file, and then delete (unlink) the name of the hitching post file.

 .   Examine the saved information about the file. The number of links must
     be exactly two for the locking to have succeeded.

System crashes cause lock files to get left lying around. Since any program
that writes to a mailbox should complete its task very quickly, it is
reasonable to time out old lock files. The timeout period is an option of
the transport, as is the number of locking retries.



                        13. THE 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,
usually as the result of mail filtering. A traditional 'vacation' message
is the standard example.

Autoreply is implemented as a local transport so that it runs under the uid
and gid of the local user. The parameters of the message to be sent can be
specified in the configuration by the options described below, but in the
common case when autoreply is activated as a result of filtering, none of
them are normally set, because all the information is obtained from the
filter file.

In an attempt to reduce the possibility of message cascades, messages
created by the autoreply transport always take form of delivery error
messages. That is, the envelope sender field is empty.

There is a subtle difference between directing a message to a pipe
transport that generates some text to be returned to the sender, and
directing 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, while if autoreply is
used, a separate message is generated for each address passed to it.

The private options of the autoreply transport are used only when the
address passed to it does not contain any reply information. Thus all the
information comes either from the director or the transport; it is never
mixed.

bcc

    Type:    string
    Default: unset

    Specifies the addresses that are to receive 'blind carbon copies' of
    the message.

cc

    Type:    string
    Default: unset

    Specifies recipients of the message and the contents of the Cc header.

file

    Type:    string
    Default: unset

    The contents of the file are sent as the body of the message. If both
    file and text are set, the text string comes first.

file_expand

    Type:    boolean
    Default: 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.

file_optional

    Type:    boolean
    Default: false

    If this option is true, no error is generated if the file named by the
    file option does not exist or cannot be read.

from

    Type:    string
    Default: unset

    The contents of the From header.

group

    Type:    string
    Default: unset

    If this option is set, it specifies the group under whose gid the
    delivery process is to be run. If it is not set, a value associated
    with a user may be used (see below); otherwise a value must have been
    associated with the address by the director which handled it. If the
    string contains no $ characters, it is resolved when Exim starts up.
    Otherwise, the string is expanded at the time the transport is run, and
    must yield either a digit string or a name which can be looked up using
    getgrnam().

headers

    Type:    string
    Default: unset

    Specified additional RFC 822 headers that are to be added to the
    message. Several can be given by using \n to separate them. There is no
    check on the format.

log

    Type:    string
    Default: unset

    This option names a file in which a record of every message sent is
    logged.

mode

    Type:    integer
    Default: 0600

    If either the log file or the 'once' file has to be created, this mode
    is used.

once

    Type:    string
    Default: unset

    This option names a DBM database in which a record of each recipient is
    kept. If a potential recipient is already in the database, no message
    is sent.

return_message

    Type:    boolean
    Default: 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
    general configuration option.

subject

    Type:    string
    Default: unset

    The contents of the Subject header.

text

    Type:    string
    Default: unset

    This specifies a single string to be used as the body of the message.
    If both text and file are set, the text comes first.

to

    Type:    string
    Default: unset

    Specifies recipients of the message and the contents of the To header.

user

    Type:    string
    Default: unset

    If this option is set, it specifies the user under whose uid the
    delivery process is to be run. If it is not set, a value must have been
    associated with the address by the director that handled it. If the
    string contains no $ characters, it is resolved when Exim starts up.
    Otherwise, the string is expanded at the time the transport is run, and
    must yield either a digit string or a name which can be looked up using
    getpwnam(). When getpwnam() is used, either at start-up time or later,
    the group id value associated with the user is taken as the value to be
    used if the group option is not set.



                          14. THE DEBUG TRANSPORT


The debug transport is provided for debugging purposes only. It has no
options and is not normally referenced in a configuration file. It is
recommended that Exim normally be built without including this code.

The debug transport is used when the configuration option debug_transport
is set. It gets called instead of the real transport for all deliveries,
both local and remote, so no real mail delivery takes place. Instead, the
debug transport appends information about the message and a copy of the
message itself to the file named by the debug_transport option. No locking
is used.

The file must be writeable by Exim at the time of delivery. For intercepted
local deliveries this means it must be writeable by the relevant user,
while for intercepted remoted deliveries it must be writeable by the Exim
user, if one is defined.



                           15. THE PIPE TRANSPORT


The pipe transport is used to deliver messages via a pipe to a command
running in another process. This can happen when an address is expanded via
an alias or forward file, or when a director explicitly directs the message
to a pipe. The pipe transport can also be used as a pseudo-remote transport
for passing messages for remote delivery by some means other than Exim.

As pipe is a local transport, it is always run in a separate process,
normally under a non-privileged uid and gid. In the common case, these are
the uid and gid belonging to the user whose .forward file directed the
message at a pipe. However, in other cases the uid and gid may be specified
explicitly.

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
success is always assumed, or the return code is 75, which is interpreted
as meaning 'try again later'. The value 75 is taken from the definition of
EX_TEMPFAIL in sysexits.h on a number of systems. The return_output option
can also affect the result of a pipe delivery.

The command is run directly from Exim, which itself breaks up the command    |
line into separate arguments. It is done this way to minimize 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. Unquoted arguments are         |
delimited by white space; in quoted arguments, backslash is interpreted an   |
escape character in the usual way.                                           |
                                                                             |
String expansion is applied to the command line except when it comes from a  |
traditional .forward file (i.e. not a filter file). The expansion is         |
applied to each argument in turn rather than to the whole line. Thus the     |
number of arguments cannot be changed by the result of string expansion,     |
and quotes or backslashes in inserted variables do not interact with         |
external quoting.                                                            |
                                                                             |
The restrict_to_path option can be used to restrict which commands may be    |
run. The following environment variables are set up when the command is      |
invoked:                                                                     |

  DOMAIN               the local domain of the address
  HOME                 the 'home' directory
  HOST                 the host name when called from a router
  LOCAL_PART           see below
  LOGNAME              see below
  MESSAGE_ID           the message's id
  PATH                 as specified by the path option below
  QUALIFY_DOMAIN       the configured qualification domain
  SENDER               the sender of the message
  SHELL                /bin/sh
  USER                 see below

When a pipe transport is called directly from (for example) a smartuser
director, then 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. LOGNAME and USER are set
to the same value as LOCAL_PART for compatibility with other MTAs.

HOST is set only when a pipe transport is called from a router as a pseudo-
remote transport (e.g. for handling batched SMTP). It is set to the first
host name specified by the router (if any).

The value of the HOME environment variable is set as follows: If the
transport's directory option is set, then its value is used. Otherwise,
certain directors may set the value:

 .   The localuser director sets the value for the user's home directory
     obtained from the getpwnam() function.

 .   The forwardfile director sets the value of its directory option, if
     given, or the value obtained for the home directory from getpwnam() if
     it checked for a local user.

 .   The aliasfile director sets the value of its directory option.

The string is expanded before use, and as well as using it for the value of
HOME, Exim makes it the current directory before running the command. If it  |
cannot be made the current directory, delivery of the message is deferred.   |

The private options of the pipe transport are as follows:

bsmtp

    Type:    string
    Default: "none"

    This option is used to set up a pipe transport as a pseudo-remote
    transport for delivering messages in batch SMTP format for onward
    transmission by some non-Exim means. The value of the option must be
    one of the strings 'none', 'one', 'domain', or 'all'. The first of
    these turns the feature off. A full description of the batch SMTP
    mechanism is given in chapter 39.

command

    Type:    string
    Default: unset

    This option need not be set when pipe is being used to deliver to pipes
    obtained from address expansions (usually under the instance name
    address_pipe). 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.                                |

delivery_date_add

    Type:    boolean
    Default: true

    If this option is true, a Delivery-date header is added to the message.
    This gives the actual time the delivery was made.

directory

    Type:    string
    Default: unset

    If this option is set, its expanded value is used to set the current
    directory and the HOME environment variable before running the command.

from_hack

    Type:    boolean
    Default: false

    If this option is true, lines in the body of the message that start
    with the string 'From ' are modified by adding the character '>' at
    their start. This is necessary for traditional BSD-format mailboxes,
    where such lines might otherwise indicate the start of a new message.

group

    Type:    string
    Default: unset

    If this option is set, it specifies the group under whose gid the
    delivery process is to be run. If it is not set, a value associated
    with a user may be used (see below); otherwise a value must have been
    associated with the address by the director which handled it. If the
    string contains no $ characters, it is resolved when Exim starts up.
    Otherwise, the string is expanded at the time the transport is run, and
    must yield either a digit string or a name which can be looked up using
    getgrnam().

ignore_status

    Type:    boolean
    Default: false

    If this option is true, the status returned by the subprocess that is
    set up to run the command is ignored. Otherwise, a non-zero status
    causes an error return from the transport.

max_output

    Type:    integer
    Default: 20K

    This specifies the maximum amount of output that the command may
    produce on its standard output. 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 whether the return_output
    option is set or not. Because of buffering effects, the amount of
    output may exceed the limit by a small amount before Exim notices.

path

    Type:    string
    Default: "/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.

pipe_as_creator

    Type:    boolean
    Default: false

    If user is not set and this option is true, then 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
    group option above, or by the director that processed the address),
    then the gid that was in force when Exim was originally called to
    accept the message is used. Setting this option may be necessary in
    order to get some free-standing local delivery agents to work cor-
    rectly. Note, however, that the never_users configuration option
    overrides.

prefix

    Type:    string
    Default: see below

    The string specified here is expanded and output at the start of every
    message. The default is the same as for the appendfile transport,
    namely

      prefix = "From ${return_path} ${tod_bsdinbox}\n"

    This is required by the commonly-used /usr/ucb/vacation program.

restrict_to_path

    Type:    boolean
    Default: false

    When this option is set, the command name must contain no slashes. It
    is searched for in the directories listed in the path option, and run
    directly, not under /bin/sh. This option isn't much use if the command
    option is set explicitly. It is intended for the case when a pipe
    command has been generated from user's .forward file. This is usually
    handled by an pipe transport called address_pipe.

return_output

    Type:    boolean
    Default: false

    If this option is true, and the command produced any standard output,
    the delivery is deemed to have failed, and the output is returned in
    the delivery error message. This facility can be used, for example, to
    return information to the senders of messages addressed to non-existent
    users.

return_path_add

    Type:    boolean
    Default: false

    If this option is true, a Return-path header is added to the message.

suffix

    Type:    string
    Default: "\n"

    The string specified here is expanded and output at the end of every
    message. The default is the same as for the appendfile transport.

umask

    Type:    integer
    Default: 022

    This specifies the umask setting for the subprocess that runs the
    command.

user

    Type:    string
    Default: unset

    If this option is set, it specifies the user under whose uid the
    delivery process is to be run. If it is not set, a value must have been
    associated with the address by the director that handled it. If the
    string contains no $ characters, it is resolved when Exim starts up.
    Otherwise, the string is expanded at the time the transport is run, and
    must yield either a digit string or a name which can be looked up using
    getpwnam(). When getpwnam() is used, either at start-up time or later,
    the group id value associated with the user is taken as the value to be
    used if the group option is not set.

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. Typically one wants this to be a uid that is trusted by the
delivery agent to supply the correct sender of the message. The following
is an example transport and director configuration for procmail:

  procmail_pipe:
    driver = pipe;
    command = "/opt/local/bin/procmail -d ${local_part}",
    from_hack,
    user = exim

  procmail:
    driver = localuser,
    transport = procmail_pipe;

In this example, the pipe is run as the user exim, assuming that procmail
trusts that user.



                           16. THE SMTP TRANSPORT


The smtp transport delivers messages over TCP/IP connections using the SMTP
protocol. The list of alternative hosts can either be taken from the
address that is being processed, or specified explicitly for the transport.
Timeout and retry processing (see chapter 27) is applied to each IP address
independently. The private options are as follows:

batch_max

    Type:    integer
    Default: 0

    This controls the maximum number of deliveries that can take place over
    a single TCP/IP connection. If the value is zero, there is no limit.

    When a message has been successfully delivered over a TCP/IP connec-
    tion, 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 create yet
    another process. Each time this happens, a sequence counter is
    incremented, and if it ever gets to the (non-zero) batch_max value, no
    further messages are sent on the same TCP/IP connection.

command_timeout

    Type:    time
    Default: 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.

data_timeout

    Type:    time
    Default: 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.

delay_after_cutoff

    Type:    boolean
    Default: 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, then 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 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.

dns_qualify_single

    Type:    boolean
    Default: true

    If the hosts option is being used and names are being looked up in the
    DNS, then the option to cause the resolver to qualify single-component
    names with the local domain is set.

dns_search_parents

    Type:    boolean
    Default: true

    If the hosts option is being used and names are being looked up in the
    DNS, then the option to cause the resolver to search parent domains is
    set.

final_timeout

    Type:    time
    Default: 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.

gethostbyname

    Type:    boolean
    Default: false

    If this option is true when the hosts option is being used, names are
    looked up using gethostbyname() instead of using the DNS. Of course,
    gethostbyname() may in fact use the DNS, but it does not do any MX
    processing.

hosts

    Type:    string-list
    Default: unset

    This option specifies a list of host names and/or IP addresses which
    are used if the address being processed does not have any hosts
    associated with it. The string is first expanded, before being
    interpreted as a colon-separated host list. The names are looked up
    either in the DNS or using gethostbyname(), depending on the other
    options. This option is typically used in association with a smartuser
    director or a domainlist router that wants to direct messages to a
    particular host or hosts. The given hosts are tried in order, subject
    to their retry status. This option is ignored when the address has been
    routed by the lookuphost router. Instead, the host list supplied by
    that router is used.

multi_domain

    Type:    boolean
    Default: 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 once. 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.

mx_domains

    Type:    domain-list
    Default: unset

    If the hosts option is being used and names are being looked up in the
    DNS, then if the host name is in this list but not in non_mx_domains,
    it is required to have an MX record.

non_mx_domains

    Type:    domain-list
    Default: unset

    See mx_domains above.

service

    Type:    string
    Default: "smtp"

    This option specifies the TCP/IP port that is used to send the message.
    If it begins with a digit it is taken as a port number; otherwise it is
    looked up using getservbyname().



                        17. GENERIC DIRECTOR OPTIONS


The following generic options apply to all directors.

domains

    Type:    domain-list
    Default: unset

    If this option is set, then the director is skipped unless the current
    domain matches one of the entries in the list.

driver

    Type:    string
    Default: unset

    This option must always be set. It specifies the name of the director
    driver.

fail_verify

    Type:    boolean
    Default: false

    If this option is true and an address is accepted by this director when
    verifying, then verification fails. This option has no effect if the
    verify option is false.

more

    Type:    boolean
    Default: true

    If this option is false, then if the director fails to match a local
    part, no further directors are tried, and direction fails. This applies
    even in the case of address verification where the director was not run
    because the verify option was off.

prefix

    Type:    string
    Default: unset

    If this option is set, then the director is skipped unless the local
    part starts with the given string, or the prefix_optional option is
    true. While direction is happening, the prefix is removed from the
    local part. This facility is commonly used to handle local parts of the
    form request-something. If both prefix and suffix are set, both
    conditions must be met.

prefix_optional

    Type:    boolean
    Default: false

    See prefix above.

require_files

    Type:    stringlist
    Default: unset

    The value of this option is first expanded and then interpreted as a
    colon-separated list of strings. 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 director is skipped if any paths not preceded by '!' do not exist,
    or if any paths preceded by '!' do exist. This provides a general
    mechanism for predicating the running of a director on the existence or
    non-existence of certain files or directories. A failure to expand the
    string, or the presence of a non-fully-qualified path within it causes
    a panic error.

suffix

    Type:    string
    Default: unset

    If this option is set, then the director is skipped unless the local
    part ends with the given string, or the suffix_optional option is true.
    While direction is happening, the suffix is removed from the local
    part. This facility is commonly used to handle local parts of the form
    something-request. If both prefix and suffix are set, both conditions
    must be met.

suffix_optional

    Type:    boolean
    Default: false

    See suffix above.

transport

    Type:    string
    Default: unset

    The string must be the name of a configured transport instance. For
    some directors a transport does not make sense, and in those cases it
    is a configuration error to supply one.

verify

    Type:    boolean
    Default: true

    If this option is false, then this director is skipped when verifying
    addresses. It is usual to set it false for instances of the smartuser
    director. See also the fail_verify option above.

Six of the generic options (domains, more, prefix, require_files, suffix,
and verify) can cause directors to be skipped for a particular local parts.
They interact with each other in the following way:

If the domains option is set for a director and the domain of the current
address does not match any of the given domains, then the director is
skipped and the next one is tried. None of the other options is inspected.
Otherwise, if the more option is not set, no subsequent directors are
called, in any circumstances. The current director is called unless

 .   Verification is happening and its verify option is turned off, or

 .   There is a prefix or suffix mismatch, or

 .   The existence or non-existence of files listed in the require_files
     option is not as expected.

The verify and fail_verify options make it possible to separate those local
parts which correspond to a real local delivery from those which are
recognized, but which do something else if actually encountered in a
message.

For example, a smartuser director might be used to pass all unrecognized
local parts to a script that tries to generate a helpful error message, or
to a different machine that might be able to handle them. This means that
no local part will ever cause a delivery failure. However, if (for example)
verification of senders is taking place (the sender_verify option), you
probably don't want <random-local-part@your.domain> to be accepted. The
solution is to set no_verify on the smartuser director.

On our systems in Cambridge we keep a list of users whose accounts have
been cancelled, and their mail is piped to a script which sends back a more
helpful message than 'user unknown'. Verification of such local parts
should fail, but just setting no_verify on the director doesn't work,
because the local part is then passed to a localuser director that may
still find it in the password file. (Initially, cancellation just resets
the password.) This is the sort of case for which fail_verify was invented.
It makes it possible to fail an explicit list of local parts.



                         18. THE ALIASFILE DIRECTOR


The aliasfile director expands local parts by consulting a file of aliases.
The file can be a text file that is searched linearly, or it may be a DBM
direct-access database, or it can be a NIS map. The case of letters is not
significant in searches. The exim_dbmbuild utility can be used to convert a
text file into a DBM database; the keys are lower-cased by this process.

A textual alias file consists of entries that start with the alias name,
terminated by a colon. The remainder of the entry consists of a list of
addresses which can be continued onto several lines by starting each of the
continuation lines with white space. The addresses are separated by commas
or newlines. Lines starting with a # character are comments, and are
ignored, and # may also appear in a white space position, in which case
everything between # and the end of the line is ignored.

Instead of an address, an item of the form

  :include:<path name>

may appear, in which case an list of addresses is taken from the given file
and included at that point.

If any error is detected while generating the list of new addresses, the
message is frozen, except for the special case of inability to open an
included file, when no_freeze_missing_include is set. In this case,
delivery is simply deferred.

If a transport is specified for this director, then the message is directed
to that transport for any local part which is found in the file, any data
in the file that is associated with the local part being ignored. Thus the
same processing can be done for any local part that is listed in the file.
For example, a file containing a list of cancelled users can be used to
directed messages addressed to them to a particular script.


directory

    Type:    string
    Default: unset

    If a local part is expanded by this director into a delivery to a pipe,
    and the transport's directory option is not set, then the value of this
    option is used for the current directory and the value of HOME while
    running the pipe. The string is expanded before use.

errors_to

    Type:    string
    Default: unset

    Delivery errors for any addresses generated by this director are sent
    to this address, if it is set and if it verifies as valid. Otherwise
    the address associated with the incoming address (normally the sender)
    are used. A typical use might be

      errors_to = "aliasmaster"

file

    Type:    string
    Default: unset

    This option specifies the name of the alias file. It must always be
    set; if it does not, an error occurs. The string is expanded before
    use; if expansion fails, Exim panics. The resulting string must be an
    absolute path. If the original string does not start with '/' or '$',
    Exim gives a configuration error when it starts up; otherwise, if an
    expanded string does not begin with '/' delivery is frozen.

forbid_file

    Type:    boolean
    Default: false

    If this option is true, then this director may not generate a new
    address which specifies delivery to a local file. If it attempts to do
    so, a delivery failure occurs.

forbid_pipe

    Type:    boolean
    Default: false

    If this option is true, then this director may not generate a new
    address which specifies delivery to a pipe. If it attempts to do so, a
    delivery failure occurs.

freeze_missing_include

    Type:    boolean
    Default: true

    If a file named by the 'include' mechanism fails to open, delivery is
    frozen if this option is true. Otherwise, delivery is just deferred.
    Unsetting this option can be useful if included files are NFS mounted
    and likely not always to be available.

group

    Type:    string
    Default: unset

    If a file or pipe delivery is generated by this director, and the
    transport does not specify a user and group, then the user and group
    given here are used when running the delivery process. If the string
    contains no $ characters, it is resolved when Exim starts up.
    Otherwise, the string is expanded at the time the director is run, and
    must yield either a digit string or a name which can be looked up using
    getgrnam().

modemask

    Type:    integer
    Default: 022

    This specifies mode bits which must not be set for the alias file. If
    they are set, the director fails and the message is frozen.

optional

    Type:    boolean
    Default: false

    If the file cannot be opened, Exim panics unless this option is set, in
    which case the director simply fails to match the address.

owners

    Type:    string-list
    Default: unset

    This specifies a list of permitted owners for the alias file. If it is
    unset, no check on the ownership is done. If the file is not owned by a
    user in the list, the director fails and the message is frozen.

owngroups

    Type:    string-list
    Default: unset

    This specifies a list of permitted groups for the alias file. If it is
    unset, no check on the file's group is done. If the file's group is not
    in the list, the director fails and the message is frozen.

search_type

    Type:    string
    Default: unset

    This option must be set to one of the strings 'lsearch', 'dbm', or
    'nis', specifying the type of alias file. For 'lsearch', the file is a
    text file in the common alias file format which is searched linearly.
    For 'dbm' the file is a DBM database in which a lookup is performed
    using the local part as the key. For 'nis' the file is the name of a
    NIS map.

user

    Type:    string
    Default: unset

    When a file or pipe delivery is generated by this director, and the
    transport does not specify a user and group, then the user and group
    given here are used when running the delivery process. If the string
    contains no $ characters, it is resolved when Exim starts up.
    Otherwise, the string is expanded at the time the director is run, and
    must yield either a digit string or a name which can be looked up using
    getpwnam().



                        19. THE FORWARDFILE DIRECTOR


The forwardfile director can be used for two different but related
operations. Its effect is to replace a local part with a list of addresses
from a single file. It gets its name from the common case where the file is
in a user's home directory and is called .forward, but another common use
is for expanding mailing lists, which are discussed in more detail in
chapter 35.

When handling a user's .forward file, a uid, gid, and home directory are
commonly obtained from the password file by calling getpwnam(). However,
these may alternatively be specified by options to the director, in which
case getpwnam() is not called.

The contents of the file are a list of addresses, file names, or pipe
commands, separated by commas or newlines. If an item is enclosed in double
quotes, these are removed, but otherwise double quotes are retained,
because some forms of mail address require the use of quotes. An item is
interpreted as a file name if it begins with '/' and as a pipe command if
it begins with '|'.

Lines starting with a # character are comments, and are ignored, and # may
also appear in a white space position, in which case everything between #
and the end of the line is ignored. If the file is empty, or contains only
blank lines and comments, the director behaves as if it did not exist.

If a message is addressed to two different local parts, each of which
results in an expansion that generates an identical file name or pipe
command, two different deliveries occur, though of course the delivery
processes run with different values in the LOCAL_PART environment variable,
and with different uids (in the common case).

Instead of an address, file name, or pipe command, an item of the form

  :include:<path name>

may appear, in which case an list of addresses is taken from the given file
and included at that point, unless the forbid_include option is set. There
are some security considerations when such an item is included in a user's
.forward file:

 .   If the seteuid() function is being used to read the main file as a
     specific user (see seteuid below) then the included file is read as
     the same user.

 .   Otherwise Exim is running as root at this point. If check_local_user
     is set, or if an explicit directory is specified, then any included
     files must be within the home or given directory, and no symbolic
     links are permitted below the directory name.

 .   If neither check_local_user nor directory is set when seteuid() is not
     in use, then included files are not permitted.

If any error is detected while generating the list of new addresses, the
message is frozen, except for the special case of inability to open an
included file when no_freeze_missing_include is set. In this case, delivery
is simply deferred.

As an alternative to treating the file as a simple list of addresses, the
forwardfile director can be configured, by means of the filter option, to
read a file and interpret it as a list of "filtering" instructions if it
conforms to a specific format. The instructions can specify various actions
such as appending the message to certain mail folders, or forwarding it to
other users, predicated on the content of the message. Details of the
syntax and semantics of filter files are described in a separate document
entitled "Exim: User interface to mail filtering"; this is intended for use
by end users.

A transport must not be specified for this director. A configuration error
occurs if one is given. The local options are:


check_local_user

    Type:    boolean
    Default: true

    If this option is true, then the local part that is passed to this
    director is checked to ensure that it is the login of a local user by
    calling the getpwnam() function. The director fails to handle the
    address if it is not. In addition, when this option is true, the string
    specified for the file option is taken as relative to the user's home
    directory if it is not an absolute path, unless the directory option is
    also given. When this option is set, the local user is always one of
    the permitted owners of the file.

check_group

    Type:    boolean
    Default: false

    The group of the file is checked only when this option is set. If
    check_local_user is set, then the user's default group is permitted;
    otherwise the group must be one of those listed in the owngroups
    option.

directory

    Type:    string
    Default: unset

    This option sets a directory path which is used if the file option does
    not specify an absolute path. This on its own is not very useful, since
    the directory string could just as well be prepended to the file
    string. However, if a separate directory is given, it is treated like a
    home directory and its existence is tested before trying to open the
    file. If the directory appears not to exist, delivery is deferred.
    Thus, a setting such as

      directory = /usr/forwards
      file = ${local_part}.forward

    defers delivery if /usr/forwards appears not to exist. This can be
    useful if the directory is NFS mounted. If check_local_user is also
    set, directory takes precedence in determining the directory name for
    non-absolute files.

errors_to

    Type:    string
    Default: unset

    Delivery errors for any addresses generated by this director are sent
    to this address, if it is set and if it verifies as valid. Otherwise
    the address associated with the incoming address (normally the sender)
    are used.

file

    Type:    string
    Default: unset

    This option must be set. The string is expanded before use - if
    expansion fails, Exim panics. The expanded string must start with a '/'
    character unless check_local_user is true, or a directory option is
    set. A non-absolute path is interpreted relative to the directory
    setting if it exists; otherwise it is interpreted relative to the
    user's home directory.

    In both cases, Exim uses the stat() function to check the directory
    before attempting to open the file therein. If the directory is
    inacessible, the delivery to the current address is deferred. This
    distinguishes between the cases of a non-existent file (where the
    director cannot handle the address) and an unmounted NFS directory
    (where delivery should be deferred).

    If the file exists but is empty or contains only blank and comment
    lines, Exim behaves as if it did not exist, and the director fails to
    handle the address.

filter

    Type:    boolean
    Default: false

    If this option is set, and the forwarding file starts with the text '#
    Exim filter', then it is interpreted as a set of filtering commands
    instead of a list of forwarding addresses. Details of the syntax and
    semantics of filter files are described in a separate document entitled
    "Exim: User interface to mail filtering"; this is intended for use by
    end users.

forbid_file

    Type:    boolean
    Default: false

    If this option is true, then this director may not generate a new
    address which specifies delivery to a local file. If it attempts to do
    so, a delivery failure occurs.

forbid_include

    Type:    boolean
    Default: false

    If this option is true, then items of the form

      :include:<path name>

    are not permitted, and if one is encountered, the message is frozen.

forbid_pipe

    Type:    boolean
    Default: false

    If this option is true, then this director may not generate a new
    address which specifies delivery to a pipe. If it attempts to do so, a
    delivery failure occurs.

forbid_reply

    Type:    boolean
    Default: false

    If this option is true, then this director may not generate an
    automatic reply message. If it attempts to do so, a delivery failure
    occurs. Automatic replies can be generated only from filter files, not
    from traditional forward files.

freeze_missing_include

    Type:    boolean
    Default: true

    If a file named by the 'include' mechanism fails to open, delivery is
    frozen if this option is true. Otherwise, delivery is just deferred.
    Unsetting this option can be useful if included files are NFS mounted
    and likely not always to be available.

group

    Type:    string
    Default: unset

    This option should be specified only in conjunction with the user
    option. If seteuid() is being used to read the file as a particular
    user, then this group is set using setegid() during that process,
    overriding any group that might have been obtained by check_local_user.

    Furthermore, if a file or pipe delivery is generated by this director,
    and the transport does not specify a user and group, then the user and
    group given in the director are used when running the delivery process.
    If the string contains no $ characters, it is resolved when Exim starts
    up. Otherwise, the string is expanded at the time the director is run,
    and must yield either a digit string or a name which can be looked up
    using getgrnam().

modemask

    Type:    integer
    Default: 022

    This specifies mode bits which must not be set for the forward file. If
    they are set, the director fails and the message is frozen.

owners

    Type:    string-list
    Default: unset

    This specifies a list of permitted owners for the file. These are in
    addition to the local user in the case when check_local_user is set. If
    owners is unset and check_local_user is false, no check on the
    ownership is done. If the file is not correctly owned, the director
    fails and the message is frozen.

owngroups

    Type:    string-list
    Default: unset

    This specifies a list of permitted groups for the file. These are in
    addition to the local user's group in the case when check_local_user is
    set. However, a check on the group is made only when check_group is
    set. If the file's group is not correct, the director fails and the
    message is frozen.

seteuid

    Type:    boolean
    Default: false

    This option may not be set unless the compile-time configuration in the
    OS-specific configuration files specifies that the seteuid() function
    is available in the operating system. In addition, either the
    check_local_user or the user and group options must be set. A configur-
    ation error occurs if these conditions do not hold.

    When this option is true, the seteuid() and setegid() functions are
    called to change the effective uid and gid to that of the local user
    before accessing the home directory and the file. This is necessary in
    two circumstances:

    (i)  When Exim is configured to change the effective uid from root to
         the Exim user (using seteuid()) while running the directors. See
         chapter 40 for details.

    (ii) When users' home directories are NFS mounted, and root access is
         not exported to the current machine, to allow for cases when the
         files are not world-readable.

    The forwardfile director can detect the first of these cases, and it
    always uses seteuid(), regardless of the setting of this option, since
    it does not make sense to do otherwise.

    On a system without the seteuid() function, but with NFS home director-
    ies that do not export root, it is necessary for forward files to be
    world-readable.

user

    Type:    string
    Default: unset

    If seteuid() is being used to read the file as a particular user, then
    this user is set during that process, overriding any user that might
    have been obtained by check_local_user. Furthermore, when a file or
    pipe delivery is generated by this director, and the transport does not
    specify a user, then the user given here is used when running the
    delivery process. If the string contains no $ characters, it is
    resolved when Exim starts up. Otherwise, the string is expanded at the
    time the director is run, and must yield either a digit string or a
    name which can be looked up using getpwnam().



                         20. THE LOCALUSER DIRECTOR


The localuser director checks whether the local part of an address is the
login of a local user, by calling the getpwnam() function. If it is, it
accepts the address and sets up a transport for it. The user's uid, gid,
and home directory are set up to be used while running the delivery
process, The generic transport option must always be specified. There is
one private option:

directory

    Type:    string
    Default: unset

    If this option is set, the user's home directory, as obtained from
    getpwnam(), must match the given string. If it does not, the director
    fails to match the address. This provides a way of partitioning the
    local users by home directory. The string is expanded before use if it
    contains any $ characters. If it starts with an asterisk, then the
    remainder must match the end of the home directory name; if it starts
    with a circumflex, a regular expression match is performed.



                         21. THE SMARTUSER DIRECTOR


The smartuser director matches any local part, so it is used to handle
local addresses that all other directors have failed. It can generate a new
address from the old one, and cause that to be re-processed, or it can set
a transport for the current address, optionally changing the address.
Common uses are to pipe the message to a script that generates an
information message to be returned to the sender, or to send the message to
another host for processing.


new_address

    Type:    string
    Default: unset

    This option specifies a new address, to replace the current one. It
    must be a qualified address (i.e. contain an '@' character). The string
    is expanded (Exim panics if expansion fails) and so settings such as

      new_address = ${local_part}@some.new.host

    can be used. If the generic transport option is not specified, this
    option is required, and the new address is processed by the directors
    and routers in the normal way. If a transport is specified, the new
    address just replaces the old one when the message is delivered.



                         22. GENERIC ROUTER OPTIONS


The following generic options apply to all the routers:

domains

    Type:    domain-list
    Default: unset

    If this option is set, then the router is skipped unless the current
    domain matches one of the entries in the list. This can be used to
    reduce the use of an expensive router such as queryprogram by doing a
    preliminary plausibility check on the domain.

driver

    Type:    string
    Default: unset

    This option must always be set. It specifies the name of the router
    driver.

fail_verify

    Type:    boolean
    Default: false

    If this option is true and an address is accepted by this router when
    verifying, then verification fails. This option has no effect if the
    verify option is false.

more

    Type:    boolean
    Default: true

    If this option is false, then if the router fails to match an address,
    no further routers are tried, and routing fails. This applies even in
    the case of address verification where the router was not run because
    the verify option was off.

require_files

    Type:    stringlist
    Default: unset

    The value of this option is first expanded and then interpreted as a
    colon-separated list of strings. 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. This provides a general
    mechanism for predicating the running of a router on the existence or
    non-existence of certain files or directories. A failure to expand the
    string, or the presence of a non-fully-qualified path within it causes
    a panic error.

transport

    Type:    string
    Default: unset

    The string must be the name of a configured transport instance. This
    option must always be specified, and the transport must be non-local.

verify

    Type:    boolean
    Default: true

    If this option is false, then this router is skipped when verifying
    addresses.



                         23. THE DOMAINLIST ROUTER


The domainlist router compares a list of domain patterns with the domain it
is trying to route. When a match is found, the information associated with
the pattern can specify several different actions:

 .   The message can be sent to a specific host, or one of a number of
     hosts.

 .   The domain name can be replaced by a new name, which can be

     (i)  looked up in the DNS, with or without MX processing; or

     (ii) looked up using gethostbyname(); or

     (iii)passed to the next router.

The list of patterns can be specified as an option string, or read from a
file, or both; at least one of the route_list and route_file options must
be set. A transport must be set (using the generic transport option) when
the routing is completed by this router, that is, when the address is not
passed on to subsequent routers.


modemask

    Type:    integer
    Default: 022

    This specifies mode bits which must not be set for the route file. If
    they are set, the director fails and the message is frozen.

owners

    Type:    string-list
    Default: unset

    This specifies a list of permitted owners for the route file. If it is
    unset, no check on the ownership is done. If the file is not owned by a
    user in the list, the router fails and the message is frozen.

owngroups

    Type:    string-list
    Default: unset

    This specifies a list of permitted groups for the route file. If it is
    unset, no check on the file's group is done. If the file's group is not
    in the list, the router fails and the message is frozen.

route_file

    Type:    string
    Default: unset

    The file is in the same format as an alias file, and contains routing
    rules in the form described below.

route_list

    Type:    string
    Default: unset

    This string is a list of routing rules, in the form defined below.

search_type

    Type:    string
    Default: unset

    This option is mandatory when the route_file option is specified. It
    must be set to one of the strings 'lsearch', or 'dbm', or 'nis',
    specifying the type of file search.

If both route_list and route_file are specified, the string list is
searched first. It consists of a sequence of routing rules, separated by
semicolons. Empty items are ignored. The format of each rule is

  <domain pattern>  <host-list>  <options>

The domain pattern is in the same format as each item in a domain list (see
section 6.8), that is, it may be wildcarded or a regular expression, or a
list in a file. The host list is a colon-separated list of host names
and/or IP addresses, and the options are optional.

If the domainlist router specifies a local transport (typically appendfile
or pipe for handling batched SMTP), then there must be no more than one
host name in the entry, and no options. If there is a host name, it becomes
available for expansion as ${host} while transporting, but is not otherwise
used. For an example, see section 39.6.

Here is a simple example with a host list containing just one host, and no
options:

  route_list = "*.uucp  uugateway.fict.book"

When routing rules are read from a file, the keys in the file must be
actual domain names; no wildcarding is possible. The data associated with
each key consists of the host list and options, as for a string list. For
example, a line from a route file might be:

  dict.ref.book:  mail-1.ref.book:mail-2.ref.book  byname

The options are a sequence of words; the following are recognized:

 .   byname: look up the new host(s) using gethostbyname().

 .   bydns: look up the new host(s) using the DNS and doing the full MX and
     A record processing.

 .   bydns_a: look up a A records for the host(s) in the DNS; fail if there
     are none.

 .   bydns_mx: look up MX records for the host(s) in the DNS; fail if there
     are none.

If none of these options is specified, then the host list must contain
exactly one host (domain) name, which is then passed on to the next router.
Otherwise, there can be a number of names, and their addresses are looked
up according to the option setting. In this case, a transport must be
specified for the domainlist router.

The domainlist router can be used to handle a number of different routing
requirements, as shown in the following examples:

 .   A gateway to another mail environment can be set up using a wildcarded
     domain pattern that matches some pseudo top-level domain. For example,
     to route certain addresses to UUCP and Bitnet gateways, use an option
     like this:

       route_list = "*.uucp   uugateway.fict.book;\
                     *.bitnet bngateway.ref.book"

     Because no options or transport are specified in either case, the name
     of the gateway machine is passed to the next router for further
     routing.

 .   A machine that is itself a gateway can 'deliver' messages to pipes or
     into files in batched SMTP format for onward transportation by some
     other means. In this case, the route list entry can be as simple as a
     single domain name in a configuration like this:

       route_append:
         transport = batchsmtp_appendfile,
         driver = domainlist;
         route_list = "gated.domain"

     though often a domain pattern is used to pick up more than one domain.

 .   A "mail hub" is a machine 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 domainlist router can be set up
     for this purpose by using a configuration file containing entries of
     the form

       dict.ref.book:  mail-1.ref.book:mail-2.ref.book  byname

     The DNS would be set up with an MX record for dict.ref.book pointing
     to the mail hub, which then forwards its mail to one of the two
     specified machines, whose addresses are looked up by gethostbyname().

 .   The domainlist router can also be used to forward all non-local mail
     to a "smart host" by using a configuration option such as

       route_list = "*  smarthost.ref.book  bydns_a"

     which causes all messages containing remote addresses to be sent to a
     single host, whose address (in this example) is obtained from its DNS
     address record.



                          24. THE IPLOOKUP ROUTER


The iplookup router was written to fulfil a specific requirement in
Cambridge. For this reason, it is not included in the binary of Exim by
default. If you want to include it, then you must set

  ROUTER_IPLOOKUP=yes

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. 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 bits 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 re-writing router, a transport must not be
specified for it. The private options are:


hosts

    Type:    string
    Default: unset

    This option must be supplied. Its value is a colon-separated list of
    host names. The hosts are looked up using gethostbyname and are tried
    in order until one responds to the query.

optional

    Type:    boolean
    Default: false

    If optional is true, then if no response is obtained from any host, the
    address is passed on to the next router. If optional is false, delivery
    to this address is deferred.

protocol

    Type:    string
    Default: udp

    This option can be set to 'udp' or 'tcp' to specify which of the two
    protocols is to be used.

query

    Type:    string
    Default: "${local_part}@${domain}"

    This defines the content of the query that is sent to the remote hosts.

reroute

    Type:    string
    Default: unset

    If this option is not set, the rerouted address is precisely the byte
    string returned by the remote host. 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>.

response_pattern

    Type:    string
    Default: 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 fails. If response_pattern is not set, no checking
    of the response is done. For example, if the response is just a new
    domain, the following could be used:

      response_pattern = "^([^@]+)$"
      reroute = "${local_part}@${1}"

service

    Type:    integer
    Default: 0

    This option must be supplied. It specifies the port number for the TCP
    or UDP call.

timeout

    Type:    time
    Default: 5s

    This specifies the amount of time to wait for a response from the
    remote machine.



                         25. THE LOOKUPHOST ROUTER


The lookuphost router looks up the hosts that handle mail for a given
domain either via the gethostbyname() function, or by using the DNS. A non-
local transport must always be set (using the generic transport option) for
this router.


gethostbyname

    Type:    boolean
    Default: false

    If this is true, the gethostbyname() function is used and the options
    relating to the DNS are ignored. Otherwise, the name is looked up in
    the DNS.

mx_domains

    Type:    string-list
    Default: unset

    This option, together with non_mx_domains, applies to domains that are
    looked up in the DNS for non-source-routed RFC 822 addresses (that is,
    addresses that do not start with @). A domain which is in mx_domains
    but is not in non_mx_domains is required to have an MX record in order
    to be recognised. For example, if all the mail hosts in fict.book are
    known to have MX records, except for those in discworld.fict.book,
    options of the form

      mx_domains = *.fict.book,
      non_mx_domains = *.discworld.fict.book

    could be used. This would cause messages addressed to a machine with
    only an A record to be bounced immediately instead sitting on the queue
    until the delivery timed out. Note, however, that for source-routed RFC
    822 addresses (ones that start with @) this restriction does not apply,
    as the first domain in such an address is a machine name.

non_mx_domains

    Type:    string-list
    Default: unset

    See mx_domains above.

qualify_single

    Type:    boolean
    Default: true

    If domains are being looked up in the DNS, then the option to cause the
    resolver to qualify single-component names with the local domain is
    set. For example, on a machine called dictionary.ref.book, looking up
    the domain thesaurus would cause the name thesaurus.ref.book to be
    looked up.

rewrite_headers

    Type:    boolean
    Default: true

    An abbreviated name may be expanded to its full form by both
    gethostbyname() or by DNS lookup, or as a result of the widen_domains
    option. For example, if an address is specified as dormouse@teaparty,
    the domain might get expanded to teaparty.wonderland.fict.book. If this
    option is true, then all occurrences of the abbreviated name in the
    headers of the message are rewritten with the full 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.

search_parents

    Type:    boolean
    Default: true

    If domains are being looked up in the DNS, then the option to cause the
    resolver to search parent domains is set. This is different from the
    qualify_single option in that it applies to domains containing dots.
    For example, on a machine in the fict.book domain, when looking up
    teaparty.wonderland initially fails, the resolver automatically tries
    teaparty.wonderland.fict.book.

self_mx

    Type:    string
    Default: "freeze"

    This option specifies what is to happen if the lowest numbered MX
    record for a remote domain points to the local host. Normally this
    indicates either an error in Exim's configuration (the domain should be
    listed as local), or an error in the DNS (the MX shouldn't point at
    this host). The default action is to freeze the message. The following
    alternatives are provided for use in special cases:

     .   defer
         Delivery of the message is tried again later.

     .   local: <domain>
         The domain is changed to the given domain, which must be one of
         the local domains, and the address is passed back to the direc-
         tors. No rewriting of headers takes place.

     .   local: rewrite: <domain>
         The domain is changed to the given domain, which must be one of
         the local domains, and the address is passed back to the direc-
         tors. Any headers that contain the original domain are rewritten.

     .   fail_soft
         The router fails, leaving the address to be passed to any
         following routers.

     .   fail_hard
         The router fails, and the address is not passed to any following
         routers. Consequently, delivery fails.

     .   send
         The anomaly is ignored and the message is transmitted anyway. This
         setting should be used only with extreme caution. 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.

widen_domains

    Type:    string-list
    Default: unset

    If a 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

      widen_domains = "fict.book:ref.book"

    is set and a lookup of klingon.dictionary fails, then
    klingon.dictionary.fict.book is looked up, and if this fails, then
    klingon.dictionary.ref.book is tried. This option applies to lookups
    using gethostbyname() as well as to DNS lookups. Note that when the DNS
    is being used for lookups, the qualify_single and search_parents
    options cause some widening to be undertaken inside the DNS resolver.



                        26. THE QUERYPROGRAM ROUTER


The queryprogram router routes a domain 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 domains generic option to skip this
router for most addresses, then it could sensibly be used in other cases.
There is only one option:


command

    Type:    string
    Default: unset

    This option must be set, and must start with a '/' character. It
    specifies the command that is to be run. It is expanded before use.
    Failure to expand causes the router to fail and the message to be
    frozen.

The command is run as 'nobody'. If the main configuration has not defined a
user and group for 'nobody', then it is looked up using getpwnam(). If this
fails, the router fails and the message is frozen.

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 four fields, separated by white space. The first field is one of
the following words:

 .   OK: routing succeeded; the remaining fields specify what to do.

 .   FAIL: routing failed; pass the address to the next router.

 .   FORCEFAIL: routing failed; do not pass the address to any more
     routers.

 .   DEFER: routing could not be completed at this time.

 .   ERROR: some disastrous error occured; freeze the message.

When the first word is not OK, the remainder of the line is an error
message explaining what went wrong. For example:

  FAIL  queryprogram cannot route to unseen.discworld.fict.book

Otherwise, the second word is the name of a non-local transport instance,
or a + character, which means that the transport specified for the router
using the generic transport option is to be used.

If the third field is not empty, it is a new domain name to replace the
current one, and if a transport is specified and the fourth field is not
empty, it specifies the method of looking up the new name. This can be one
of the words 'byname', 'bydns', 'bydns_a', or 'bydns_mx'. For example,

  OK  smtp  gate.star.fict.book  bydns_a

causes the message to be sent to the host gate.star.fict.book, whose
address is looked up as a DNS address record.

The fourth field is ignored, and the new domain name (if any) is passed to
the next router if no transport is specified in the response line (i.e. a +
character is given) and the generic transport option is also unset.



                          27. RETRY CONFIGURATION


The fifth part of the 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, Exim gives up
after the first failure.

Retry processing applies to directing and routing as well as to delivering.
The retry rules do not distinguish between these three actions, so it is
not possible, for example, to specify different behaviour for failures to
route the domain snark.fict.book and failures to deliver to the host
snark.fict.book. I didn't think anyone would ever need this added compli-
cation, so did not implement it. Internally, however, the actual retry
times for routing, directing, and transporting are maintained
independently.

Each retry rule occupies one line and consists of three parts. The rules
are searched in order until one which matches the current domain (and
possibly local part) is found.

The first field in a retry rule is a key for the rule, which may start with
an asterisk, or be a regular expression. For rules that apply to remote
hosts and domains, the key is matched against the domain name. For rules
that apply to local addresses, the key contains both the local part and the
local domain, separated by @. Note that it is a single key; unlike
rewriting rules, the local part and domain are not treated separately.
Local parts must not be given except with local domain names.

The second field is the name of a particular error, or an asterisk, which
matches any error. The errors that can be tested for are:

     refused_MX: connection refused from a host obtained from an MX record

     refused_A: connection refused from a host not obtained from an MX
     record

     refused: any connection refusal

     timeout_connect: connection timed out

     timeout_DNS: DNS lookup timed out

     timeout: any timeout

     quota: quota exceeded in local delivery

     quota_<time>: quota exceeded in local delivery, and the mailbox has
     not been read for <time>.

The third field is a sequence of retry parameter sets, separated by
semicolons. Each set consists of

  <letter>,<cutoff time>,<arguments>

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.

The available algorithms are:

 .   F: retry at fixed intervals. There is a single time parameter
     specifying the interval.

 .   G: retry at geometrically increasing intervals. The first argument
     specifies a starting value for the interval, and the second a
     multiplier.

Here are some example retry rules suitable for use when
wonderland.fict.book is a local domain:

  *@wonderland.fict.book   quota_5d
  *@wonderland.fict.book   *          F,1h,15m; G,2d,1h,2;
  lookingglass.fict.book   *          F,24h,30m;
  *                        refused_A  F,2h,20m;
  *                        *          F,2h,15m; G,16h,2h,1.5; F,5d,8h

The first two specify that local deliveries are to be retried every 15
minutes for an hour, then with geometrically increasing intervals until 2
days have passed, except when there is an over-quota error and the mailbox
has not been read for at least 5 days. In this case, as there are no retry
algorithms, messages are bounced straight away. Note that no 'local part'
is given in the rule for lookingglass.fict.book, which implies that it is
not a local domain.

The final rule 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 increasing by a factor of 1.5 up to 16 hours, then every 8
hours up to 5 days.

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
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
broken, Exim will generate retry times for it and will not try to use it
until its next retry time comes.

Retry times are hints rather than promises. Exim does not make any attempt
to run deliveries at the computed times. Instead, a queue-running process
starts delivery processes for delayed messages periodically, and these
attempt new deliveries only for those addresses that have passed their next
retry time.

Special processing happens when an address has been failing for so long
that the cutoff time for the last algorithm has been reached. If this is
the case for a local delivery, or for all IP addresses associated with a
remote delivery, a subsequent delivery failure causes Exim to give up on
the address, and a delivery error message is generated. In order to cater
for new messages that may use the failing address, however, a next retry
time is still computed from the final algorithm, and is used as described
below.

If the delivery is a local one, one delivery attempt is always made for any
subsequent messages. If it 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
delay_after_cutoff option of the smtp transport. The option is true by
default and in that case:

     Until the post-cutoff retry time for one of the IP addresses is
     reached, any attempt to access the failing address is bounced immedi-
     ately. 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.

     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. This ensures that few resources are wasted
     in repeatedly trying to delivery to a broken destination, but if it
     does eventually 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 none, 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, unsetting delay_after_cutoff means
     that there will be many more attempts to deliver to failing IP
     addresses than when delay_after_cutoff is true.

An additional rule is needed to cope with cases where a host is intermit-    |
tently available, or when a message has some attribute that prevents its     |
delivery when others to the same address get through. 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 the message has been on the queue for longer than the cutoff time   |
of an address, that address is bounced after a temporary delivery error.     |
                                                                             |
Even with this rule a large queue of messages can take a long time to clear  |
if some occasionally get delivered, because the intermittent failures delay  |
delivery attempts on the others (and the above rule acts only after a        |
delivery attempt). There is therefore an ultimate clean-up rule which        |
causes all the remaining addresses in a message to be failed, whether or     |
not there has just been a delivery attempt, if the message has been on the   |
queue for longer than the longest cutoff time in the configuration file.     |

The data in the retry hints database can be inspected by using the
exim_dumpdb or exim_fixdb utility programs (see chapter 37). 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.



                           28. ADDRESS REWRITING


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. There are two cases that are commonly
accepted:

 .   The company hitch.fict.book has a number of machines that exchange
     mail with each other behind a firewall, but only a single gateway to
     the outer world. The gateway rewrites *.hitch.fict.book as
     hitch.fict.book.

 .   A machine rewrites the local parts of outgoing messages from its own
     users so that, for example, fp42@hitch.fict.book becomes
     Ford.Prefect@hitch.fict.book.

In general, rewriting addresses from one's own system or domain has some
legitimacy. Rewriting other addresses should be done only with great care
and in special circumstances.

Exim's rewriting configuration, which appears as the sixth part of the
runtime configuration file, consists of lines of rewriting rules in the
form

  <source pattern>  <replacement>  <flags>

Long rules can be split over several lines by terminating all but the last
with a backslash character. Leading white space on continuation lines is
ignored. The rules are scanned in order and relacements from earlier rules
can themselves be replaced as a result of later rules.

The source pattern is an address containing both a local part and a domain.
Each of these may start with an asterisk, implying independent wildcard
matching, or the entire thing may be a single regular expression. The
replacement is a string which is expanded. Within the expansion, numerical
variable names can be used to refer to parts of the actual address.

If the pattern is a regular expression, the numerical variables refer to
the bracketed sub-expressions therein, with ${0} referring to the entire
address. For example, if the pattern

  ^(red|white).king@(wonderland|lookingglass).fict.book$

is matched against the address red.king@lookingglass.fict.book then

  ${0}   is red.king@lookingglass.fict.book
  ${1}   is red
  ${2}   is lookingglass

If the pattern is not a regular expression, the numerical variables refer
to the character strings matched by asterisks, with ${1} associated with
the first asterisk. Once again, ${0} refers to the entire address. For
example, if the pattern

  *queen@*.fict.book

is matched against the address hearts-queen@wonderland.fict.book then

  ${0}   is hearts-queen@wonderland.fict.book
  ${1}   is hearts-
  ${2}   is wonderland

Note that if the local part does not start with an asterisk, but the domain
does, then it is ${1} that contains the wild part of the domain.

The flags field may be empty, in which case the rewriting rule applies to
all headers and to both the sender and recipient fields of the envelope.
Otherwise, one or more of the following letters can be given to control
which addresses are rewritten:

  E       rewrite all envelope fields
  F       rewrite the envelope From field
  T       rewrite the envelope To field
  b       rewrite the Bcc header
  c       rewrite the Cc header
  f       rewrite the From header
  h       rewrite all headers
  r       rewrite the Reply-to header
  s       rewrite the Sender header
  t       rewrite the To header

You should be particularly careful about rewriting Sender headers, and
restrict this to special known cases in your own domains.

Rewriting happens immediately after a message has been read, which is why
it is possible to rewrite the Bcc header. Here is an example of the two
common rewriting paradigms:

  *@*.hitch.book.fict  $1@hitch.book.fict
  *@hitch.book.fict    ${lookup{$1}lsearch{/etc/realnames}\
                       {$value}fail}@hitch.book.fict bcfrF

Note the use of 'fail' in the lookup expansion. This causes the string
expansion to fail, and in this context it has the effect of leaving the
original address unchanged. An alternative 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.



                               29. LOG FILES


Exim writes four different log files into a subdirectory of its spool
directory called log.

 .   The file called mainlog 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 also recorded on the main log.

 .   The file called rejectlog records information from messages that are
     rejected because their return paths are invalid (a configurable
     option). The headers are written to this log, following a copy of the
     one-line message that is also written to the main log.

 .   The file called paniclog is written when Exim suffers a disaster and
     has to bomb out.

 .   On systems that support signal handlers that restart a system call on
     exit, Exim reacts to a USR1 signal by writing a line describing its
     current activity to a file called processlog. This makes it possible
     to find out what each exim process on a machine is currently doing.

A utility script called exicyclog which renames and compresses the main and
reject logs each time it is called is provided. The maximum number of old
logs to keep can be set. It is suggested this is run as a daily cron job. A
Perl script called eximstats which does simple analysis of main log files
is also provided. See chapter 37 for details of both these utilities.

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 re-uses an open
file, and if the file does not exists, 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.


29.1 Message reception

The format of the single-line entry in the main log that is written for
every message received is as in the example below, which is split over
several lines in order to fit it on the page:

1995-10-31 08:57:53 0tACW1-0005MB-00 <= kryten@dwarf.fict.book
  H=mailer.fict.book [123.123.123.123] U=exim
  P=smtp S=5678 id=<incoming message id>

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 host
name in the H field is the name quoted by the remote host in the SMTP HELO
or EHLO command, and the number in square brackets is the IP address of the
host. Misconfigured hosts (and mail forgers) sometimes put an IP address in
the HELO or EHLO command, leading to entries in the log containing things
like

  H=10.21.32.43 [123.99.8.34]

which can be confusing. Only the address in brackets can be relied on. For
locally generated messages, the H and U fields are are omitted. The P field
specifies the protocol used to receive the message, the S field is the
message size, and the id field records the existing message id, if present.

If the log_received_recipients option is on, a list of all the recipients
of a message is added to the log line, preceded by the word 'for'. The
happens after any unqualified addresses are qualified, but before any
rewriting is done.


29.2 Deliveries

The format of the single-line entry in the main log that is written for
every delivery is as in one of the examples below, for local or remote
deliveries, respectively. Each example has been split into two lines in
order to fit it on the page.

1995-10-31 08:59:13 0tACW1-0005MB-00 => marvin <marvin@hitch.fict.book>
  D=localuser T=local_delivery
1995-10-31 09:00:10 0tACW1-0005MB-00 => monk@holistic.fict.book
  R=lookuphost T=smtp H=holistic.fict.book [234.234.234.234]

For local deliveries, the original address is given in angle brackets after
the final delivery address, which might be a pipe or a file. The generation
of a reply message by a filter file gets logged as a 'delivery' to the
addressee, preceded by '>'. The D and T items record the director and
transport. For remote deliveries, the router, transport, and host are
recorded. When more than one address is included in a single delivery (e.g.
two SMTP MAIL FROM commands in one transaction) then the second and
subsequent addresses are flagged with -> instead of =>. When two or more
messages are delivered down a single SMTP connection, an asterisk follows
the IP addresses for the second and subsequent messages.


29.3 Deferred deliveries

When a delivery is deferred, a line of the following form is logged:

1995-12-19 16:20:23 0tRiQz-0002Q5-00 == marvin@endrest.book
  T=smtp defer (146): Connection refused

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

1995-12-19 16:20:23 0tRiQz-0002Q5-00 Failed to connect to endrest.book
  [239.239.239.239]: Connection refused


29.4 Delivery failures

If a delivery fails, a line of the following form is logged:

1995-12-19 16:20:23 0tRiQz-0002Q5-00 ** jim@trek99.film
  <jimtrek99.film>: unknown mail domain

This is followed (eventually) by a line giving the address to which the
delivery error has been sent.


29.5 Completion

A line of the form

  1995-10-31 09:00:11 0tACW1-0005MB-00 Completed

is written to the main log when a message is about to be removed from the
spool file at the end of its processing.


29.6 Message log

In addition to the four main 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 they are kept in the msglog subdirectory of the spool
directory. A single line is written to the message log for each delivery
attempt for each address. It records either a successful delivery, or the
reason (temporary or permanent) for failure. SMTP connection failures for
each remote host are also logged here. The log is deleted when processing
of the message is complete, unless preserve_message_logs is set, but this
should be used only with great care.



                           30. MESSAGE PROCESSING


Exim performs various transformations on the sender and recipient addresses
of 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, happens when a
message is received, before it is first written to the spool.

Any addresses that are unqualified are made fully qualified by adding the
qualify_domain or qualify_recipient value, as appropriate. Unqualified
addresses are accepted only from local sources or from hosts that match one
of the receiver_unqualified or sender_unqualified options, as appropriate.


30.1 The Bcc header

If Exim is called with the -t option, to take recipient addresses from a
message's headers, it removes any Bcc header that may exist (after
extracting its addresses), unless the message has no To or Cc header, in
which case a Bcc header with no addresses is left in the message, in
accordance with RFC 822.


30.2 The Date header

If a message has no Date header, Exim adds one, giving the current date and
time.


30.3 The Delivery-date header

Delivery-date headers are not part of the standard RFC 822 header set. Exim
can be configured to add them to the final delivery of messages. (See the
delivery_date_add option in the appendfile and pipe transports.) They
should not be present in messages in transit. If the delivery_date_remove
configuration option is set, Exim removes delivery-date headers from
incoming messages.


30.4 The From header

If an incoming message does not contain a From header, Exim adds one
containing the sender's address. This is obtained from the message's
envelope in the case of remote messages; for locally-generated messages the
calling user's login name and full name are used. They are obtained from
the password file entry by calling getpwid() (but see the unknown_login
configuration option). The address is qualified with the value of
qualify_domain.


30.5 The Message-id header

If an incoming message does not contain a Message-id header, Exim con-
structs one and adds it to the message. 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 by setting the message_id_header_text
option.


30.6 The Received header

A Received header is added at the start of every message. The contents of
this header are defined by the received_header_text configuration option,
and Exim automatically adds a semicolon and a timestamp to the configured
string.


30.7 The Return-path header

Return-path headers are defined as something the MTA may insert when it
does the final delivery of messages. (See the return_path_add option in the
appendfile and pipe transports.) Therefore, they should not be present in
messages in transit. If the return_path_remove configuration option is set,
Exim removes Return-path headers from incoming messages.


30.8 The Sender header

For locally-originated messages, unless originated by a trusted user using
the -f or -bs command line option, any existing Sender header is removed. A
check is then made to see if the address given in the From header is the
correct (local) sender of the message. If not, a Sender header giving the
true sender address is added to the message. No processing of the Sender
header is done for messages originating externally.


30.9 The To header

If a message has no To, Cc, or Bcc header, Exim adds an empty Bcc header,
in accordance with RFC 822. It does not add an Apparently-to header.


30.10 Constructed addresses

When Exim constructs a sender address for a locally-generated message, it
uses the form

  <user name> <<login>@<qualify_domain>>

For example:

  Zaphod Beeblebrox <zaphod@end.univ>

The user name is obtained from the -F command line option if set, or
otherwise by looking up the calling user by getpwuid() and extracing the
'gecos' field from the password entry. (See the gecos_name option for a way
to tailor this.) 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 822 by quoting all or parts of it if
necessary.


30.11 Case of local parts

RFC 822 states that the case of letters in the local parts of addresses
cannot be assumed not to be significant. Exim preserves the case of local
parts of remote addresses. However, when it is processing an address in one
of its local domains, the case of letters in the local part is not
significant.


30.12 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 28.

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

  To: hare@teaparty

might get rewritten as

  To: hare@teaparty.wonderland.fict.book

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 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.



                     31. THE DEFAULT CONFIGURATION FILE


The default configuration file supplied with Exim as src/configure.default
is suffient for a simple configuration. Its contents are described here.


31.1 Main configuration settings

Only one explicit option is specified in this section:

  never_users = root

This prevents Exim from ever running as root when performing a local
delivery. Instead, it runs as 'nobody'.

As the primary_hostname, qualify_domain, and local_domains options are not
specified, they will all take the name of the local host, as obtained by
the uname() function, as their value.


31.2 Transport configuration settings

Three local and one remote transport are defined:

  local_delivery:
    driver = appendfile;
    file = /var/mail/${local_part}

This transport is set up to deliver to local mailboxes in a traditional
'sticky bit' directory. To deliver into files in users' home directories, a
configuration such as

  local_delivery:
    driver = appendfile;
    file = /home/${local_part}/inbox

should be substituted.

  address_pipe:
    driver = pipe;
    ignore_status,
    return_output

This transport, whose name (address_pipe) is conventional, is automatically
used by Exim when a local part that is expanded via an alias or forward
file causes delivery to a pipe. The status returned by the pipe process is
ignored, and any output from the pipe is returned to the sender of the
message.

  address_file:
    driver = appendfile

This transport, whose name (address_file) is conventional, is automatically
used by Exim when a local part that is expanded via an alias or forward
file causes delivery to a specified file.

  address_reply:
    driver = autoreply

This transport, whose name (address_reply) is conventional, is automati-
cally used by Exim when a local part that is expanded via a filter file
causes an automatic reply to a message to be generated.

  smtp:
    driver = smtp;

This transport is used to do external deliveries over SMTP, with default
options.


31.3 Director configuration settings

Three directors are specified for the default configuration. Note that the
order of director definitions matters.

  system_aliases:
    driver = aliasfile;
    file = /etc/aliases,
    search_type = lsearch

The first director causes local parts to be checked against the system
alias file, which is searched linearly.

  userforward:
    no_verify,
    driver = forwardfile;
    file = .forward

If a local part does not match a system alias, an attempt is made to look
for a file called .forward in the home directory of a local user. However,
this director is skipped when verifying addresses. This director does not
contain the filter option. Thus .forward files are treated in the conven-
tional manner.

  localuser:
    driver = localuser,
    transport = local_delivery;

This final director checks that a local part is the login of a local user,
and if so, directs the message to be delivered using the local_delivery
transport.


31.4 Router configuration settings

A single router is defined in the default configuration:

  lookuphost:
    driver = lookuphost,
    transport = smtp;

The default settings for lookuphost cause it to look up the domain in the
DNS, in order to determine the host to which a message should be sent,
using the smtp transport.


31.5 Retry rules

A single retry rule is given in the default configuration:

  *    *   F,2h,15m; G,16h,2h,1.5; F,4d,8h

This causes any temporarily failing address to be retried every 15 minutes
for 2 hours, then at intervals increasing by a factor of 1.5 until 16 hours
have passed, then every 8 hours up to 4 days.


31.6 Rewriting configuration

There are no explicit rewriting rules in the default configuration file.



                         32. DAY-TO-DAY MANAGEMENT


This chapter describes some of the regular tasks that need to be done to
keep Exim running smoothly.


32.1 The reject log

If checking of sender addresses on incoming mail is enabled, the headers of
rejected messages are written to the reject log. This can be regularly
checked to ensure that the checking is working properly, and to pick up
errors such as missing DNS entries.


32.2 Log cycling

The exicyclog script (see chapter 37) cycles the names of log files,
compresses all but the most recent, and deletes the oldest. This should be
run at intervals dependent on the amount of mail traffic. For a system with
a reasonable amount of mail, running it daily via cron is suggested.


32.3 Statistics

The eximstats script (see chapter 37) produces statistics about messages
received and delivered by analysing log files.


32.4 What is Exim doing?

On systems that can restart a system call after receiving a signal, Exim
responds to the SIGUSR1 signal by writing a line describing what it is
doing to its processlog file. The exiwhat script (see chapter 37) sends the
signal to all Exim processes it can find, having first emptied the log
file. It then waits a bit before displaying the results.

When the number of processes handling incoming SMTP calls is limited by
setting the smtp_accept_max option, the daemon uses the SIGCHLD signal to
detect when any of its subprocesses finishes. On some operating systems
this signal sometimes gets lost when the system is very busy. If you think
that Exim is running fewer reception processes than it should, use the kill
command to send a SIGCHLD signal to the daemon process. This causes the
daemon to pick up all of its subprocesses that have finished but have not
yet been noticed.


32.5 Changing the configuration

A changed configuration file is picked up immediately by any Exim processes
that are subsequently started, but it will not be noticed by any existing
processes. The daemon process can be caused to restart itself by sending it
the SIGHUP signal, which should also be sent when a new version of the Exim
binary is installed. Restarting causes its process id to change. The
current process id is written to a file called exim-daemon.pid in Exim's
spool directory. It is not necessary to use SIGHUP when changing the
contents of any files referred to in the configuration (e.g. alias files)
since each delivery process reads such files independently.


32.6 Watching the queue

The queue of messages awaiting delivery can be examined by running the Exim
monitor (see chapter 38), or by obeying "exim -bp" periodically. If any
messages are frozen, their header files and message log files should be
examined to determine the cause of the problem. Once the problem is
believed to be fixed, the messages can be unfrozen by the administrator,
who can also kick off an immediate delivery attempt if necessary.



                     33. INTERMITTENTLY CONNECTED HOSTS


It is becoming 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.

If such a 'holding system' is running Exim, then it should be configured
with a long retry period for the intermittent host. For example:

  cheshire.wonderland.fict.book    *   F,24h,5d

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, then forcing delivery of one message
(either by using the -M or -R options) causes all the queued up messages to
be delivered, often down a single SMTP connection. While the host remains
connected, any new messages will get delivered immediately.



                       34. AUTOMATIC MAIL PROCESSING


This chapter describes some of the ways in which incoming mail can be
processed automatically, either on a system-wide basis, or as specified by
individual users.


34.1 System-wide automatic processing

Simple re-addressing of messages can be handled by aliasfile or forwardfile
directors. The particular case of mailing lists is covered in the following
chapter. Other kinds of automatic processing can be handled by suitable
configurations of directors and transports. As an example, here is an
extract from the configuration of a system which tries to send back helpful
information when a message is received for an unknown user. The last
director in the configuration is:

  unknownuser:
    no_verify,
    driver = smartuser,
    transport = unknownuser_pipe;

This collects all the addresses whose local parts haven't been matched by
any other director, and directs them to a special pipe transport, whose
configuration is:

  unknownuser_pipe:
    driver = pipe;
    command = /opt/exim/util/baduser.sh,
    ignore_status,
    return_output,
    user = nobody

The script is run as the user 'nobody', and it applies heuristics and a
"soundex" search to the local part, in an attempt to produce a list of
possible users for whom the message might have been intended. This is then
included in a message that is written to its standard output; Exim picks
this up and returns it to the sender as part of the delivery error message.

System-wide automatic processing that depends on the contents of messages    |
can be implemented by means of a system mail filter file, using a director   |
such as the following:                                                       |
                                                                             |
  system_filter:                                                             |
    no_verify,                                                               |
    driver = forwardfile;                                                    |
    no_check_local_user,                                                     |
    filter,                                                                  |
    file = /etc/system-mail-filter,                                          |
    user = nobody                                                            |
                                                                             |
See the separate document that describes the available filtering commands.   |
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. Thus the director will not claim to have dealt    |
with the address, so it will be passed on to subsequent directors to be      |
delivered in the normal way. Note that a traditional .forward file does not  |
have this property, so cannot be used in this way, though you could use it   |
to forward all mail for a particular domain to a single recipient in a       |
different domain.                                                            |


34.2 Users' automatic processing

Users can cause their mail to be processed automatically by creating
.forward files, provided that Exim's configuration contains an appropriate
forwardfile director. Traditionally, such files contain just a list of
forwarding addresses, local files, and pipe commands, but if the
forwardfile director has the filter option set, users can access Exim's
filtering facilities by beginning a .forward file with the text '# Exim
filter'. Details of the syntax and semantics of filter files are described
in a separate document entitled "Exim: User interface to mail filtering";
this is intended for use by end users.

The name .forward is purely conventional; a forwardfile director can be      |
configured to use any arbitrary name. As there are some finger daemons that  |
display the contents of users' .forward files, some sites might like to use  |
a different name when mail filtering is provided.                            |

What users may do in their .forward files can be constrained by various
options of the forwardfile director:

 .   If the filter option is not set, then only traditional .forward files
     are permitted.

 .   If the forbid_file option is set, then neither a traditional .forward
     file, nor a filter file may direct that a message be appended to a
     particular local file. An attempt to do so causes a delivery error.

 .   If the forbid_pipe option is set, then neither a traditional .forward
     file, nor a filter file may direct that a message be piped to a user-
     specified command. An attempt to do so causes a delivery error.

 .   If the forbid_reply option is set, then a filter file may not direct
     that a new mail message be created. An attempt to do so causes a
     delivery error.

If piping is permitted, the pipe transport that is used (conventionally
called address_pipe) can constrain the command to be taken from a particu-
lar set of files. Pipe commands generated from traditional .forward files    |
are not string-expanded, but when a pipe command is generated in a filter    |
file, each argument is separately expanded.                                  |

If delivery to specified files is permitted, the appendfile transport that
is used (conventionally called address_file) can specify that the file must
already exist, or can restrict the whereabouts of its creation by means of
the create_file option.



                   35. USING EXIM TO HANDLE MAILING LISTS


The forwardfile director 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 director option can be used to run these
lists in a separate domain from normal mail. For example:

  lists:
    driver = forwardfile,
    domains = lists.ref.book;
    file = /opt/lists/${local_part},
    no_check_local_user,
    forbid_pipe,
    forbid_file,
    no_more,
    errors_to = ${local_part}-request@lists.ref.book

The domain lists.ref.book must appear as one of the domains in the
local_domains configuration option. This director is used only when an
address refers to that domain. Because the no_more option is set, if the
local part of the address does not match a file in the /opt/lists
directory, causing the director to fail, no subsequent directors are tried,
and the whole delivery fails.

The no_check_local_user option stops Exim insisting that the local part is
the login id of a local user, and because no user or group is specified, no
check is made on the ownership of the file. The forbid_pipe and forbid_file
options prevent a local part from being expanded into a file name or a pipe
delivery.

The errors_to option specifies that an 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, mail sent to dicts@lists.ref.book is passed on to those addresses
contained in /opt/lists/dict with error reports directed to dicts-
request@lists.ref.book, provided that there is a file called
/opt/lists/dicts-request, presumably containing the address(es) of this
particular list's manager(s).

More complicated schemes can be set up, for example, by using the prefix or
suffix director options to handle addresses of the form xxx-request
differently.

It is not advisable to have list files that are NFS mounted, since the
absence of the mount cannot be distinguished from a non-existent file. One
way round this is to use an aliasfile director where the alias file is
local and contains a list of the lists, and each alias expansion is simply
an 'include' item to get the list from a separate, NFS mounted file. If
no_freeze_missing_include is set for the aliasfile director, an unavailable
file then just causes delivery to be deferred.



                            36. VIRTUAL DOMAINS


There are a number of ways in which virtual domains can be handled in Exim.
As this seems to be quite a common requirement, some ways of doing this are
described here. These are not the only possibilities.


36.1 All mail to a given host

Simply sending all mail for a domain to a given host isn't really a virtual
domain; it is just a routing requirement that can be handled by a
domainlist router.

To send all mail for a domain to a particular local part at a given host,
define the domain as local, then process it with a smartuser director that
sets the new delivery address and passes the message to an smtp transport
which specifies the host.


36.2 Virtual domain not preserving envelope

A virtual domain that does not preserve the envelope information when
delivering can be handled by an alias file defined for a local domain. If
you are handling a large number of local domains, you can define them as a
file lookup. For example:

  local_domains = "your.normal.domain:\
                   dbm;/customer/domains"

Where /customer/domains is a dbm file built from a source file that
contains just a list of domains:

  # list of virtual domains for customers
  customer1.domain
  customer2.domain

This can be turned into a dbm file by exim_dbmbuild.

You can then set up a director to handle the customer domains, arranging a
separate alias file for each domain. A single director can handle all of
them if the names follow a fixed pattern. Permissions can be arranged so
that appropriate people can edit the alias files. The domains option
ensures that this director is used only for the customer domains. The DBM
file lookup is cached, so it isn't too inefficient to do this. The no_more
setting ensures that if the lookup fails, Exim gives up on the address
without trying any subsequent directors.

  virtual:
    domains = dbm;/customer/domains,
    driver = aliasfile,
    no_more;
    file = /etc/mail/$domain,
    search_type = lsearch

A succesful aliasing operation results in a new envelope recipient address,
which is then directed or routed from scratch.


36.3 Virtual domain preserving envelope

If you want to arrange for mail for a given domain to be sent on to a host
that is dependent on the local part, without changing the envelope
recipient of the message, then the following is one way of doing it.

Set up the domains as local, and create an aliasfile director for them, as
above, but in addition, specify a transport for the director:

  virtual:
    domains = dbm;/customer/domains,
    driver = aliasfile,
    transport = virtual_smtp,
    no_more;
    file = /etc/mail/$domain,
    search_type = lsearch

Each domain has its own alias file, but the provision of a transport means
that this is used purely as a check list of local parts. The data portion
of each alias is not used.

The transport has to look up the appropriate host to which the message must
be sent:

  virtual_smtp:
    driver = smtp;
    hosts = ${lookup{$domain}dbm{/virtual/routes}{$value}fail}

The file /virtual/routes contains lines of the form

  customer1.domain:  cust1.host
  customer2.domain:  cust2.host

and the messages get delivered with RCPT TO (the envelope) containing the
original destination address (e.g. postmaster@customer1.domain). In fact,
you could use the same file for /virtual/routes and /customer/domains,
since the lookup on the latter doesn't make any use of the data - it's just
checking that the file contains the key.



                             37. EXIM UTILITIES


A number of utility scripts and programs are supplied with Exim. Most of
them are built as part of the normal building process, but the log file
analyser is entirely free-standing.


37.1 Querying Exim processes

The shell script called exiwhat first of all empties the processlog file in
Exim's log directory. It then uses the ps command to find all processes
running exim, and sends each one the SIGUSR1 signal. This causes each
process to write a single line describing its current activity to the
processlog file. The script waits a bit, then copies the file to the
standard output.

This facility is available only in operating systems where a signal handler
can be set up such that an interrupted system call is resumed when the
signal handler has finished. An example of typical output from exiwhat is

  164 0.12 daemon: -q1h, listening on port 25
10483 0.13 running queue: waiting for 0tAycK-0002ij-00 (10492)
10492 0.13 delivering 0tAycK-0002ij-00 to mail.ref.book [42.42.42.42]
  (editor@ref.book)
10592 0.12 handling incoming call from [245.211.243.242]
10628 0.13 accepting a local non-SMTP message

The first number in the output line is the process number; the second is
the Exim version number. The third line has been split here, in order to
fit it on the page. Because Exim processes run under a variety of uids, it
is necessary to run exiwhat as root in order to be able to send the signal
to all Exim processes.


37.2 Extracting log information

The exigrep utility is a Perl script, provided in the util directory, that
extracts from one or more log files all entries relevant to any message
whose log entries contain at least one that matches a given pattern. Thus
one can search for all mail for a given user or a given host, for example.
The usage is:

  exigrep [-l] <pattern> [<log file>] ...

where 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. If no file names are given on the command line, the
standard input is read.


37.3 Cycling log files

The exicyclog script cycles the main and reject log files. Each time it is
run the files get 'shuffled down' by one. The mainlog file becomes
mainlog.1, the previous mainlog.1 becomes mainlog.2 and so on, up to a
limit which is set in the script, and which defaults to 10. Reject logs are
handled similarly. Files that 'drop off' the end are deleted. All files
with numbers greater than 1 are compressed, using a compression command
which is configured in the script.

It is usual to run exicyclog daily from a crontab entry of the form

  1 0 * * *  /opt/exim/bin/exicyclog

In this way, each day's log is (mostly) in a separate file. There will be
some overlap from processes that have the log open at the time of renaming.

The exicyclog script can be run as the Exim user when one is defined, as
the log files will be owned by that user in that case. Otherwise it has to
be run as root.


37.4 Making DBM files

The exim_dbmbuild program reads an input file in the format of an alias
file (see chapter 18) and writes a DBM database using the lower-cased alias
names as keys and the remainder of the information as data. Two arguments
are required: the name of the input file (which can be a single hyphen to
indicate the standard input), and the base name of the output database. For
example:

  exim_dbmbuild /etc/aliases /etc/aliases

reads the system alias file and creates a DBM database using /etc/aliases
as the base name. In systems that use the ndbm routines, the database
consists of two files called (in this case) /etc/aliases.dir and
/etc/aliases.pag, while in systems using the db routines a single file
called /etc/aliases.db is used. The utility in fact creates the database
under a temporary name, and then renames the appropriate files.


37.5 Individual retry times

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. At present, the retry information is obtained by
running exim_dumpdb (see below) and post-processing the output. For
example:

  exinext piglet@milne.fict.book
  kanga.milne.fict.book:100.100.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.book:100.100.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

You can also give exinext a local local_part, without a domain, and it will
give any retry information for it. Exinext is not particularly efficient,
but then it isn't expected to be run very often.


37.6 Database maintenance

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:

 .   retry: the database of retry information

 .   reject: the database of information about rejected messages

 .   wait-smtp: the database of information about messages waiting for SMTP
     hosts

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:

  exim_dumpdb /var/spool/exim retry

Two lines of output are produced for each entry:

    T:mail.ref.book:242.242.242.242 146 77 Connection refused
  31-Oct-1995 12:00:12  02-Nov-1995 12:21:39  02-Nov-1995 20:21:39 *

The first item on the first line is the key of the record. It starts with
one of the letters D, R, or T, depending on whether it refers to a
directing, 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. 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 reject database consists of a
date and time, followed by the address that was rejected, followed by the
name of the host that sent the bad address (as given in the SMTP HELO
command).

Each output line from exim_dumpdb for the wait-smtp database 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.

The exim_tidydb utility program is used to tidy up the contents of the
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:

  exim_tidydb -t 7d /var/spool/exim retry

For the wait-smtp database, the -f option can also be used (it has no
effect for other databases). This causes a check to be made to ensure that
message ids in database records are those of messages that are still on the
queue. Other message ids are removed, and if this leaves records empty,
they are also removed.

The exim_tidydb utility outputs comments on the standard output whenever it
removes information from the database. It is suggested that it be run
periodically on all three databases, but at a quiet time of day, since it
requires a database to be locked (and therefore inaccessible to Exim) while
it does its work.

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 >
character. 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 the
reject and wait-smtp databases, 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:

  > 4 951102:1000

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.


37.7 Mail statistics

A Perl script called eximstats is supplied in the util directory. This
reads the files listed on its command line, which should be main log files,
and it 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 50 hosts in each category are
listed on the standard output.

The output also includes total counts and statistics about delivery errors,
and a histogram showing the number of deliveries made in each hour of the
day. A delivery with more than one address in its 'envelope' (e.g. an SMTP
transaction with more than one RCPT TO commands) 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 spool 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. An error report is      |
handled as an entirely separate message.                                     |
                                                                             |
If a message contains several recipients at the same remote site, then only  |
a single delivery is made to that site, and only one delivery is counted by  |
eximstats.                                                                   |



                            38. THE EXIM MONITOR


The Exim monitor is an application which displays in an X window infor-
mation about the state of Exim's queue and what Exim is doing. The monitor
is started up by running the script called eximon. This is a shell script
which sets up a number of parameters, and then runs the binary called
eximon.bin. The 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.

In order to see the contents of messages on the spool, and to operate on
them, eximon must either be run as root or by an admin user, that is, a
user who is a member of the Exim group (when one is defined).

The monitor's window is divided into three parts. The top section displays
a number of stripcharts, the first of which is always a count of messages
on the queue. The remaining ones 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.

It is also possible to have a stripchart which shows the percentage          |
fullness of a particular disc partition, which is useful when local          |
deliveries are confined to a single partition. This relies on the avail-     |
ability of the statvfs function or equivalent in the operating system.       |
Most, but not all versions of Unix that support Exim have this.              |

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.

Below the stripcharts there is an action button for quitting the monitor.
It is placed here so that shrinking the window to its default minimum size
leaves just the queue count stripchart and the quit button visible. Next to
this button is a button marked 'Size'. Pressing this 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, the
window is moved if it will not all be visible at the current position.
However, if 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.

The next big section of the window is an area in which a display of the
tail of the main log is displayed. This has a scroll bar at its lefthand
side which can be used to move back to look at earlier text, and the arrow
keys also have this effect. Similarly, there is a horizontal scroll bar for
accessing long log lines. Text can be cut from this part of the window
using the mouse in the normal way.

The final window section 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 frequency at which this is updated is
controlled by a parameter in the Local/eximon.conf file - the default is 5
minutes. There is an Update action button just above the display which can
be used to force an update of the queue display.

For each queued message, the length of time it has been on the queue, the
message id, the message sender, and the first undelivered recipient are
displayed on one line. If it is a delivery error message, the sender is
shown as <>. If there is more than one recipient to which the message has
not yet been delivered, subsquent 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. 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. 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. The title of the menu
is the message id, and it contains entries which act as follows:

 .   message log: The contents of the message log for the message are
     displayed in a new text window.

 .   headers: Information from the spool file that contains the envelope
     information and headers is displayed in a new text window. See chapter
     41 for a description of the format of spool files.

 .   body: The spool file containing the body of the message is displayed
     in a new text window.

 .   deliver message: A call to Exim is made using the -M option to request
     delivery of the message. 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.

 .   freeze: A call to Exim is made using the -Mf option to request that
     the message be frozen.

 .   thaw: A call to Exim is made using the -Mt option to request that the
     message be thawed.

 .   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 delivery failure
     report is generated for any remaining underlivered addresses.

 .   remove message: A call to Exim is made using the -Mrm option to
     request that the message be deleted from the system without generating
     any failure reports.

 .   add recipient: A dialog box is displayed into which a fully-qualified
     recipient address can be typed. 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.

 .   mark delivered: A dialog box is displayed into which a fully-qualified
     recipient address can be typed. 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.

 .   edit sender: A dialog box is displayed into which a fully-qualified
     address can be typed. This is 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.

 .   edit body: A new xterm process is forked in which a call to Exim is
     made using the -Meb option in order to allow the body of the message
     to be edited.

In cases when a call to Exim is made, the actual command used is reflected
in a new text window by default, but this can be turned off for all except
the delivery action by setting ACTION_OUTPUT=no in Local/eximon.conf.
However, if the call results in 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. The latter is automatically updated for actions such as
freezing and thawing.



                            39. SMTP PROCESSING


Two kinds of SMTP processing are supported: SMTP over TCP/IP, and so-called
'batched SMTP'. The latter is the name for a process in which batches of
messages are stored in files, using SMTP commands as separators and to
contain the envelope information. Such batches are delivered to or received
from other systems using some transport mechanism other than Exim. For each
kind of SMTP processing there are two aspects: outgoing and incoming.


39.1 Outgoing SMTP over TCP/IP

This is implemented by the smtp transport. Exim does not at present use
ESMTP for sending mail, as it has no facilities for using the information
it might get back. At some point in the future this may change.

If a message contains a number of different addresses, all those that
resolve to the same set of hosts are sent in a single SMTP transaction,
even if they are for different domains. 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.

When the smtp transport suffers a temporary failure while trying to deliver
a message, Exim updates its wait-smtp database, which contains records
indexed by host name that remember which messages are waiting for each
particular host.

When a message is successfully delivered over a TCP/IP SMTP connection,
Exim looks in the wait-smtp database 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 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. 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 batch_max option of the smtp transport can be used to limit the
number of messages sent down a single connection.


39.2 Incoming SMTP over TCP/IP

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:

  smtp  stream  tcp  nowait  exim  /opt/exim/bin/exim  in.exim  -bs

Exim distinguishes between this case and the case of a user agent using the
-bs option by checking whether the standard input is a socket.

The Exim daemon can limit the number of simultaneous incoming connections
it is prepared to handle (see the smtp_accept_max configuration option).
Additional connection attempts are rejected using the SMTP temporary error
code 421. On some operating systems the SIGCHLD signal that is used to
detect when a subprocess has finished can get lost at busy times. If this
happens, Exim may not accept as many incoming connections as expected. This
problem can be fixed by sending the daemon a SIGCHLD signal, which causes
it to notice all its completed subprocesses.

Exim can also reserve some SMTP slots for specific hosts or networks - for
details see the smtp_accept_reserve, smtp_reserve_hosts and
smtp_reserve_nets configuration options.

If the queue_only (or -odq option) option is not set, the daemon normally
starts a delivery process for each message received. However, the number of
simultaneously running delivery processes started in this way can be
limited by the smtp_accept_queue option. When the limit is reached,
subsequently received messages are just put on the input queue.

The two controls just described are not available when Exim is started up
from the inetd daemon, since each connection is handled by an entirely
separate Exim process.

It is possible to configure Exim to reject SMTP calls from certain hosts,
or from certain RFC 1413 ident values at particular hosts. This is achieved
by means of the sender_host_accept and sender_host_reject options. If the
first of these is set, Exim accepts only from a host (plus ident) that
matches; however, it rejects any call that matches sender_host_reject. Thus
sender_host_reject can be used to cut out exceptions from a wildcarded item
in sender_host_accept.

The format of the the accept and reject options is a colon-separated list
of entries, each of which is in one of the following formats:

  <host name>
  <IP address>
  <ident>@<host name>
  <ident>@<IP address>
  !<ident>@<host name>
  !<ident>@<IP address>

When an <ident> is preceded by an exclamation mark, it matches any other
RFC 1413 identification at the given host. Compare the following examples:

  sender_host_accept = root@hub.biog.book

accepts calls only from root on the host hub.biog.book, while

  sender_host_reject = !root@hub.biog.book

accepts calls from any host except those from hub.biog.book made by a non-
root user. The host names in these entries can be wildcarded, or can be
regular expressions. However, this flexibility is gained at the cost of
performance, particularly when a daemon listener is used.

If a complete host name is given, it is looked up in the DNS when the
daemon starts up, and subsequently the checks can be performed using only
the IP address. On the other hand, if a wildcarded name is given, the check
has to be performed by doing a reverse lookup on the IP address for each
call, in order to get the host name to match against the wildcarded string.
Therefore, it is best to avoid wild cards and regular expressions wherever
possible.

There are corresponding options which control connections on the basis of
IP network number. These are sender_net_accept and sender_net_reject. Each
entry consists of an IP network number and a mask, separated by a slash.
For example:

  sender_net_accept = 131.111.0.0/255.255.0.0
  sender_net_reject = 131.111.8.0/255.255.255.0

accepts calls only from the 131.111.0.0 network, unless the call is from
the 131.111.8.0 subnet. The host and net tests interact - for example, a
call from a network listed in sender_net_accept is rejected if the host
appears in sender_host_reject.

Incoming messages can also be rejected on the basis of the sender address,
as given in the MAIL FROM command. A list of senders to reject is set by
the sender_reject configuration option; see its description in chapter 9
for details.

The SMTP command VRFY is accepted only when the configuration option
smtp_verify is set, and if so, it runs exactly the same code as when Exim
is called with the -bv option. The SMTP commands EXPN and DEBUG are not
supported at all. Support for EXPN could be added if there were a demand
for it.


39.3 Unqualified addresses

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 require-
ment to accept unqualified addresses from specified hosts or IP networks.

Exim has two pairs of options that separately control which hosts or
networks may send unqualified sender or receiver addresses in SMTP com-
mands. The options are sender_unqualified_hosts and
sender_unqualified_nets, and receiver_unqualified_hosts and
receiver_unqualified_nets. In all cases, if an unqualified address is
accepted, it is qualified by adding the value of qualify_domain or
qualify_receiver, as appropriate.


39.4 Sender verification

When the sender_verify configuration option is set, Exim checks the senders
of incoming SMTP messages, that is, the addresses given in the SMTP MAIL
FROM commands. The check is performed by running the same verification code
as is used then Exim is called with the -bv option. The check is performed
when the MAIL FROM command is received. If the address cannot immediately
be verified (typically because of DNS timeouts), a temporary failure error
response (code 451) is given to the MAIL FROM command.

What happens if verification fails depends on the setting of the
sender_verify_reject option. If it is set (the default) then the message is
rejected. Otherwise a warning message is logged, and processing continues.

Because remote postmasters always want to see the message headers when
there is a problem, Exim does not give an error response immediately a
sender address fails, but instead it reads the data for the message first.
The headers of rejected messages are written to the rejectlog file, for use
in tracking down the problem or tracing mail abusers.

Unfortunately, there are a number of mailers in use that treat any SMTP
error response given after the data has been transmitted as a temporary
failure. Exim sends code 521 when it rejects a message because of a bad
sender, and RFC 821 is quite clear in stating that all codes starting with
5 are always 'permanent negative completion' replies. However, it does not
give any guidance as to what should be done on receiving such replies, and
some mailers persist in trying to send messages when they receive such a
code at the end of the data.

To get round this, Exim keeps a database in which it remembers the bad
sender address and host name when it rejects a message. If the same host
sends the same bad sender address within 24 hours, Exim rejects the message
at the MAIL FROM stage, before it reads the data for the message. This
should prevent the sender from trying to send the message again.

The sender_verify_except_hosts and sender_verify_except_nets options can be
used to specify hosts and RFC 1413 idents or IP networks for which sender
verification is not applied. If a cluster of hosts all check incoming
external messages, there is no need to waste effort checking mail sent
between them. The format of the data for sender_verify_except_hosts is the
same as described for the sender_host_accept and sender_host_reject option
in the previous section. For example:

  sender_verify_except_hosts  "*.ref.book:exim@mailer.fict.book"

It is unfortunately the case that lots of messages are sent out onto the
Internet with invalid senders, mainly as a result of mis-configured mailers
and gateways. In many cases, the message itself contains a valid return
address in one of its headers. If the sender_verify_fixup option is set as
well as sender_verify, Exim does not reject a message if the sender is
invalid, provided it can find a valid address in one of the Sender, Reply-
to, or From headers, which are checked in that order. Instead, it replaces
the sender with the valid address, and records the fact that it has done so
by adding a header of the form:

  X-BadReturnPath: <invalid address> rewritten using <name> header

This approach is, of course, fixing the symptom and not the disease.


39.5 Receiver verification

By default, Exim just checks the syntax of addresses given in the SMTP RCPT
TO command. This minimizes the time required for an SMTP message transfer,
and also makes it possible to provide special processing for unknown local
parts in local domains, by using a smartuser director to pass messages with
unknown local parts to a script or to another host.

Some installations, however, prefer to check receiver addresses as they are
received. If the receiver_verify option is set, the same code that is used
for verification by the -bv option is used to check incoming receiver
addresses. If verification fails, a permanent negative response is given to
the RCPT TO command if receiver_verify_reject is true (the default).
Otherwise the address is accepted, but a warning message is returned with
the 250 response code.


39.6 Outgoing batched SMTP

Both the appendfile and pipe transports can be used for handling batched
SMTP. Each has an option called bsmtp which, if set to anything other than
'none' causes the message to be output in SMTP format. The message is
written to the file or pipe preceded by the SMTP commands MAIL FROM and
RCPT TO, and followed by a line containing a single dot. Lines in the
message starting with a dot get an extra dot added. If the prefix or suffix
options are set, their contents are included inside the SMTP commands;
normally they would be specified as empty, to override the defaults. No
return-path header is ever added.

The value of the bsmtp option determines how multiple addresses in a single
message may be batched, if other conditions permit. If the value of bsmtp
is 'one', then there is no batching, and a copy of the message is output
for each address. If the value is 'domain' then a single copy (with
multiple RCPT TO commands) is output for all addresses that have the same
domain. If the value is 'all' then only a single copy of the message is
written. The batching is further constrained by other parameters:

 .   If any of the transport's expandable strings contain a reference to
     local_part, then no batching takes place.

 .   If any of the transport's expandable strings contains a reference to
     domain, then only domain batching is done.

 .   Addresses are not batched if they have different error addresses or
     different associated hosts.

 .   The transport must set the uid and gid for delivery. If at some future
     time routers are allowed to set the uid/gid, then batching can only
     occur for addresses that have the same uid/gid set up.

Here is an example of a transport and router for batched SMTP:

  # transport
  smtp_appendfile:
    driver = appendfile;
    directory = /var/bsmtp/${host},
    bsmtp = all,
    prefix =,
    suffix =,
    user = exim

  #router
  route_append:
    transport = smtp_appendfile,
    driver = domainlist;
    route_list = "some.domain batch.host"

This causes messages addressed to some.domain to be written in batched SMTP
format to /var/bsmtp/batch.host, with only a single copy of each message.
Note that prefix and suffix must be explicitly changed from their defaults.


39.7 Incoming batched SMTP

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. All
errors are reported by sending mail. If the caller is trusted, then the
senders in the MAIL FROM 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.
Receiver verification and administrative rejection is not done, even if
configured. HELO and EHLO act as RSET; VRFY, EXPN, HELP, and DEBUG act as
NOOP; QUIT quits.



                        40. SECURITY CONSIDERATIONS


This chapter discusses a number of issues concerned with security, some of
which are also covered in other parts of this manual.


40.1 Root privilege

The Exim binary has to start off running as root, and is therefore a setuid
program. Root privilege is required for two things:

 .   To set up a socket connected to the standard SMTP port (25) when
     initialising the listening daemon.

 .   To be able to change uid and gid in order to read forward files and
     perform local deliveries as the receiving user or as specified in the
     configuration.

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.

If no user is specified for Exim in either the compile-time or runtime
configuration files, then it runs as root all the time, except when
performing local deliveries. When an alternative user is specified, it
gives up root privilege when it can. Exactly how and when it does this
depends on whether the operating system supports the seteuid() or the
setresuid() function.

To avoid unnecessary complication, the discussion below talks about users,
and functions for setting the uid. It should be understood that in all
cases there is a corresponding group and gid, and that this is also changed
whenever the uid is changed. The description is written in terms of
seteuid(), since this is more common than setresuid(). However, it is
possible to specify at compile time that an operating system has
setresuid() and not seteuid().

On systems without seteuid(), Exim uses setuid() to give up root privilege
at certain times, at the expense of having to re-invoke itself (using exec)
in order to regain privilege. When seteuid() is available, there is a
configuration choice as to which method is used for temporarily giving up
the privilege. Using setuid() is more secure, but uses more resources.

Exim always uses setuid() to become a non-root user when running a local
delivery process. This applies whether or not an Exim user is defined. The
following discussion applies only when an Exim user is defined; if it is
not, Exim runs as root except when doing local deliveries.

Exim always uses setuid() to change to the Exim user before doing remote
deliveries. These are the last things a delivery process does, so it does
not need to regain root privilege again.

For other operations, the security configuration option controls whether
Exim uses setuid() or seteuid(). It can be set to one of three strings:

 .   seteuid: Exim uses seteuid() to give up root temporarily when it does
     not need it, and to regain the privilege subsequently. This enables it
     to run with a non-root effective uid most of the time, at very little
     cost.

 .   setuid: Exim uses setuid() to give up root when it is receiving a
     locally generated message, and after it has set up a listening socket
     when running as a daemon. This means that, in order to deliver a
     message that it has received, it has to re-invoke a fresh copy of
     itself to regain root privilege. During delivery, it retains root
     except when actually transporting the message. In particular, it runs
     the directors and routers as root. Setuid() is generally reckoned to
     be more secure than seteuid() but running this way uses more
     resources.

 .   setuid+seteuid: Exim uses setuid() as described immediately above, but
     in addition, it uses seteuid() to give up root privilege temporarily
     when it needs to regain it subsequently without losing a lot of state
     information, for example, while running the directors and routers.

On systems that do not support the seteuid() function, the only possible
value for the security option is 'setuid', and this is the default on such
systems if an Exim user is defined. Otherwise the default is
'setuid+seteuid' - the most secure setting.


40.2 Reading forward files

When forward files are read from users' home directories and those home
directories are NFS mounted without root privilege, even a program running
as root cannot read a forward file that does not have world read access.

If the seteuid() function is being used as described in the previous
section, so that Exim is not root when running the directors, then the
forwardfile director automatically uses seteuid() to become the local user
when attempting to read a file in a user's home directory. If seteuid() is
not being used generally, but is available in the operating system, the
forwardfile director can be configured to make use of it when reading files
in home directories.

The forwardfile director does not necessarily have to read from users' home
directories as obtained from getpwnam(). It can be given a directory
explicitly, and a specific associated user and group. The above remarks are
applicable in this case also.

On systems that do not have seteuid(), the only way to support forward
files on NFS file systems that do not export root is to insist that the
files be world readable.

Forward files are permitted to contain :include: items unless forbidden by
setting forbid_include in the director. If seteuid() is being used to read
the forward file, then any included files are read as the same user.
Otherwise Exim is running as root, and it insists that any included files
are within the same directory as the forward file, and that there are no
symbolic links below the directory. If no directory is specified (either
explicitly or by looking up a local user's home directory) then included
files are not permitted when seteuid() is not in use.

When the filtering option is enabled for forward files, users can construct  |
pipe commands that contain data from the incoming message by quoting         |
variables such as $sender_address. To prevent the contents of inserted data  |
from interfering with a command, the string expansion is done after the      |
command line is split up into separate arguments, and the command is run     |
directly instead of passing the command line to a shell.                     |


40.3 Delivering to local files

Full details of the checks applied by appendfile before it writes to a file
are given in chapter 12 above.


40.4 Trusted and admin users

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.

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.

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 (if defined), as any user listed in the
trusted_users configuration option, or under any group listed in the
trusted_group 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, or remove them entirely. 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.

Exim recognises an admin user if the calling process is running as root or
as the Exim user (if defined) or if any of the groups associated with the
calling process is the Exim group (if defined). It is not necessary
actually to be running under the Exim group. However, if admin users who
are not root or exim 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.


40.5 Spool files

If a uid and gid are defined for Exim, then the spool directory and
everything it contains will be owned by exim and have its group set to
exim. The mode for spool files is defined in the Local/Makefile configur-
ation file, and defaults to 0600. This should normally be changed to 0640
if a uid and gid are defined for Exim, to allow access to spool files via
the Exim monitor by other members of the exim group.


                         41. FORMAT OF SPOOL FILES


A message on Exim's spool consists of two files. The data portion of the
message is kept in a file of its own, on which no processing is ever done.
The message's 'envelope', status, and headers are all kept in the other
file, whose format is described here.

The first line of the file contains the login id of the process that called
Exim to create the file, followed by the numerical uid and gid. For a
locally generated message, this is normally the user who sent the message.
For an external message, the user is either root or Exim.

The second line of the file contains the address of the message's sender as
transmitted on the 'envelope', contained in angle brackets. In the case of
incoming SMTP mail, this is the address given in the MAIL FROM command. For
locally generated mail, the sender address is created by Exim from the
login of the current user and the configured qualify_domain, except when
Exim is called by a trusted user that supplied a sender address via the -f
option. The sender address is null if the message is a delivery failure
report.

The third line contains two numbers. The first is the time that the message
was received, in the form supplied by the Unix time() function - a 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 optional lines, each of which starts with a hyphen
when present. These can appear in any order:

 .   -frozen <time>: The message is frozen, and the freezing happened at
     <time>. No deliveries will be attempted while the message remains
     frozen, but the auto_thaw configuration option can specify a time
     delay after which a delivery will be attempted.

 .   -local: The message is from a local sender.

 .   -localerror: The message is a locally-generated delivery error report.

 .   -resent: The message contains Resent- headers, so the alternative set
     of header names is to be used (see RFC 822).

Following the options are 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; 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 completed.

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:

  YY darcy@austen.fict.book
  NN alice@wonderland.fict.book
  NN editor@thesaurus.ref.book

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. For example,

  4
  editor@thesaurus.ref.book
  darcy@austen.fict.book
  rdo@foundation
  alice@wonderland.fict.book

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:

  <blank>  header in which Exim has no special interest
   B       Bcc header
   C       Cc header
   F       From header
   P       Received header - P for 'postmark'
   R       Reply-to header
   S       Sender header
   T       To header
   *       replaced or deleted header

Deleted or replaced (rewritten) headers remain in the spool file for
debugging purposes. They are not transmitted when the message is delivered.
When Resent- headers are present, it is those headers that have the
appropriate flags. Here is a typical set of headers:

  111P Received: by hobbit.fict.book with local (Exim 0.17 #8)
          id E0tHplY-0000mG-00; Tue, 21 Nov 1995 10:17:32 +0000
  049  Message-Id: <E0tHplY-0000mG-00@hobbit.fict.book>
  038* X-rewrote-sender: bb@hobbit.fict.book
  042* From: Bilbo Baggins <bb@hobbit.fict.book>
  049F From: Bilbo Baggins <B.Baggins@hobbit.fict.book>
  099* To: alice@wonderland.fict.book, rdo@foundation,
   darcy@austen.fict.book, editor@thesaurus.ref.book
  109T To: alice@wonderland.fict.book, rdo@foundation.fict.book,
   darcy@austen.fict.book, editor@thesaurus.ref.book
  038  Date: Tue, 21 Nov 1995 10:17:32 +0000

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.



                       42. ADDING NEW DRIVERS TO EXIM


The following actions have to be taken in order to add a new director,
router, or transport to Exim:

 .   Choose a name for the driver that does not conflict with any existing
     name; I will use 'newdriver' in what follows.

 .   Add to src/EDITME one of the lines

       <type>_NEWDRIVER=yes

     where <type> is DIRECTOR or ROUTER or TRANSPORT, depending on the type
     of driver. If the driver is not to be included in the binary by
     default, comment this line out. It may also be worth adding comments
     about the driver.

 .   Add to src/config.h.defaults the line

       #define <type>_NEWDRIVER

 .   Edit src/drtables.c. Add in conditional code to pull in the driver's
     header and create a table entry as is done for all the other drivers.

 .   Edit Makefile in the appropriate subdirectory (directors, routers, or
     transports); add a line for the new driver and add it to the
     definition of OBJ.

 .   Create newdriver.h and newdriver.c in the appropriate subdirectory of
     src.

 .   Edit scripts/MakeLinks and add commands to link the .h and .c files as
     for other drivers.

Then all you need to do is write the code! A good way to start is to make a
proforma by copying an existing driver of the same type, globally changing
all occurrences of the name, and cutting out most of the code.

