diff options
author | Nigel Metheringham <nigel@exim.org> | 2008-01-17 13:14:07 +0000 |
---|---|---|
committer | Nigel Metheringham <nigel@exim.org> | 2008-01-17 13:14:07 +0000 |
commit | 0caec8e792b969ca442413e75c8966f074bc5fd4 (patch) | |
tree | 8c6c0c4699af5a93efad24657972d1de0a167f05 /doc/doc-src/filter.src | |
parent | 8fde9903e121cba1a4381d7126d6642561b2af4c (diff) |
Removed old documentation source files to prevent confusion. Fixes: #658
Diffstat (limited to 'doc/doc-src/filter.src')
-rw-r--r-- | doc/doc-src/filter.src | 1735 |
1 files changed, 0 insertions, 1735 deletions
diff --git a/doc/doc-src/filter.src b/doc/doc-src/filter.src deleted file mode 100644 index 8688721af..000000000 --- a/doc/doc-src/filter.src +++ /dev/null @@ -1,1735 +0,0 @@ -. $Cambridge: exim/doc/doc-src/filter.src,v 1.2 2005/01/11 15:17:51 ph10 Exp $ -. -.if !set style -.library "a4ps" -.linelength ~~sys.linelength + 0.2in -.emphasis ~~sys.linelength + 0.1in -.pagedepth ~~sys.pagedepth - 0.2in -.bindfont 53 "atl/Times-Roman" 7 -.set ssspaceb 1.50 -.fi - -.include "markup.sg" - -.set sgcal true -.set html false -.set texinfo false - - -.if ~~sys.fancy -.flag $sm{ "$push$g0$f53" -. -.else -.pagedepth ~~sys.pagedepth - 1ld -.linelength 75em -.emphasis 77em -.footdepth 0 -.disable formfeed -.backspace none -.set chapspaceb 24 -.set sspacea 24 -.flag $sm{ "$push" -.fi - -.macro tabs 6 -.if ~~sys.fancy -.tabset ~~1em -.else -.set temp (~~1 * 5)/4 -.tabset ~~temp em -.fi -.endm - -.macro startitems -.newline -.push -.indent 3em -.endm - -.macro enditems -.newline -.pop -.endm - -.macro item "item" -.newpar -.if ~~sys.leftonpage < 5ld -.newpage -.fi -.tempindent 0 -\~~1\ -.blank -.endm - -.macro index -.endm - -.set contents false -.set displayindent 2em - - -. ====================================================== - - -.if ~~sys.fancy -.footdepth 2ld -.foot -$c[~~sys.pagenumber]$e -.endfoot -.fi - - -.set chapter -1 -.chapter Exim's interfaces to mail filtering -.space -2ld -This document describes the user interfaces to Exim's in-built mail filtering -facilities, and is copyright (c) University of Cambridge 2005. It corresponds -to Exim version 4.50. -.rule - -. --------------------------------------------------------------------------- -. Some clever jiggery-pokery here. The contents list is known to be less than -. one page long, so we arrange for it to get onto the rest of the first page. -. Because we aren't doing any indexing, the z-rawindex file will contain only -. the TOC entries. The Makefile arranges for it to be empty at the start, then -. runs SGCAL twice so on the second pass it gets inserted automatically. - -.if ~~sgcal -.space 1ld -. $chead{Contents} -. space 1ld -.tabset 2em 2em -.push -.linedepth ~~sys.linedepth - 1 -.include "z-rawindex" -.newline -.pop -.newpage -.set contents true -.fi -. --------------------------------------------------------------------------- - - -.set chapter 0 -.chapter Forwarding and filtering in Exim - - -.section Introduction -Most Unix mail transfer agents (programs that deliver mail) permit individual -users to specify automatic forwarding of their mail, usually by placing a list -of forwarding addresses in a file called \(.forward)\ in their home directories. -Exim extends this facility by allowing the forwarding instructions to be a set -of rules rather than just a list of addresses, in effect providing `\(.forward)\ -with conditions'. Operating the set of rules is called $it{filtering}, and the -file that contains them is called a $it{filter file}. - -Exim supports two different kinds of filter file. An \*Exim filter*\ contains -instructions in a format that is unique to Exim. A \*Sieve filter*\ contains -instructions in the Sieve format that is defined by RFC 3028. As this is a -standard format, Sieve filter files may already be familiar to some users. -Sieve files should also be portable between different environments. However, -the Exim filtering facility contains more features (such as variable -expansion), and better integration with the host environment (such as the use -of external processes and pipes). - -The choice of which kind of filter to use can be left to the end-user, provided -that the system administrator has configured Exim appropriately for both kinds -of filter. However, if interoperability is important, Sieve is the only -choice. - -The ability to use filtering or traditional forwarding has to be enabled by the -system administrator, and some of the individual facilities can be separately -enabled or disabled. A local document should be provided to describe exactly -what has been enabled. In the absence of this, consult your system -administrator. - -This document describes how to use a filter file and the format of its -contents. It is intended for use by end-users. Both Sieve filters and Exim -filters are covered. However, for Sieve filters, only issues that relate to the -Exim implementation are discussed, since Sieve itself is described elsewhere. - -The contents of traditional \(.forward)\ files are not described here. They -normally contain just a list of addresses, file names, or pipe commands, -separated by commas or newlines, but other types of item are also available. -The full details can be found in the chapter on the \%redirect%\ router in the -Exim specification, which also describes how the system administrator can set -up and control the use of filtering. - - -.em -.section Filter operation -It is important to realize that, in Exim, no deliveries are actually made while -a filter or traditional \(.forward)\ file is being processed. Running a filter -or processing a traditional \(.forward)\ file sets up future delivery -operations, but does not carry them out. - -The result of filter or \(.forward)\ file processing is a list of destinations -to which a message should be delivered. The deliveries themselves take place -later, along with all other deliveries for the message. This means that it is -not possible to test for successful deliveries while filtering. It also means -that any duplicate addresses that are generated are dropped, because Exim never -delivers the same message to the same address more than once. -.nem - - -.section Testing a new filter file -.rset SECTtesting "~~chapter.~~section" -Filter files, especially the more complicated ones, should always be tested, as -it is easy to make mistakes. Exim provides a facility for preliminary testing -of a filter file before installing it. This tests the syntax of the file and -its basic operation, and can also be used with traditional \(.forward)\ files. - -Because a filter can do tests on the content of messages, a test message is -required. Suppose you have a new filter file called \(myfilter)\ and a test -message called \(test-message)\. Assuming that Exim is installed with the -conventional path name \(/usr/sbin/sendmail)\ (some operating systems use -\(/usr/lib/sendmail)\), the following command can be used: -.display asis -/usr/sbin/sendmail -bf myfilter <test-message -.endd -The \-bf-\ option tells Exim that the following item on the command line is the -name of a filter file that is to be tested. There is also a \-bF-\ option, -which is similar, but which is used for testing system filter files, as opposed -to user filter files, and which is therefore of use only to the system -administrator. - -The test message is supplied on the standard input. If there are no -message-dependent tests in the filter, an empty file (\(/dev/null)\) can be -used. A supplied message must start with header lines or the `From' message -separator line which is found in many multi-message folder files. Note that -blank lines at the start terminate the header lines. A warning is given if no -header lines are read. - -The result of running this command, provided no errors are detected in the -filter file, is a list of the actions that Exim would try to take if presented -with the message for real. -For example, for an Exim filter, the output -.display asis -Deliver message to: gulliver@lilliput.fict.example -Save message to: /home/lemuel/mail/archive -.endd -means that one copy of the message would be sent to -\gulliver@@lilliput.fict.example\, and another would be added to the file -\(/home/lemuel/mail/archive)\, if all went well. - -The actions themselves are not attempted while testing a filter file in this -way; there is no check, for example, that any forwarding addresses are valid. -For an Exim filter, -if you want to know why a particular action is being taken, add the \-v-\ -option to the command. This causes Exim to output the results of any -conditional tests and to indent its output according to the depth of nesting of -\"if"\ commands. Further additional output from a filter test can be generated -by the \"testprint"\ command, which is described below. - -When Exim is outputting a list of the actions it would take, if any text -strings are included in the output, non-printing characters therein are -converted to escape sequences. In particular, if any text string contains a -newline character, this is shown as `@\n' in the testing output. - -When testing a filter in this way, Exim makes up an `envelope' for the message. -The recipient is by default the user running the command, and so is the sender, -but the command can be run with the \-f-\ option to supply a different sender. -For example, -.display -.indent 0 -/usr/sbin/sendmail -bf myfilter -f islington@@never.where <test-message -.endd -Alternatively, if the \-f-\ option is not used, but the first line of the -supplied message is a `From' separator from a message folder file (not the same -thing as a \"From:"\ header line), the sender is taken from there. If \-f-\ is -present, the contents of any `From' line are ignored. - -The `return path' is the same as the envelope sender, unless the message -contains a \"Return-path:"\ header, in which case it is taken from there. You -need not worry about any of this unless you want to test out features of a -filter file that rely on the sender address or the return path. - -It is possible to change the envelope recipient by specifying further options. -The \-bfd-\ option changes the domain of the recipient address, while the -\-bfl-\ option changes the `local part', that is, the part before the @@ sign. -An adviser could make use of these to test someone else's filter file. - -The \-bfp-\ and \-bfs-\ options specify the prefix or suffix for the local part. -These are relevant only when support for multiple personal mailboxes is -implemented; see the description in section ~~SECTmbox below. - -.section Installing a filter file -A filter file is normally installed under the name \(.forward)\ in your home -directory -- it is distinguished from a conventional \(.forward)\ file by its -first line (described below). However, the file name is configurable, and some -system administrators may choose to use some different name or location for -filter files. - -.section Testing an installed filter file -Testing a filter file before installation cannot find every potential problem; -for example, it does not actually run commands to which messages are piped. -Some `live' tests should therefore also be done once a filter is installed. - -If at all possible, test your filter file by sending messages from some other -account. If you send a message to yourself from the filtered account, and -delivery fails, the error message will be sent back to the same account, which -may cause another delivery failure. It won't cause an infinite sequence of such -messages, because delivery failure messages do not themselves generate further -messages. However, it does mean that the failure won't be returned to you, and -also that the postmaster will have to investigate the stuck message. - -If you have to test an Exim filter from the same account, a sensible precaution -is to include the line -.display asis -if error_message then finish endif -.endd -as the first filter command, at least while testing. This causes filtering to -be abandoned for a delivery failure message, and since no destinations are -generated, the message goes on to be delivered to the original address. Unless -there is a good reason for not doing so, it is recommended that the above test -be left in all Exim filter files. -(This does not apply to Sieve files.) - - -.section Details of filtering commands -The filtering commands for Sieve and Exim filters are completely different in -syntax and semantics. The Sieve mechanism is defined in RFC 3028; in the next -chapter we describe how it is integrated into Exim. The subsequent chapter -covers Exim filtering commands in detail. - - -. -. -. -. -. -.chapter Sieve filter files -.rset CHAPsievefilter "~~chapter" -The code for Sieve filtering in Exim was contributed by Michael Haardt, and -most of the content of this chapter is taken from the notes he provided. Since -Sieve is a extensible language, it is important to understand `Sieve' in this -context as `the specific implementation of Sieve for Exim'. - -This chapter does not contain a description of Sieve, since that can be found -in RFC 3028, which should be read in conjunction with these notes. - -The Exim Sieve implementation offers the core as defined by RFC 3028, -.em -comparison tests, the \%copy%\, \%envelope%\, \%fileinto%\, and \%vacation%\ -extensions, -.nem -but not the \%reject%\ extension. Exim does not support message delivery -notifications (MDNs), so adding it just to the Sieve filter (as required for -\%reject%\) makes little sense. - -In order for Sieve to work properly in Exim, the system administrator needs to -make some adjustments to the Exim configuration. These are described in the -chapter on the \%redirect%\ router in the full Exim specification. - -.section Recognition of Sieve filters -A filter file is interpreted as a Sieve filter if its first line is -.display asis -# Sieve filter -.endd -This is what distinguishes it from a conventional \(.forward)\ file or an Exim -filter file. - - -.section Saving to specified folders -If the system administrator has set things up as suggested in the Exim -specification, and you use \%keep%\ or \%fileinto%\ to save a mail into a -folder, absolute files are stored where specified, relative files are stored -relative to \$home$\, and \%inbox%\ goes to the standard mailbox location. - - -.section Strings containing header names -RFC 3028 does not specify what happens if a string denoting a header field does -not contain a valid header name, for example, it contains a colon. This -implementation generates an error instead of ignoring the header field in order -to ease script debugging, which fits in the common picture of Sieve. - - -.section Exists test with empty list of headers -The \%exists%\ test succeeds only if all specified headers exist. RFC 3028 -does not explicitly specify what happens on an empty list of headers. This -implementation evaluates that condition as true, interpreting the RFC in a -strict sense. - - -.section Header test with invalid MIME encoding in header -Some MUAs process invalid base64 encoded data, generating junk. -Others ignore junk after seeing an equal sign in base64 encoded data. -RFC 2047 does not specify how to react in this case, other than stating -that a client must not forbid to process a message for that reason. -RFC 2045 specifies that invalid data should be ignored (apparently -looking at end of line characters). It also specifies that invalid data -may lead to rejecting messages containing them (and there it appears to -talk about true encoding violations), which is a clear contradiction to -ignoring them. - -RFC 3028 does not specify how to process incorrect MIME words. -This implementation treats them literally, as it does if the word is -correct but its character set cannot be converted to UTF-8. - - -.section Address test for multiple addresses per header -A header may contain multiple addresses. RFC 3028 does not explicitly -specify how to deal with them, but since the address test checks if -anything matches anything else, matching one address suffices to -satisfy the condition. That makes it impossible to test if a header -contains a certain set of addresses and no more, but it is more logical -than letting the test fail if the header contains an additional address -besides the one the test checks for. - - -.section Semantics of keep -The \%keep%\ command is equivalent to -.display -fileinto "inbox"; -.endd -It saves the message and resets the implicit keep flag. It does not set the -implicit keep flag; there is no command to set it once it has been reset. - - -.section Semantics of fileinto -RFC 3028 does not specify whether \fileinto\ should try to create a mail folder -if it does not exist. This implementation allows the sysadmin to configure that -aspect using the \%appendfile%\ transport options \create@_directory\, -\create@_file\, and \file@_must@_exist\. See the \%appendfile%\ transport in -the Exim specification for details. - - -.section Semantics of redirect -Sieve scripts are supposed to be interoperable between servers, so this -implementation does not allow mail to be redirected to unqualified addresses, -because the domain would depend on the system being used. On systems with -virtual mail domains, the default domain is probably not what the user expects -it to be. - - -.section String arguments -There has been confusion if the string arguments to \%require%\ are to be -matched case-sensitively or not. This implementation matches them with -the match type \":is"\ (default, see section 2.7.1) and the comparator -\"i;ascii-casemap"\ (default, see section 2.7.3). The RFC defines the -command defaults clearly, so any different implementations violate RFC -3028. The same is valid for comparator names, also specified as strings. - - -.section Number units -There is a mistake in RFC 3028: the suffix G denotes gibi-, not tebibyte. -The mistake is obvious, because RFC 3028 specifies G to denote 2@^30 -(which is gibi, not tebi), and that is what this implementation uses as -scaling factor for the suffix G. - - -.section RFC compliance -Exim requires the first line of a Sieve filter to be -.display asis -# Sieve filter -.endd -Of course the RFC does not specify that line. Do not expect examples to work -without adding it, though. - -RFC 3028 requires the use of CRLF to terminate a line. -The rationale was that CRLF is universally used in network protocols -to mark the end of the line. This implementation does not embed Sieve -in a network protocol, but uses Sieve scripts as part of the Exim MTA. -Since all parts of Exim use LF as newline character, this implementation -does, too, by default, though the system administrator may choose (at Exim -compile time) to use CRLF instead. - -Exim violates RFC 2822, section 3.6.8, by accepting 8-bit header names, so -this implementation repeats this violation to stay consistent with Exim. -This is in preparation to UTF-8 data. - -Sieve scripts cannot contain NUL characters in strings, but mail -headers could contain MIME encoded NUL characters, which could never -be matched by Sieve scripts using exact comparisons. For that reason, -this implementation extends the Sieve quoted string syntax with @\0 -to describe a NUL character, violating @\0 being the same as 0 in -RFC 3028. Even without using @\0, the following tests are all true in -this implementation. Implementations that use C-style strings will only -evaluate the first test as true. -.display asis -Subject: =?iso-8859-1?q?abc=00def - -header :contains "Subject" ["abc"] -header :contains "Subject" ["def"] -header :matches "Subject" ["abc?def"] -.endd - -Note that by considering Sieve to be a MUA, RFC 2047 can be interpreted -in a way that NUL characters truncating strings is allowed for Sieve -implementations, although not recommended. It is further allowed to use -encoded NUL characters in headers, but that's not recommended either. -The above example shows why. - -RFC 3028 states that if an implementation fails to convert a character -set to UTF-8, two strings cannot be equal if one contains octets greater -than 127. Assuming that all unknown character sets are one-byte character -sets with the lower 128 octets being US-ASCII is not sound, so this -implementation violates RFC 3028 and treats such MIME words literally. -That way at least something could be matched. - -The folder specified by \%fileinto%\ must not contain the character -sequence \".."\ to avoid security problems. RFC 3028 does not specify the -syntax of folders apart from \%keep%\ being equivalent to -.display asis -fileinto "INBOX"; -.endd -This implementation uses \"inbox"\ instead. - -Sieve script errors currently cause messages to be silently filed into -\"inbox"\. RFC 3028 requires that the user is notified of that condition. -This may be implemented in future by adding a header line to mails that -are filed into \"inbox"\ due to an error in the filter. - - -. -. -. -. -. -.chapter Exim filter files -.rset CHAPeximfilter "~~chapter" -This chapter contains a full description of the contents of Exim filter files. - -.section Format of Exim filter files -Apart from leading white space, the first text in a filter file must be -.display asis -# Exim filter -.endd -This is what distinguishes it from a conventional \(.forward)\ file or a Sieve -filter file. If the file does not have this initial line (or the equivalent for -a Sieve filter), it is treated as a -conventional \(.forward)\ file, both when delivering mail and when using the -\-bf-\ testing mechanism. The white space in the line is optional, and any -capitalization may be used. Further text on the same line is treated as a -comment. For example, you could have -.display asis -# Exim filter <<== do not edit or remove this line! -.endd -The remainder of the file is a sequence of filtering commands, which consist of -keywords and data values. For example, in the command -.display asis -deliver gulliver@lilliput.fict.example -.endd -the keyword is \"deliver"\ and the data value is -\"gulliver@@lilliput.fict.example"\. -White space or line breaks separate the components of a command, except in the -case of conditions for the \"if"\ command, where round brackets (parentheses) -also act as separators. Complete commands are separated from each other by -white space or line breaks; there are no special terminators. Thus, several -commands may appear on one line, or one command may be spread over a number of -lines. - -If the character @# follows a separator anywhere in a command, everything from -@# up to the next newline is ignored. This provides a way of including comments -in a filter file. - -.section Data values in filter commands -There are two ways in which a data value can be input: -.numberpars $. -If the text contains no white space then it can be typed verbatim. However, if -it is part of a condition, it must also be free of round brackets -(parentheses), as these are used for grouping in conditions. -.nextp -Otherwise, it must be enclosed in double quotation marks. In this case, the -character @\ (backslash) is treated as an `escape character' within the string, -causing the following character or characters to be treated specially: -.display rm -.tabs 8 -@\n $t is replaced by a newline -@\r $t is replaced by a carriage return -@\t $t is replaced by a tab -.endd -Backslash followed by up to three octal digits is replaced by the character -specified by those digits, and @\x followed by up to two hexadecimal digits is -treated similarly. Backslash followed by any other character is replaced -by the second character, so that in particular, @\" becomes " and @\@\ becomes -@\$<. A data item enclosed in double quotes can be continued onto the next line -by ending the first line with a backslash. Any leading white space at the start -of the continuation line is ignored. -.endp -In addition to the escape character processing that occurs when strings are -enclosed in quotes, most data values are also subject to $it{string expansion} -(as described in the next section), in which case the characters \@$\ and \@\\ -are also significant. This means that if a single backslash is actually -required in such a string, and the string is also quoted, @\@\@\@\ has to be -entered. - -The maximum permitted length of a data string, before expansion, is 1024 -characters. - - -.section String expansion -.rset SECTfilterstringexpansion "~~chapter.~~section" -Most data values are expanded before use. Expansion consists of replacing -substrings beginning with \"@$"\ with other text. The full expansion facilities -available in Exim are extensive. If you want to know everything that Exim can -do with strings, you should consult the chapter on string expansion in the Exim -documentation. - -In filter files, by far the most common use of string expansion is the -substitution of the contents of a variable. For example, the substring -.display asis -$reply_address -.endd -is replaced by the address to which replies to the message should be sent. If -such a variable name is followed by a letter or digit or underscore, it must be -enclosed in curly brackets (braces), for example, -.display asis -${reply_address} -.endd -If a \"@$"\ character is actually required in an expanded string, it must be -escaped with a backslash, and because backslash is also an escape character in -quoted input strings, it must be doubled in that case. The following two -examples illustrate two different ways of testing for a \"@$"\ character in a -message: -.display asis -if $message_body contains \$ then ... -if $message_body contains "\\$" then ... -.endd -You can prevent part of a string from being expanded by enclosing it between -two occurrences of \"@\N"\. For example, -.display asis -if $message_body contains \N$$$$\N then ... -.endd -tests for a run of four dollar characters. - -.section Some useful general variables -A complete list of the available variables is given in the Exim documentation. -This shortened list contains the ones that are most likely to be useful in -personal filter files: - -\$body@_linecount$\: The number of lines in the body of the message. - -.em -\$body@_zerocount$\: The number of binary zero characters in the body of the -message. -.nem - -\$home$\: In conventional configurations, this variable normally contains the -user's home directory. The system administrator can, however, change this. - -\$local@_part$\: The part of the email address that precedes the @@ sign -- -normally the user's login name. If support for multiple personal mailboxes is -enabled (see section ~~SECTmbox below) and a prefix or suffix for the local -part was recognized, it is removed from the string in this variable. - -\$local@_part@_prefix$\: If support for multiple personal mailboxes is enabled -(see section ~~SECTmbox below), and a local part prefix was recognized, -this variable contains the prefix. Otherwise it contains an empty string. - -\$local@_part@_suffix$\: If support for multiple personal mailboxes is enabled -(see section ~~SECTmbox below), and a local part suffix was recognized, -this variable contains the suffix. Otherwise it contains an empty string. - -\$message@_body$\: The initial portion of the body of the message. By default, -up to 500 characters are read into this variable, but the system administrator -can configure this to some other value. Newlines in the body are converted into -single spaces. - -\$message@_body@_end$\: The final portion of the body of the message, formatted -and limited in the same way as \$message@_body$\. - -\$message@_body@_size$\: The size of the body of the message, in bytes. - -\$message@_headers$\: The header lines of the message, concatenated into a -single string, with newline characters between them. - -\$message@_id$\: The message's local identification string, which is unique for -each message handled by a single host. - -\$message@_size$\: The size of the entire message, in bytes. - -\$original@_local@_part$\: When an address that arrived with the message is -being processed, this contains the same value as the variable \$local@_part$\. -However, if an address generated by an alias, forward, or filter file is being -processed, this variable contains the local part of the original address. - -\$reply@_address$\: The contents of the \"Reply-to:"\ header, if the message -has one; otherwise the contents of the \"From:"\ header. It is the address to -which normal replies to the message should be sent. - -\$return@_path$\: The return path -- that is, the sender field that will be -transmitted as part of the message's envelope if the message is sent to another -host. This is the address to which delivery errors are sent. In many cases, -this variable has the same value as \$sender@_address$\, but if, for example, -an incoming message to a mailing list has been expanded, \$return@_path$\ may -have been changed to contain the address of the list maintainer. - -\$sender@_address$\: The sender address that was received in the envelope of -the message. This is not necessarily the same as the contents of the \"From:"\ -or \"Sender:"\ header lines. For delivery error messages (`bounce messages') -there is no sender address, and this variable is empty. - -\$tod@_full$\: A full version of the time and date, for example: Wed, 18 Oct -1995 09:51:40 +0100. The timezone is always given as a numerical offset from -GMT. - -\$tod@_log$\: The time and date in the format used for writing Exim's log files, -without the timezone, for example: 1995-10-12 15:32:29. - -\$tod@_zone$\: The local timezone offset, for example: +0100. - - -.section Header variables -.rset SECTheadervariables "~~chapter.~~section" -There is a special set of expansion variables containing the header lines of -the message being processed. These variables have names beginning with -\"@$header@_"\ followed by the name of the header line, terminated by a colon. -For example, -.display asis -$header_from: -$header_subject: -.endd -The whole item, including the terminating colon, is replaced by the contents of -the message header line. If there is more than one header line with the same -name, their contents are concatenated. For header lines whose data consists of -a list of addresses (for example, ::From:: and ::To::), a comma and newline is -inserted between each set of data. For all other header lines, just a newline -is used. - -Leading and trailing white space is removed from header line data, and if there -are any MIME `words' that are encoded as defined by RFC 2047 (because they -contain non-ASCII characters), they are decoded and translated, if possible, to -a local character set. Translation is attempted only on operating systems that -have the \iconv(@)\ function. This makes the header line look the same as it -would when displayed by an MUA. The default character set is ISO-8859-1, but -this can be changed by means of the \"headers"\ command (see below). - -If you want to see the actual characters that make up a header line, you can -specify \"@$rheader@_"\ instead of \"@$header@_"\. This inserts the `raw' -header line, unmodified. - -There is also an intermediate form, requested by \"@$bheader@_"\, which removes -leading and trailing space and decodes MIME `words', but does not do any -character translation. If an attempt to decode what looks superficially like a -MIME `word' fails, the raw string is returned. If decoding produces a binary -zero character, it is replaced by a question mark. - -The capitalization of the name following \"@$header@_"\ is not significant. -Because any printing character except colon may appear in the name of a -message's header (this is a requirement of RFC 2822, the document that -describes the format of a mail message) curly brackets must $it{not} be used in -this case, as they will be taken as part of the header name. Two shortcuts are -allowed in naming header variables: -.numberpars $. -The initiating \"@$header@_"\, \"@$rheader@_"\, or \"@$bheader@_"\ can be -abbreviated to \"@$h@_"\, \"@$rh@_"\, or \"@$bh@_"\, respectively. -.nextp -The terminating colon can be omitted if the next character is white space. The -white space character is retained in the expanded string. However, this is not -recommended, because it makes it easy to forget the colon when it really is -needed. -.endp -If the message does not contain a header of the given name, an empty string is -substituted. Thus it is important to spell the names of headers correctly. Do -not use \"@$header@_Reply@_to"\ when you really mean \"@$header@_Reply-to"\. - -.section User variables -There are ten user variables with names \$n0$\ -- \$n9$\ that can be -incremented by the \"add"\ command (see section ~~SECTadd). These can be used -for `scoring' messages in various ways. If Exim is configured to run a `system -filter' on every message, the values left in these variables are copied into -the variables \$sn0$\ -- \$sn9$\ at the end of the system filter, thus making -them available to users' filter files. How these values are used is entirely up -to the individual installation. - -.section Current directory -The contents of your filter file should not make any assumptions about the -current directory. It is best to use absolute paths for file names; you -can normally make use of the \$home$\ variable to refer to your home directory. -The \save\ command automatically inserts \$home$\ at the start of non-absolute -paths. - - - -.section Significant deliveries -.rset SECTsigdel "~~chapter.~~section" -When in the course of delivery a message is processed by a filter file, what -happens next, that is, after the filter file has been processed, depends on -whether or not the filter sets up any $it{significant deliveries}. If at least -one significant delivery is set up, the filter is considered to have handled -the entire delivery arrangements for the current address, and no further -processing of the address takes place. If, however, no significant deliveries -are set up, Exim continues processing the current address as if there were no -filter file, and typically sets up a delivery of a copy of the message into a -local mailbox. In particular, this happens in the special case of a filter file -containing only comments. - -The delivery commands \"deliver"\, \"save"\, and \"pipe"\ are by default -significant. However, if such a command is preceded by the word \"unseen"\, its -delivery is not considered to be significant. In contrast, other commands such -as \"mail"\ and \"vacation"\ do not set up significant deliveries unless -preceded by the word \"seen"\. - -.em -The following example commands set up significant deliveries: -.display asis -deliver jack@beanstalk.example -pipe $home/bin/mymailscript -seen mail subject "message discarded" -seen finish -.endd -The following example commands do not set up significant deliveries: -.display asis -unseen deliver jack@beanstalk.example -unseen pipe $home/bin/mymailscript -mail subject "message discarded" -finish -.endd -.nem - - -.section Filter commands -The filter commands that are described in subsequent sections are listed -below, with the section in which they are described in brackets: -.display rm -.tabs 15 -\add\ $t increment a user variable (section ~~SECTadd) -\deliver\ $t deliver to an email address (section ~~SECTdeliver) -\fail\ $t force delivery failure (sysadmin use) (section ~~SECTfail) -\finish\ $t end processing (section ~~SECTfinish) -\freeze\ $t freeze message (sysadmin use) (section ~~SECTfreeze) -\headers\ $t set the header character set (section ~~SECTheaders) -\if\ $t test condition(s) (section ~~SECTif) -\logfile\ $t define log file (section ~~SECTlog) -\logwrite\ $t write to log file (section ~~SECTlog) -\mail\ $t send a reply message (section ~~SECTmail) -\pipe\ $t pipe to a command (section ~~SECTpipe) -\save\ $t save to a file (section ~~SECTsave) -\testprint\ $t print while testing (section ~~SECTtestprint) -\vacation\ $t tailored form of \mail\ (section ~~SECTmail) -.endd -.em -The \"headers"\ command has additional parameters that can be used only in a -system filter. The \"fail"\ and \"freeze"\ commands are available only when -Exim's filtering facilities are being used as a system filter, and are -therefore usable only by the system administrator and not by ordinary users. -They are mentioned only briefly in this document; for more information, see the -main Exim specification. -.nem - -.section The add command -.rset SECTadd "~~chapter.~~section" -.display - add <<number>> to <<user variable>> -e.g. add 2 to n3 -.endd -There are 10 user variables of this type, with names \"n0"\ -- \"n9"\. Their -values can be obtained by the normal expansion syntax (for example \$n3$\) in -other commands. At the start of filtering, these variables all contain zero. -Both arguments of the \"add"\ command are expanded before use, making it -possible to add variables to each other. Subtraction can be obtained by adding -negative numbers. - - -.section The deliver command -.rset SECTdeliver "~~chapter.~~section" -.display - deliver <<mail address>> -e.g. deliver "Dr Livingstone <David@@somewhere.africa.example>" -.endd -This command provides a forwarding operation. -.em -The delivery that it sets up is significant unless the command is preceded by -\"unseen"\ (see section ~~SECTsigdel). -.nem -The message is sent on to the given address, exactly as happens if the address -had appeared in a traditional \(.forward)\ file. If you want to deliver the -message to a number of different addresses, you can use more than one -\"deliver"\ command (each one may have only one address). However, duplicate -addresses are discarded. - -To deliver a copy of the message to your normal mailbox, your login name can be -given as the address. Once an address has been processed by the filtering -mechanism, an identical generated address will not be so processed again, so -doing this does not cause a loop. - -However, if you have a mail alias, you should $it{not} refer to it here. For -example, if the mail address \"L.Gulliver"\ is aliased to \"lg303"\ then all -references in Gulliver's \(.forward)\ file should be to \"lg303"\. A reference -to the alias will not work for messages that are addressed to that alias, -since, like \(.forward)\ file processing, aliasing is performed only once on an -address, in order to avoid looping. - -Following the new address, an optional second address, preceded by -\"errors@_to"\ may appear. This changes the address to which delivery errors on -the forwarded message will be sent. Instead of going to the message's original -sender, they go to this new address. For ordinary users, the only value that is -permitted for this address is the user whose filter file is being processed. -For example, the user \"lg303"\ whose mailbox is in the domain -\lilliput.example\ could have a filter file that contains -.display asis - deliver jon@elsewhere.example errors_to lg303@lilliput.example -.endd -Clearly, using this feature makes sense only in situations where not all -messages are being forwarded. In particular, bounce messages must not be -forwarded in this way, as this is likely to create a mail loop if something -goes wrong. - - -.section The save command -.rset SECTsave "~~chapter.~~section" -.display - save <<file name>> -e.g. save @$home/mail/bookfolder -.endd -.em -This command specifies that a copy of the message is to be appended to the -given file (that is, the file is to be used as a mail folder). The delivery -that \"save"\ sets up is significant unless the command is preceded by -\"unseen"\ (see section ~~SECTsigdel). -.nem -More than one \"save"\ command may be obeyed; each one causes a copy of the -message to be written to its argument file, provided they are different -(duplicate \"save"\ commands are ignored). - -If the file name does not start with a / character, the contents of the -\$home$\ variable are prepended, unless it is empty. In conventional -configurations, this variable is normally set in a user filter to the user's -home directory, but the system administrator may set it to some other path. In -some configurations, \$home$\ may be unset, in which case a non-absolute path -name may be generated. Such configurations convert this to an absolute path -when the delivery takes place. In a system filter, \$home$\ is never set. - -The user must of course have permission to write to the file, and the writing -of the file takes place in a process that is running as the user, under the -user's primary group. Any secondary groups to which the user may belong are not -normally taken into account, though the system administrator can configure Exim -to set them up. In addition, the ability to use this command at all is -controlled by the system administrator -- it may be forbidden on some systems. - -An optional mode value may be given after the file name. The value for the mode -is interpreted as an octal number, even if it does not begin with a zero. For -example: -.display - save /some/folder 640 -.endd -This makes it possible for users to override the system-wide mode setting for -file deliveries, which is normally 600. If an existing file does not have the -correct mode, it is changed. - -An alternative form of delivery may be enabled on your system, in which each -message is delivered into a new file in a given directory. If this is the case, -this functionality can be requested by giving the directory name terminated by -a slash after the \"save"\ command, for example -.display - save separated/messages/ -.endd -There are several different formats for such deliveries; check with your system -administrator or local documentation to find out which (if any) are available -on your system. If this functionality is not enabled, the use of a path name -ending in a slash causes an error. - - -.section The pipe command -.rset SECTpipe "~~chapter.~~section" -.display - pipe <<command>> -e.g. pipe "@$home/bin/countmail @$sender@_address" -.endd -.em -This command specifies that the message is to be delivered to the specified -command using a pipe. The delivery that it sets up is significant unless the -command is preceded by \"unseen"\ (see section ~~SECTsigdel). -.nem -Remember, however, that no deliveries are done while the filter is being -processed. All deliveries happen later on. Therefore, the result of running the -pipe is not available to the filter. - -When the deliveries are done, a separate process is run, and a copy of the -message is passed on its standard input. The process runs as the user, under -the user's primary group. Any secondary groups to which the user may belong are -not normally taken into account, though the system administrator can configure -Exim to set them up. More than one \"pipe"\ command may appear; each one causes -a copy of the message to be written to its argument pipe, provided they are -different (duplicate \"pipe"\ commands are ignored). - -When the time comes to transport the message, -the command supplied to \"pipe"\ is split up by Exim into a command name and a -number of arguments. These are delimited by white space except for arguments -enclosed in double quotes, in which case backslash is interpreted as an escape, -or in single quotes, in which case no escaping is recognized. Note that as the -whole command is normally supplied in double quotes, a second level of quoting -is required for internal double quotes. For example: -.display asis - pipe "$home/myscript \"size is $message_size\"" -.endd -String expansion is performed on the separate components after the line has -been split up, and the command is then run directly by Exim; it is not run -under a shell. Therefore, substitution cannot change the number of arguments, -nor can quotes, backslashes or other shell metacharacters in variables cause -confusion. - -Documentation for some programs that are normally run via this kind of pipe -often suggest that the command should start with -.display asis -IFS=" " -.endd -This is a shell command, and should $it{not} be present in Exim filter files, -since it does not normally run the command under a shell. - -However, there is an option that the administrator can set to cause a shell to -be used. In this case, the entire command is expanded as a single string and -passed to the shell for interpretation. It is recommended that this be avoided -if at all possible, since it can lead to problems when inserted variables -contain shell metacharacters. - -The default \\PATH\\ set up for the command is determined by the system -administrator, usually containing at least \/usr/bin\ so that common commands -are available without having to specify an absolute file name. However, it is -possible for the system administrator to restrict the pipe facility so that the -command name must not contain any / characters, and must be found in one of the -directories in the configured \\PATH\\. It is also possible for the system -administrator to lock out the use of the \"pipe"\ command altogether. - -When the command is run, a number of environment variables are set up. The -complete list for pipe deliveries may be found in the Exim reference manual. -Those that may be useful for pipe deliveries from user filter files are: -.display -.tabs 20 -DOMAIN $t $rm{the domain of the address} -HOME $t $rm{your home directory} -LOCAL@_PART $t $rm{see below} -LOCAL@_PART@_PREFIX $t $rm{see below} -LOCAL@_PART@_SUFFIX $t $rm{see below} -LOGNAME $t $rm{your login name} -MESSAGE@_ID $t $rm{the message's unique id} -PATH $t $rm{the command search path} -RECIPIENT $t $rm{the complete recipient address} -SENDER $t $rm{the sender of the message} -SHELL $t $bf{/bin/sh} -USER $t $rm{see below} -.endd -\\LOCAL@_PART\\, \\LOGNAME\\, and \\USER\\ are all set to the same value, -namely, your login id. \\LOCAL@_PART@_PREFIX\\ and \\LOCAL@_PART@_SUFFIX\\ may -be set if Exim is configured to recognize prefixes or suffixes in the local -parts of addresses. For example, a message addressed to -\*pat-suf2@@domain.example*\ may cause user \*pat*\'s filter file to be run. If -this sets up a pipe delivery, \\LOCAL@_PART@_SUFFIX\\ is \"-suf2"\ when the -pipe command runs. The system administrator has to configure Exim specially for -this feature to be available. - -If you run a command that is a shell script, be very careful in your use of -data from the incoming message in the commands in your script. RFC 2822 is very -generous in the characters that are legally permitted to appear in mail -addresses, and in particular, an address may begin with a vertical bar or a -slash. For this reason you should always use quotes round any arguments that -involve data from the message, like this: -.display asis -/some/command '$SENDER' -.endd -so that inserted shell meta-characters do not cause unwanted effects. - -Remember that, as was explained earlier, the pipe command is not run at the -time the filter file is interpreted. The filter just defines what deliveries -are required for one particular addressee of a message. The deliveries -themselves happen later, once Exim has decided everything that needs to be done -for the message. - -A consequence of this is that you cannot inspect the return code from the pipe -command from within the filter. Nevertheless, the code returned by the command -is important, because Exim uses it to decide whether the delivery has succeeded -or failed. - -The command should return a zero completion code if all has gone well. Most -non-zero codes are treated by Exim as indicating a failure of the pipe. This is -treated as a delivery failure, causing the message to be returned to its -sender. However, there are some completion codes that are treated as temporary -errors. The message remains on Exim's spool disk, and the delivery is tried -again later, though it will ultimately time out if the delivery failures go on -too long. The completion codes to which this applies can be specified by the -system administrator; the default values are 73 and 75. - -The pipe command should not normally write anything to its standard output or -standard error file descriptors. If it does, whatever is written is normally -returned to the sender of the message as a delivery error, though this action -can be varied by the system administrator. - - -.section Mail commands -.rset SECTmail "~~chapter.~~section" -There are two commands that cause the creation of a new mail message, neither -of which count as a significant delivery unless the command is preceded by the -word \"seen"\ (see section ~~SECTsigdel). This is a powerful facility, but it -should be used with care, because of the danger of creating infinite sequences -of messages. The system administrator can forbid the use of these commands -altogether. - -To help prevent runaway message sequences, these commands have no effect when -the incoming message is a bounce (delivery error) message, and messages sent by -this means are treated as if they were reporting delivery errors. Thus, they -should never themselves cause a bounce message to be returned. The basic -mail-sending command is -.display - mail [to <<address-list>>] - [cc <<address-list>>] - [bcc <<address-list>>] - [from <<address>>] - [reply@_to <<address>>] - [subject <<text>>] - [extra@_headers <<text>>] - [text <<text>>] - [[expand] file <<filename>>] - [return message] - [log <<log file name>>] - [once <<note file name>>] - [once@_repeat <<time interval>>] -.blank -e.g. mail text "Your message about @$h@_subject: has been received" -.endd - -Each <<address-list>> can contain a number of addresses, separated by commas, -in the format of a ::To:: or ::Cc:: header line. In fact, the text you supply -here is copied exactly into the appropriate header line. It may contain -additional information as well as email addresses. For example: -.display asis -mail to "Julius Caesar <jc@rome.example>, \ - <ma@rome.example> (Mark A.)" -.endd -Similarly, the texts supplied for \"from"\ and \"reply@_to"\ are copied into -their respective header lines. - -As a convenience for use in one common case, there is also a command called -\vacation\. It behaves in the same way as \mail\, except that the defaults for -the -\"subject"\, -\"file"\, \"log"\, \"once"\, and \"once@_repeat"\ options are -.display -subject "On vacation" -expand file .vacation.msg -log .vacation.log -once .vacation -once@_repeat 7d -.endd -respectively. These are the same file names and repeat period used by the -traditional Unix \"vacation"\ command. The defaults can be overridden by -explicit settings, but if a file name is given its contents are expanded only -if explicitly requested. - -\**Warning**\: The \"vacation"\ command should always be used conditionally, -subject to at least the \"personal"\ condition (see section ~~SECTpersonal -below) so as not to send automatic replies to non-personal messages from -mailing lists or elsewhere. Sending an automatic response to a mailing list or -a mailing list manager is an Internet Sin. - -For both commands, the key/value argument pairs can appear in any order. At -least one of \"text"\ or \"file"\ must appear (except with \"vacation"\, where -there is a default for \"file"\); if both are present, the text string appears -first in the message. If \"expand"\ precedes \"file"\, each line of the file is -subject to string expansion before it is included in the message. - -Several lines of text can be supplied to \"text"\ by including the escape -sequence `@\n' in the string wherever a newline is required. If the command is -output during filter file testing, newlines in the text are shown as `@\n'. - -Note that the keyword for creating a \"Reply-To:"\ header is \reply@_to\, -because Exim keywords may contain underscores, but not hyphens. If the \"from"\ -keyword is present and the given address does not match the user who owns the -forward file, Exim normally adds a \"Sender:"\ header to the message, -though it can be configured not to do this. - -The \extra@_headers\ keyword allows you to add custom header lines to the -message. The text supplied must be one or more syntactically valid RFC 2882 -header lines. You can use `@\n' within quoted text to specify newlines between -headers, and also to define continued header lines. For example: -.display asis -extra_headers "h1: first\nh2: second\n continued\nh3: third" -.endd -No newline should appear at the end of the final header line. - -If no \"to"\ argument appears, the message is sent to the address in the -\"@$reply@_address"\ variable (see section ~~SECTfilterstringexpansion above). -An \"In-Reply-To:"\ header is automatically included in the created message, -giving a reference to the message identification of the incoming message. - -If \"return message"\ is specified, the incoming message that caused the filter -file to be run is added to the end of the message, subject to a maximum size -limitation. - -If a log file is specified, a line is added to it for each message sent. - -If a \"once"\ file is specified, it is used to hold a database for remembering -who has received a message, and no more than one message is ever sent to any -particular address, unless \"once@_repeat"\ is set. This specifies a time -interval after which another copy of the message is sent. The interval is -specified as a sequence of numbers, each followed by the initial letter of one -of `seconds', `minutes', `hours', `days', or `weeks'. For example, -.display asis -once_repeat 5d4h -.endd -causes a new message to be sent if 5 days and 4 hours have elapsed since the -last one was sent. There must be no white space in a time interval. - -Commonly, the file name specified for \"once"\ is used as the base name for -direct-access (DBM) file operations. There are a number of different DBM -libraries in existence. Some operating systems provide one as a default, but -even in this case a different one may have been used when building Exim. With -some DBM libraries, specifying \"once"\ results in two files being created, -with the suffixes \".dir"\ and \".pag"\ being added to the given name. With -some others a single file with the suffix \".db"\ is used, or the name is used -unchanged. - -Using a DBM file for implementing the \"once"\ feature means that the file -grows as large as necessary. This is not usually a problem, but some system -administrators want to put a limit on it. The facility can be configured not to -use a DBM file, but instead, to use a regular file with a maximum size. The -data in such a file is searched sequentially, and if the file fills up, the -oldest entry is deleted to make way for a new one. This means that some -correspondents may receive a second copy of the message after an unpredictable -interval. Consult your local information to see if your system is configured -this way. - -More than one \"mail"\ or \"vacation"\ command may be obeyed in a single filter -run; they are all honoured, even when they are to the same recipient. - - -.section Logging commands -.rset SECTlog "~~chapter.~~section" -A log can be kept of actions taken by a filter file. This facility is normally -available in conventional configurations, but there are some situations where -it might not be. Also, the system administrator may choose to disable it. Check -your local information if in doubt. - -Logging takes place while the filter file is being interpreted. It does not -queue up for later like the delivery commands. The reason for this is so that a -log file need be opened only once for several write operations. There are two -commands, neither of which constitutes a significant delivery. The first -defines a file to which logging output is subsequently written: -.display - logfile <<file name>> -e.g. logfile @$home/filter.log -.endd -The file name must be fully qualified. You can use \$home$\, as in this -example, to refer to your home directory. The file name may optionally be -followed by a mode for the file, which is used if the file has to be created. -For example, -.display - logfile @$home/filter.log 0644 -.endd -The number is interpreted as octal, even if it does not begin with a zero. -The default for the mode is 600. It is suggested that the \"logfile"\ command -normally appear as the first command in a filter file. Once \"logfile"\ has -been obeyed, the \"logwrite"\ command can be used to write to the log file: -.display - logwrite "<<some text string>>" -e.g. logwrite "@$tod@_log @$message@_id processed" -.endd -It is possible to have more than one \"logfile"\ command, to specify writing to -different log files in different circumstances. Writing takes place at the end -of the file, and a newline character is added to the end of each string if -there isn't one already there. Newlines can be put in the middle of the string -by using the `@\n' escape sequence. Lines from simultaneous deliveries may get -interleaved in the file, as there is no interlocking, so you should plan your -logging with this in mind. However, data should not get lost. - - -.section The finish command -.rset SECTfinish "~~chapter.~~section" -The command \"finish"\, which has no arguments, causes Exim to stop -interpreting the filter file. This is not a significant action unless preceded -by \"seen"\. A filter file containing only \"seen finish"\ is a black hole. - -.section The testprint command -.rset SECTtestprint "~~chapter.~~section" -It is sometimes helpful to be able to print out the values of variables when -testing filter files. The command -.display - testprint <<text>> -e.g. testprint "home=@$home reply@_address=@$reply@_address" -.endd -does nothing when mail is being delivered. However, when the filtering code is -being tested by means of the \-bf-\ option (see section ~~SECTtesting above), -the value of the string is written to the standard output. - -.section The fail command -.rset SECTfail "~~chapter.~~section" -When Exim's filtering facilities are being used as a system filter, the -\"fail"\ command is available, to force delivery failure. Because this command -is normally usable only by the system administrator, and not enabled for use by -ordinary users, it is described in more detail in the main Exim specification -rather than in this document. - -.section The freeze command -.rset SECTfreeze "~~chapter.~~section" -When Exim's filtering facilities are being used as a system filter, the -\"freeze"\ command is available, to freeze a message on the queue. Because this -command is normally usable only by the system administrator, and not enabled -for use by ordinary users, it is described in more detail in the main Exim -specification rather than in this document. - - -.section The headers command -.rset SECTheaders "~~chapter.~~section" -The \"headers"\ command can be used to change the target character set that is -used when translating the contents of encoded header lines for insertion by the -\"@$header@_"\ mechanism (see section ~~SECTheadervariables above). The default -can be set in the Exim configuration; if not specified, ISO-8859-1 is used. The -only currently supported format for the \"headers"\ command -.em -in user filters -.nem -is as in this example: -.display asis -headers charset "UTF-8" -.endd -That is, \"headers"\ is followed by the word \"charset"\ and then the name of a -character set. This particular example would be useful if you wanted to compare -the contents of a header to a UTF-8 string. - -.em -In system filter files, the \"headers"\ command can be used to add or remove -header lines from the message. These features are described in the main Exim -specification. -.nem - - - -.section Obeying commands conditionally -.rset SECTif "~~chapter.~~section" -Most of the power of filtering comes from the ability to test conditions and -obey different commands depending on the outcome. The \"if"\ command is used to -specify conditional execution, and its general form is -.display -if <<condition>> -then <<commands>> -elif <<condition>> -then <<commands>> -else <<commands>> -endif -.endd -There may be any number of \"elif"\ and \"then"\ sections (including none) and -the \"else"\ section is also optional. Any number of commands, including nested -\"if"\ commands, may appear in any of the <<commands>> sections. - -Conditions can be combined by using the words \"and"\ and \"or"\, and round -brackets (parentheses) can be used to specify how several conditions are to -combine. Without brackets, \"and"\ is more binding than \"or"\. -For example, -.display asis -if - $h_subject: contains "Make money" or - $h_precedence: is "junk" or - ($h_sender: matches ^\\d{8}@ and not personal) or - $message_body contains "this is spam" -then - seen finish -endif -.endd -A condition can be preceded by \"not"\ to negate it, and there are also some -negative forms of condition that are more English-like. - - - -.section String testing conditions -There are a number of conditions that operate on text strings, using the words -`begins', `ends', `is', `contains' and `matches'. If you want to apply the same -test to more than one header line, you can easily concatenate them into a -single string for testing, as in this example: -.display asis -if "$h_to:, $h_cc:" contains me@domain.example then ... -.endd - -If a string-testing condition name is written in lower case, the testing -of letters is done without regard to case; if it is written in upper case -(for example, `CONTAINS'), the case of letters is taken into account. -.display - <<text1>> begins <<text2>> - <<text1>> does not begin <<text2>> -e.g. @$header@_from: begins "Friend@@" -.endd -A `begins' test checks for the presence of the second string at the start of -the first, both strings having been expanded. -.display - <<text1>> ends <<text2>> - <<text1>> does not end <<text2>> -e.g. @$header@_from: ends "@public.com.example" -.endd -An `ends' test checks for the presence of the second string at the end of -the first, both strings having been expanded. -.display - <<text1>> is <<text2>> - <<text1>> is not <<text2>> -e.g. @$local@_part@_suffix is "-foo" -.endd -An `is' test does an exact match between the strings, having first expanded -both strings. -.display - <<text1>> contains <<text2>> - <<text1>> does not contain <<text2>> -e.g. @$header@_subject: contains "evolution" -.endd -A `contains' test does a partial string match, having expanded both strings. -.display - <<text1>> matches <<text2>> - <<text1>> does not match <<text2>> -e.g. @$sender@_address matches "(bill|john)@@" -.endd -For a `matches' test, after expansion of both strings, the second one is -interpreted as a regular expression. Exim uses the PCRE regular expression -library, which provides regular expressions that are compatible with Perl. - -The match succeeds if the regular expression matches any part of the first -string. If you want a regular expression to match only at the start or end of -the subject string, you must encode that requirement explicitly, using the @^ -or @$ metacharacters. The above example, which is not so constrained, matches -all these addresses: -.display asis -bill@test.example -john@some.example -spoonbill@example.com -littlejohn@example.com -.endd -To match only the first two, you could use this: -.display asis -if $sender_address matches "^(bill|john)@" then ... -.endd - -Care must be taken if you need a backslash in a regular expression, because -backslashes are interpreted as escape characters both by the string expansion -code and by Exim's normal processing of strings in quotes. For example, if you -want to test the sender address for a domain ending in \".com"\ the regular -expression is -.display asis -\.com$ -.endd -The backslash and dollar sign in that expression have to be escaped when used -in a filter command, as otherwise they would be interpreted by the expansion -code. Thus what you actually write is -.display asis -if $sender_address matches \\.com\$ -.endd -An alternative way of handling this is to make use of the \"@\N"\ expansion -flag for suppressing expansion: -.display asis -if $sender_address matches \N\.com$\N -.endd -Everything between the two occurrences of \"@\N"\ is copied without change by -the string expander (and in fact you do not need the final one, because it is -at the end of the string). - -If the regular expression is given in quotes (mandatory only if it contains -white space) you have to write either -.display asis -if $sender_address matches "\\\\.com\\$" -.endd -or -.display asis -if $sender_address matches "\\N\\.com$\\N" -.endd - -If the regular expression contains bracketed sub-expressions, numeric -variable substitutions such as \$1$\ can be used in the subsequent actions -after a successful match. If the match fails, the values of the numeric -variables remain unchanged. Previous values are not restored after \"endif"\. -In other words, only one set of values is ever available. If the condition -contains several sub-conditions connected by \"and"\ or \"or"\, it is the -strings extracted from the last successful match that are available in -subsequent actions. Numeric variables from any one sub-condition are also -available for use in subsequent sub-conditions, because string expansion of a -condition occurs just before it is tested. - -.section Numeric testing conditions -The following conditions are available for performing numerical tests: -.display - <<number1>> is above <<number2>> - <<number1>> is not above <<number2>> - <<number1>> is below <<number2>> - <<number1>> is not below <<number2>> -e.g. @$message@_size is not above 10k -.endd -The <<number>> arguments must expand to strings of digits, optionally followed -by one of the letters K or M (upper case or lower case) which cause -multiplication by 1024 and 1024x1024 respectively. - -.section Testing for significant deliveries -You can use the \"delivered"\ condition to test whether or not any previously -obeyed filter commands have set up a significant delivery. For example: -.display asis -if not delivered then save mail/anomalous endif -.endd - -.section Testing for error messages -The condition \"error@_message"\ is true if the incoming message is a bounce -(mail delivery error) message. Putting the command -.display asis -if error_message then finish endif -.endd -at the head of your filter file is a useful insurance against things going -wrong in such a way that you cannot receive delivery error reports. \**Note**\: -\"error@_message"\ is a condition, not an expansion variable, and therefore is -not preceded by \@$\. - -.section Testing a list of addresses -There is a facility for looping through a list of addresses and applying a -condition to each of them. It takes the form -.display -foranyaddress <<string>> (<<condition>>) -.endd -where <<string>> is interpreted as a list of RFC 2822 addresses, as in a -typical header line, and <<condition>> is any valid filter condition or -combination of conditions. The `group' syntax that is defined for certain -header lines that contain addresses is supported. - -The parentheses surrounding the condition are mandatory, to delimit it from -possible further sub-conditions of the enclosing \"if"\ command. Within the -condition, the expansion variable \$thisaddress$\ is set to the non-comment -portion of each of the addresses in the string in turn. For example, if the -string is -.display asis -B.Simpson <bart@sfld.example>, lisa@sfld.example (his sister) -.endd -then \$thisaddress$\ would take on the values \"bart@@sfld.example"\ and -\"lisa@@sfld.example"\ in turn. - -If there are no valid addresses in the list, the whole condition is false. If -the internal condition is true for any one address, the overall condition is -true and the loop ends. If the internal condition is false for all addresses in -the list, the overall condition is false. This example tests for the presence -of an eight-digit local part in any address in a \To:\ header: -.display asis -if foranyaddress $h_to: ( $thisaddress matches ^\\d{8}@ ) then ... -.endd -When the overall condition is true, the value of \$thisaddress$\ in the -commands that follow \"then"\ is the last value it took on inside the loop. At -the end of the \"if"\ command, the value of \$thisaddress$\ is reset to what it -was before. It is best to avoid the use of multiple occurrences of -\"foranyaddress"\, nested or otherwise, in a single \"if"\ command, if the -value of \$thisaddress$\ is to be used afterwards, because it isn't always -clear what the value will be. Nested \"if"\ commands should be used instead. - -Header lines can be joined together if a check is to be applied to more than -one of them. For example: -.display asis -if foranyaddress $h_to:,$h_cc: .... -.endd -scans through the addresses in both the \To:\ and the \Cc:\ headers. - -.section Testing for personal mail -.rset SECTpersonal "~~chapter.~~section" -A common requirement is to distinguish between incoming personal mail and mail -from a mailing list, or from a robot or other automatic process (for example, a -bounce message). In particular, this test is normally required for `vacation -messages'. - -.em -The \"personal"\ condition checks that the message is not a bounce message and -that the current user's email address appears in the \"To:"\ header. It also -checks that the sender is not the current user or one of a number of common -daemons, and that there are no header lines starting \"List-"\ in the message. -Finally, it checks the content of the \"Precedence:"\ header line, if there is -one. - -You should always use the \"personal"\ condition when generating automatic -responses. -.nem -This example shows the use of \"personal"\ in a filter file that is sending out -vacation messages: -.display asis -if personal then - mail - to $reply_address -.newline -.em - subject "I am on holiday" -.nem -.newline - file $home/vacation/message - once $home/vacation/once - once_repeat 10d -endif -.endd -.em -It is tempting, when writing commands like the above, to quote the original -subject in the reply. For example: -.display asis -subject "Re: $h_subject:" -.endd -There is a danger in doing this, however. It may allow a third party to -subscribe you to an opt-in mailing list, provided that the list accepts bounce -messages as subscription confirmations. (Messages sent from filters are always -sent as bounce messages.) Well-managed lists require a non-bounce message to -confirm a subscription, so the danger is relatively small. - -If prefixes or suffixes are in use for local parts -- something which depends -on the configuration of Exim (see section ~~SECTmbox below) -- the tests for -the current user are done with the full address (including the prefix and -suffix, if any) as well as with the prefix and suffix removed. If the system is -configured to rewrite local parts of mail addresses, for example, to rewrite -`dag46' as `Dirk.Gently', the rewritten form of the address is also used in the -tests. -.nem - -.em -.section Alias addresses for the personal condition -It is quite common for people who have mail accounts on a number of different -systems to forward all their mail to one system, and in this case a check for -personal mail should test all their various mail addresses. To allow for this, -the \"personal"\ condition keyword can be followed by -.display -alias <<address>> -.endd -any number of times, for example -.display asis -if personal alias smith@else.where.example - alias jones@other.place.example -then ... -.endd -The alias addresses are treated as alternatives to the current user's email -address when testing the contents of header lines. -.nem - - -.em -.section Details of the personal condition -The basic \"personal"\ test is roughly equivalent to the following: -.display flow asis -not error_message and -$message_headers does not contain "\nList-" and -$header_auto-submitted: does not contain "auto-" and -$header_precedence: does not contain "bulk" and -$header_precedence: does not contain "list" and -$header_precedence: does not contain "junk" and -foranyaddress $header_to: - ( $thisaddress contains "$local_part@$domain" ) and -not foranyaddress $header_from: - ( - $thisaddress contains "$local_part@domain" or - $thisaddress contains "server@" or - $thisaddress contains "daemon@" or - $thisaddress contains "root@" or - $thisaddress contains "listserv@" or - $thisaddress contains "majordomo@" or - $thisaddress contains "-request@" or - $thisaddress matches "^owner-[^@]+@" - ) -.endd -The variable \$local@_part$\ contains the local part of the mail address of -the user whose filter file is being run -- it is normally your login id. The -\$domain$\ variable contains the mail domain. As explained above, if aliases -or rewriting are defined, or if prefixes or suffixes are in use, the tests for -the current user are also done with alternative addresses. -.nem - - -.section Testing delivery status -There are two conditions that are intended mainly for use in system filter -files, but which are available in users' filter files as well. The condition -\"first@_delivery"\ is true if this is the first process that is attempting to -deliver the message, and false otherwise. This indicator is not reset until the -first delivery process successfully terminates; if there is a crash or a power -failure (for example), the next delivery attempt is also a `first delivery'. - -In a user filter file \"first@_delivery"\ will be false only if -there was previously an error in the filter, or if a delivery for the user -failed owing to, for example, a quota error, or if forwarding to a remote -address was deferred for some reason. - -The condition \"manually@_thawed"\ is true only if the message was `frozen' for -some reason, and was subsequently released by the system administrator. It is -unlikely to be of use in users' filter files. - -.section Multiple personal mailboxes -.rset SECTmbox "~~chapter.~~section" -The system administrator can configure Exim so that users can set up variants -on their email addresses and handle them separately. Consult your system -administrator or local documentation to see if this facility is enabled on your -system, and if so, what the details are. - -The facility involves the use of a prefix or a suffix on an email address. For -example, all mail addressed to \lg303-<<something>>\ would be the property of -user \lg303\, who could determine how it was to be handled, depending on the -value of <<something>>. - -There are two possible ways in which this can be set up. The first possibility -is the use of multiple \(.forward)\ files. In this case, mail to \lg303-foo\, -for example, is handled by looking for a file called \.forward-foo\ in -\lg303's\ home directory. If such a file does not exist, delivery fails and the -message is returned to its sender. - -The alternative approach is to pass all messages through a single \(.forward)\ -file, which must be a filter file so that it can distinguish between the -different cases by referencing the variables \$local@_part@_prefix$\ or -\$local@_part@_suffix$\, as in the final example in section ~~SECTex below. - -It is possible to configure Exim to support both schemes at once. In this case, -a specific \.forward-foo\ file is first sought; if it is not found, the basic -\(.forward)\ file is used. - -The \"personal"\ test (see section ~~SECTpersonal) includes prefixes and -suffixes in its checking. - - -.section Ignoring delivery errors -As was explained above, filtering just sets up addresses for delivery -- no -deliveries are actually done while a filter file is active. If any of the -generated addresses subsequently suffers a delivery failure, an error message -is generated in the normal way. However, if a filter command that sets up a -delivery is preceded by the word \"noerror"\, errors for that delivery, -$it{and any deliveries consequent on it} (that is, from alias, forwarding, or -filter files it invokes) are ignored. - - -.section Examples of Exim filter commands -.rset SECTex "~~chapter.~~section" -Simple forwarding: -.display asis -# Exim filter -deliver baggins@rivendell.middle-earth.example -.endd -Vacation handling using traditional means, assuming that the \.vacation.msg\ -and other files have been set up in your home directory: -.display asis -# Exim filter -unseen pipe "/usr/ucb/vacation \"$local_part\"" -.endd -Vacation handling inside Exim, having first created a file called -\.vacation.msg\ in your home directory: -.display asis -# Exim filter -if personal then vacation endif -.endd -File some messages by subject: -.display asis -# Exim filter -if $header_subject: contains "empire" or - $header_subject: contains "foundation" -then - save $home/mail/f+e -endif -.endd -Save all non-urgent messages by weekday: -.display asis -# Exim filter -if $header_subject: does not contain "urgent" and - $tod_full matches "^(...)," -then - save $home/mail/$1 -endif -.endd -Throw away all mail from one site, except from postmaster: -.display asis -# Exim filter -if $reply_address contains "@spam.site.example" and - $reply_address does not contain "postmaster@" -then - seen finish -endif -.endd -.if ~~sgcal -.if ~~sys.leftonpage < 6ld -.newpage -.fi -.fi -Handle multiple personal mailboxes -.display asis -# Exim filter -if $local_part_suffix is "-foo" -then - save $home/mail/foo -elif $local_part_suffix is "-bar" -then - save $home/mail/bar -endif -.endd - -. End of filter |