+lists_closed:
+ driver = redirect
+ domains = lists.example
+ allow_fail
+ data = :fail: $local_part@lists.example is a closed mailing list
+.endd
+All three routers have the same \domains\ setting, so for any other domains,
+they are all skipped. The first router runs only if the local part ends in
+\@-request\. It handles messages to the list manager(s) by means of an open
+mailing list.
+
+The second router runs only if the \senders\ precondition is satisfied. It
+checks for the existence of a list that corresponds to the local part, and then
+checks that the sender is on the list by means of a linear search. It is
+necessary to check for the existence of the file before trying to search it,
+because otherwise Exim thinks there is a configuration error. If the file does
+not exist, the expansion of \senders\ is $*$, which matches all senders. This
+means that the router runs, but because there is no list, declines, and
+\no@_more\ ensures that no further routers are run. The address fails with an
+`unrouteable address' error.
+
+The third router runs only if the second router is skipped, which happens when
+a mailing list exists, but the sender is not on it. This router forcibly fails
+the address, giving a suitable error message.
+
+
+
+.section Virtual domains
+.rset SECTvirtualdomains "~~chapter.~~section"
+.index virtual domains
+.index domain||virtual
+The phrase \*virtual domain*\ is unfortunately used with two rather different
+meanings:
+.numberpars $.
+A domain for which there are no real mailboxes; all valid local parts are
+aliases for other email addresses. Common examples are organizational
+top-level domains and `vanity' domains.
+.nextp
+One of a number of independent domains that are all handled by the same host,
+with mailboxes on that host, but where the mailbox owners do not necessarily
+have login accounts on that host.
+.endp
+The first usage is probably more common, and does seem more `virtual' than the
+second. This kind of domain can be handled in Exim with a straightforward
+aliasing router. One approach is to create a separate alias file for each
+virtual domain. Exim can test for the existence of the alias file to determine
+whether the domain exists. The \%dsearch%\ lookup type is useful here, leading
+to a router of this form:
+.display asis
+virtual:
+ driver = redirect
+ domains = dsearch;/etc/mail/virtual
+ data = ${lookup{$local_part}lsearch{/etc/mail/virtual/$domain}}
+ no_more
+.endd
+The \domains\ option specifies that the router is to be skipped, unless there
+is a file in the \(/etc/mail/virtual)\ directory whose name is the same as the
+domain that is being processed. When the router runs, it looks up the local
+part in the file to find a new address (or list of addresses). The \no@_more\
+setting ensures that if the lookup fails (leading to \data\ being an empty
+string), Exim gives up on the address without trying any subsequent routers.
+
+This one router can handle all the virtual domains because the alias file names
+follow a fixed pattern. Permissions can be arranged so that appropriate people
+can edit the different alias files. A successful aliasing operation results in
+a new envelope recipient address, which is then routed from scratch.
+
+The other kind of `virtual' domain can also be handled in a straightforward
+way. One approach is to create a file for each domain containing a list of
+valid local parts, and use it in a router like this:
+.display asis
+my_domains:
+ driver = accept
+ domains = dsearch;/etc/mail/domains
+ local_parts = lsearch;/etc/mail/domains/$domain
+ transport = my_mailboxes
+.endd
+The address is accepted if there is a file for the domain, and the local part
+can be found in the file. The \domains\ option is used to check for the file's
+existence because \domains\ is tested before the \local@_parts\ option (see
+section ~~SECTrouprecon). You can't use \require@_files\, because that option
+is tested after \local@_parts\. The transport is as follows:
+.display asis
+my_mailboxes:
+ driver = appendfile
+ file = /var/mail/$domain/$local_part
+ user = mail
+.endd
+This uses a directory of mailboxes for each domain. The \user\ setting is
+required, to specify which uid is to be used for writing to the mailboxes.
+
+The configuration shown here is just one example of how you might support this
+requirement. There are many other ways this kind of configuration can be set
+up, for example, by using a database instead of separate files to hold all the
+information about the domains.
+
+
+.section Multiple user mailboxes
+.rset SECTmulbox "~~chapter.~~section"
+.index multiple mailboxes
+.index mailbox||multiple
+.index local part||prefix
+.index local part||suffix
+Heavy email users often want to operate with multiple mailboxes, into which
+incoming mail is automatically sorted. A popular way of handling this is to
+allow users to use multiple sender addresses, so that replies can easily be
+identified. Users are permitted to add prefixes or suffixes to their local
+parts for this purpose. The wildcard facility of the generic router options
+\local@_part@_prefix\ and \local@_part@_suffix\ can be used for this. For
+example, consider this router:
+.display asis
+userforward:
+ driver = redirect
+ check_local_user
+ file = $home/.forward
+ local_part_suffix = -*
+ local_part_suffix_optional
+ allow_filter
+.endd
+It runs a user's \(.forward)\ file for all local parts of the form
+\*username-$*$*\. Within the filter file the user can distinguish different
+cases by testing the variable \$local@_part@_suffix$\. For example:
+.display asis
+if $local_part_suffix contains -special then
+ save /home/$local_part/Mail/special
+endif
+.endd
+If the filter file does not exist, or does not deal with such addresses, they
+fall through to subsequent routers, and, assuming no subsequent use of the
+\local@_part@_suffix\ option is made, they presumably fail. Thus, users have
+control over which suffixes are valid.
+
+Alternatively, a suffix can be used to trigger the use of a different
+\(.forward)\ file -- which is the way a similar facility is implemented in
+another MTA:
+.display asis
+userforward:
+ driver = redirect
+ check_local_user
+ file = $home/.forward$local_part_suffix
+ local_part_suffix = -*
+ local_part_suffix_optional
+ allow_filter
+.endd
+If there is no suffix, \(.forward)\ is used; if the suffix is \*-special*\, for
+example, \(.forward-special)\ is used. Once again, if the appropriate file
+does not exist, or does not deal with the address, it is passed on to
+subsequent routers, which could, if required, look for an unqualified
+\(.forward)\ file to use as a default.
+
+
+.section Simplified vacation processing
+.index vacation processing
+The traditional way of running the \*vacation*\ program is for a user to set up
+a pipe command in a \(.forward)\ file
+(see section ~~SECTspecitredli for syntax details).
+This is prone to error by inexperienced users. There are two features of Exim
+that can be used to make this process simpler for users:
+.numberpars $.
+A local part prefix such as `vacation-' can be specified on a router which
+can cause the message to be delivered directly to the \*vacation*\ program, or
+alternatively can use Exim's \%autoreply%\ transport. The contents of a user's
+\(.forward)\ file are then much simpler. For example:
+.display asis
+spqr, vacation-spqr
+.endd
+.nextp
+The \require@_files\ generic router option can be used to trigger a
+vacation delivery by checking for the existence of a certain file in the
+user's home directory. The \unseen\ generic option should also be used, to
+ensure that the original delivery also proceeds. In this case, all the user has
+to do is to create a file called, say, \(.vacation)\, containing a vacation
+message.
+.endp
+Another advantage of both these methods is that they both work even when the
+use of arbitrary pipes by users is locked out.