/usr/local/etc/maildroprc, $HOME/.mailfilter, $HOME/.mailfilters/*, and
friends...
Instructions for filtering messages come from a file, using a simple language. The language is loosely structured, it is based on pattern matching. The language has a distinct lexical and syntactical structure, but it uses common features found in other pseudo-languages.
If the filtering instructions do not exist, maildrop delivers the message to the default mailbox without doing any additional processing, making it indistinguishable from the usual mail delivery agent.
It is important to note that maildrop reads and parses the
filter file before doing anything. If there are any errors
maildrop prints an error message, and terminates with the exit code
set to EX_TEMPFAIL.
A compliant mail transport agent should
re-queue the message for a later delivery attempt. Hopefully, most simple
syntax errors will not cause mail to be bounced back if the error is caught
and fixed quickly.
HOME
, or DEFAULT
. Text is placed into a variable by
using an assignment statement, such as:
FILE="IN.junk"
This statement puts the text "IN.junk" (without the quotes) into a variable
whose name is FILE. Later, the contents of a variable are accessed by using
the $ symbol and the name for the variable. For example:
to $FILE
This will deliver the current message to the mailbox file (or a maildir
directory) named "IN.junk".
maildrop initially creates variables from the environment variables
of the operating system, UNLESS maildrop runs in delivery mode. Each
variable in the operating system environment becomes a maildrop
variable. When running in delivery mode, maildrop does not import the
environment for security reasons. In all cases maildrop resets the
following variables to their default values: HOME, DEFAULT, SHELL,
PATH, LOCKEXT, LOCKREFRESH, LOCKSLEEP, LOCKTIMEOUT, MAILDIRQUOTA,
SENDMAIL
and LOGNAME
.
There's one exception to this rule which applies to the version of
maildrop that comes with the Courier mail server. The following
does not apply to the standalone version of maildrop: when running in
delivery mode, if the -d
flag was not used, or if it specifies
the same userid as the one that's running maildrop, the following
variables are automatically imported from the environment: HOME, SHELL,
LOGNAME
and MAILDIRQUOTA
. These environment variables are
initialized by Courier prior to running maildrop. Additionally, the
initial value for the DEFAULT
maildrop variable is imported from
the MAILDROPDEFAULT
environment variable. This is because
Courier overloads the DEFAULT environment variable to store the defaulted
portion of the local mailbox address. See the dot-courier(5) man page in the Courier
distribution. You can grab Courier's DEFAULT
value by using the
import
setting. Note, however, that this will clobber the old
contents of DEFAULT
, which is probably not what you want. The
right way to do this would be something like this:
SAVEDEFAULT=$DEFAULT import DEFAULT LOCALDEFAULT=$DEFAULT DEFAULT=$SAVEDEFAULT
All internal variables are exported back as environment variables when maildrop runs an external command. Changes to internal variables, made by the filter file, are reflected in the exported environment.
EX_TEMPFAIL
. That should cause the
mail message to remain in the queue, and, hopefully allow the problem to be
corrected, without bouncing any mail.
In maildrop the end of line is a lexical token. In order to continue a long statement on the next line, terminate the line with a backslash character.
NOTE: a backslash followed by either a backslash, or a matching quote, is the only situation where the backslash character is actually removed, leaving only the following character in the actual text literal. If a backslash character is followed by any other character, the backslash is NOT removed.
Multiple text literals in a row are automatically concatenated, even if they use different quotes. For example:
FOOBAR="Foo"'bar'
Sets the variable FOOBAR
to the text "Foobar".
MAILBOX="$HOME/Mailbox"
Sets the variable MAILBOX
to the contents of the variable
HOME
followed by "/Mailbox". Variable names must begin with an
uppercase letter, a lowercase letter, or an underscore. Following that, all
letters, digits, and underscores are taken as a variable name, and its
contents replace the $ sign, and the variable name. It is possible to access
variables whose name includes other characters, by using braces as follows:
MAILBOX="${HOME-WORD}/Mailbox"
Inserts the contents of the HOME-WORD
variable. If the variable
does not exist, the empty text literal is used to replace the variable name.
It is not possible to access variables whose names include the } character.
If the $ character is not followed by a left brace, letter, or an underscore, the $ character remains unmolested in the text literal. A backslash followed by the $ character results in a $ character in the text literal, without doing any variable substitution.
Variable substitution is not done in text literals which are surrounded by single quotes.
DEFAULT
- the default mailbox to deliver the message to.
If the filter file does not indicate a mailbox to deliver this message
to, the message is delivered to this mailbox. The default mailbox is
defined by the system administrator.FROM
- message envelope sender. This is usually the same
address as what appears in the From:
header, but may not be.
This information may or may not be available to maildrop on your
system. The message envelope sender is usually specified with the -f
option to maildrop. If the -f option is not given, maildrop
looks for the From_
line in the message. As the last resort,
FROM
defaults to the userid which invoked maildrop.
Note that FROM
may be empty - the message envelope sender is
empty for bounce messages.HOME
- home directory of the user running
maildrop.HOSTNAME
- network name of the machine running maildrop.
Obtained from gethostname(3)
.LOCKEXT
- extension for dot-lock files (default:
.lock).LOCKREFRESH
- refresh interval, in seconds, for dot-locks
(default: 15). When maildrop dot-locks a mailbox, maildrop
tries to refresh the lock periodically in order to keep other programs
from removing a stale dot-lock. This is only required if a dot-lock
exists for a prolonged period of time, which should be discouraged
anyway.LOCKSLEEP
- number of seconds to wait to try again to
create a dot-lock file, if one already exists (default: 5).LOCKTIMEOUT
- number of seconds to wait before removing a
stale dot-lock file (default: 60). If a dot-lock file still exists after
LOCKTIMEOUT
seconds, maildrop assumes that the
process holding the lock no longer exists, and the dot-lock file can be
safely removed. After removing the dot-lock file, maildrop waits
LOCKSLEEP
seconds before trying to create its own dot-lock
file, in order to avoid a race condition with another process which is
also trying to remove the same stale dot-lock, at the same time.LOGNAME
- name of the user to who the message is being
delivered.MAILFILTER
- this is the name of the original filter file
that was given to maildrop on the command line. This is mostly
usefull to -default
filter files, it allows them to
obtain the value of the -M option
specified on the command line.PATH
- command execution path. maildrop resets PATH
to the system default (usually
/bin:/usr/bin:/usr/local/bin
).SENDMAIL
- mail delivery agent. When maildrop is
instructed to deliver the message to a mailbox whose name begins with the
! character, this is interpreted as a request to forward the message. The
SENDMAIL
command is executed to forward the message.SHELL
- login shell. The shell is used to execute all
commands invoked by maildrop.VERBOSE
- debug level (default: 0). Setting VERBOSE to
progressive higher values, between 1 and 9, produces debugging output on
standard error. maildrop ignores the VERBOSE variable in delivery
mode (in order not to confuse the mail transport agent).UMASK
- the file creation mode mask, in octal. The
default setting of 077 creates mailboxes that are readable and writable
by the owner only. Use 007 to create mailboxes that are
readable/writable by both owner and the group. Use 037 to create
mailboxes that are readable by both owner and group, but writable by
owner only. Permissions on existing mailboxes are not changed, this
setting affects only new mailboxes. When delivering to maildirs this
setting sets the permissions on new messages only. Access permissions on
messages in maildirs are also affected by the permissions on the maildir
directories.EXITCODE
- return code for maildrop. When
maildrop successfully delivers a message, it terminates with this
exit code, which defaults to 0. When the to
or the
cc
command is used to deliver the message to an external
process, via a pipe, maildrop will set this variable to the exit
code of the external process. Since maildrop immediately
terminates after completing the to
command this means that
maildrop's exit code will be the exit code of the external
process. If the to
command does not deliver the message to a
process you must set EXITCODE
before the to
command, since maildrop terminates immediately after finishing the
delivery.LINES
- number of lines in the current message. Note that
this may be an approximation. It may or may not take into account the -A
option, or any mbox "From " lines. Use this as criteria for filtering,
nothing more.MAILDIRQUOTA
- Set this variable in order to manually
enforce a maximum size on ANY maildir where the message is delivered.
This is an optional feature that must be enabled by the system
administrator, see maildirquota(8) for
more information.RETURNCODE
- This variable is set when maildrop
runs the xfilter command, or a command that's
specified within a pair of backtick characters ( command substitution ).
The RETURNCODE
variable will be set to the exit code of the
command, after it completes.SIZE
- number of bytes in the message. This may or may not
include the -A option, and the mbox From_ line. Use this as a criteria
for filtering, nothing more.Text that includes ONLY letters, digits, and the following characters:
_-.:/${}@
may appear without quotes. Note that this does not
allow spaces, or backslashes to be entered, however the text is still
variable-substituted, and the substituted text may contain other
characters.
Also, note that patterns (see below) begin with the slash character.
Normally, anything that begins with the slash is interpreted as a pattern.
However, text immediately after "VARIABLE=
" is interpreted as a
string even if it begins with a slash. This is why something like
MAILDIR=/var/spool/mail
works as expected. Using quotes, though, is highly recommended. You must use
quotes to set a variable to a lone slash, because an unquoted slash is
interpreted as a division sign.
DIR=`ls`
Places the names of the files in the current directory into the DIR variable.
The output of the command will have all newline characters replaced by spaces, and leading and trailing spaces will be stripped (multiple spaces are not removed, though). Also, the contents of the message being delivered is made available to the command on standard input.
/pattern/:options
"pattern" specifies the text to look for in the message.
"pattern" may not start with a space, because the leading slash will be
interpreted as a division sign. If you must search for something that starts
with a space, use something like "/[ ] ... /"
.
With the exception of the following characters, an exact match is looked for. The following special characters are used to specify complex patterns. If it is necessary to look for one of the following characters, verbatim, in the message, put a backslash in front of it. "x" and "abc" designates an arbitrary character, or a pattern, which may include other special characters as well.
x*
- look for zero, or more, occurrences of one character
x.(abc)*
- look for zero or more occurrences of "abc".x+
- look for at least one, may be more, occurrences of
one character x.(abc)+
- look for at least one, may be more, occurrences
of "abc".x?
- look for zero, or one occurrence of one character
x..
- the period matches any character except the newline
character. (This is also applicable within sets - see below).(abc)?
- look for zero, or one occurrence, of "abc".[abc]
- specifies a set of characters - this matches one
character. either a, b, or c. Between the brackets, list all characters
that can be matched at this point in the pattern. One or more characters
can be listed. For example, [~=+] matches either a tilde, an equals sign,
or a +. It is EXACTLY equivalent to (~|=|+), however with large list of
characters this notation is much shorter. In addition, [a-b] matches any
character between "a" and "b", inclusive. For example: [0-9] matches a
digit/ [0-9A-Za-z_] matches either a digit, a letter, or an underscore.
To include the dash, or the left or the right bracket characters in the
set itself, prefix them with a backslash. Use two backslashes to include
the backslash character itself. (Other, historical ways of including
these special characters are permitted, but discouraged).[^abc]
- specifies a set of characters that is NOT the
given characters indicated. If the set begins with the ^ symbol, it
matches a single character that is NOT any of the characters listed.\x
- where "x" is a character. Specifies that x
must be matched exactly. In order to match any special character verbatim
(for example - you want to match the asterisk, *) you must prefix it with
a backslash character. Use two backslashes in order to match a backslash
character verbatim. Also, there are several characters reserved for
matching control characters, without having to enter them verbatim into
the pattern. See below for more information.\nnn
- specifies a character in octal. "nnn" is an octal
number.[:alnum:]
- alphanumeric character, same as
[0-9A-Za-z]
.[:alpha:]
- an uppercase or a lowercase letter, same as
[A-Za-z]
.[:cntrl:]
- a control character.[:digit:]
- a digit, same as [0-9]
.[:graph:]
- a "graphable" character (a non-control
character that's not a space).[:lower:]
- a lowercase letter, same as
[a-z]
.[:print:]
- a printable character (not a control
character).[:punct:]
- a punctuation character.[:space:]
- any whitespace character.[:upper:]
- uppercase letter, same as
[A-Z]
.[:wbreak:]
- any character other than a letter, digit, or
an underscore, same as [^a-zA-Z0-9_]
.[:xdigit:]
- a hexadecimal digit, same as
[0-9A-Fa-f]
.\?
matches the question mark. To match a backslash, use
\\
.
Normally, the pattern can be found anywhere within the message header or body (see below). However, putting the character ^ at the beginning of the pattern forces the pattern to be matched against the beginning of the line only. Putting the character $ at the end of the pattern forces the pattern to be matched against the end of the line only.
Elsewhere in the pattern, the $ sign is used for variable substitution (see above). To include the $ character in the pattern, prefix it with a backslash.
\n
- matches a newline character. Note - this is only
effective if the w option is specified, because
without this option maildrop does not recognize multi-line
patterns.\r
- matches a carriage return. Note - maildrop
automatically ignores carriage returns at the end of each line. I don't
know why you'd want to use \r, but it's there if you need it.\t
- matches a tab.\f
- matches a form feed.\v
- matches a vertical tab. TEXT="This is a long \
text string"
The backslash, the newline, and all leading whitespace on the next line is
removed, resulting in "This is a long text string".
/pattern/,
there is an optional colon, followed by one. or
more. options. The following options may be specified in any order:
/john/
will match "John",
"john", or "JOHN". Specify the D option for a case-sensitive search:
lowercase letters in the pattern must match lowercase letters in the
message; ditto for uppercase.Please note that the 'b' and the 'w' options consume an excessive amount
of CPU time, and should be avoided, if possible. HINT: If possible, use the
SIZE
environment variable to avoid using patterns with these
flags.
If neither 'h' or 'b' is specified, the pattern is matched against the header only. Specifying the 'b' option causes the pattern to be matched against the message body. Specifying both causes the pattern to be matched against the entire message.
Normally, each line in the message gets matched against the pattern individually. When applying patterns to a header, multi-line headers (headers split on several lines by beginning each continuation line with whitespace) are silently combined into a single line, before the pattern is applied. Specifying the 'w' flag causes the pattern to be applied to the whole part of the message that's being searched (which is specified via the presence, or the absence, of the h and b flags). Also, if the 'w' flag is used, but neither 'h' nor 'b' flags are used, the 'b' flag is the default, instead of the 'h' flag.
This flag also changes the way that ^ and $ is interpreted in patterns. Normally, those characters anchor the pattern at the beginning, or the end, of each line. When the 'w' flag is specified, ^ and $ anchors the pattern against the beginning, or the end, of either the header, body, or both.
Patterns are evaluated by maildrop as any other numerical expression. If a pattern is found, maildrop's filter interprets the results of the pattern match as number 1, or true, for filtering purposes. If a pattern is not found the results of the pattern search is zero. Once a pattern is found, the search stops. Second, and subsequent occurrences of the same pattern are NOT searched for.
maildrop can also do weighted scoring. In weighted scoring, multiple occurrences of the same pattern are used to calculate a numerical value.
To use a weighted search, specify the pattern as follows:
/pattern/:options,xxx,yyy
where xxx and yyy are two numbers. yyy is optional -- it will default to 1,
if missing.
The first occurrence of the pattern is evaluated as xxx. The second occurrence of the pattern is evaluated as xxx*yyy, the third as xxx*yyy*yyy, etc... All occurrences of the pattern are added up to calculate the final score.
IMPORTANT: when the w option is not specified, maildrop does not recognize multiple occurrences of the same pattern in the same line. This is required in order to have the ^ and $ operators working correctly. For example:
/^Received:/:1
This pattern counts how many Received: headers the message has, and does not
recognize any occurrences of the text "Received:" anywhere else in the
headers.
You must specify the 'w' option in order to take into account multiple occurrences of the same pattern in the message. This also activates all the usual semantics of the 'w' option. For example:
/[:upper:]/:wbD,1
Counts the number of uppercase letters in the body of the message.
After a pattern is successfully matched, the actual text that is matched is placed in the MATCH variable. For example:
/^From:.*/
matches a line of the form:
From: postmaster@localhost
In this case, the variable MATCH
will be set to "From:
postmaster@localhost", which can be used in subsequent statements. It is
possible to use selective parts of the matched string by using the !
character in patterns. For example:
/^From: *!.*/
matched against the same line will set MATCH
to "From: " and
MATCH2
to "postmaster@localhost". More than one ! character may
be used. Subsequent matched text will be assigned to MATCH3
,
MATCH4
, and so on.
Please note that the abuse of this feature will slow down mail delivery -- the ! character introduces a lot of complexity for maildrop to deal with.
When there is more than one way to match a string, maildrop favors matching as much as possible initially. For example:
/^To:.*,!.*/
when matched against
To: joe@somewhere,bob@somewhere.else,gary@whoknowswhere
will set MATCH
to "To: joe@somewhere,bob@somewhere.else," and
MATCH2 to "gary@whoknowswhere".
The MATCH
variables are NOT set when weighted scoring is
used, since the same pattern is matched multiple times.
Although maildrop evaluates expressions numerically, results of expressions are stored as text literals. When necessary, text literals are converted to numbers, then the results of a mathematical operation is converted back into a text literal.
The following operators carry their usual meaning, and are listed in order from lowest precedence, to the highest:
||
&&
< <= > >= == != lt le gt ge eq ne
|
&
+ -
* /
=~ /pattern/
/pattern/ ! ~ function()
VARIABLE=expression
Assigns the result of the expression to VARIABLE (note no leading $ in front
of variable).
Please note that if VARIABLE is NOT surrounded by quotes that it may contain only letters, numbers, underscores, dashes, and a selected few other characters. in order to initialize a variable whose name contains non-standard punctuation marks, surround the name of the variable with quotes.
cc expression
The cc statement is very similar to the to statement, except
that after delivering the message maildrop continues to process the
filter file, unlike the to statement which immediately
terminates maildrop after the delivery is complete. Essentially, the
message is carbon copied to the given mailbox, and may be delivered again to
another mailbox by other cc or to statement.
See the to statement for more details. When
cc
is used to deliver a message to a process maildrop
will set the EXITCODE
variable to the process's exit code.
dotlock expression {
...
}
maildrop automatically creates a lock when a message is delivered to a
mailbox. Depending upon your system configuration, maildrop will use
either dot-locks, or the flock() system call.
The dotlock statement creates an explicit dot-lock file. Use the flock statement to create an explicit flock() lock.
The expression is a filename that should be used as a lock file. maildrop creates the indicated dot-lock, executes the filtering instructions contained within the { ... } block, and removes the lock. The expression must be the name of the dot-lock file itself, NOT the name of the mailbox file you want to lock.
WARNING: with manual locking, it is possible to deadlock multiple maildrop processes (or any other processes that try to claim the same locks).
No deadlock detection is possible with dot-locks, and since maildrop automatically refreshes all of its dot-locks regularly, they will never go stale. You'll have maildrop processes hanging in limbo, until their watchdog timers go off, aborting the mail delivery.
echo expression
maildrop will print the given text. This is usually used when
maildrop is used in embedded mode, but can be used for debugging
purposes. Normally, a newline is printed after the text. If text is
terminated with a \c, no newline will be printed.
exception {
.
.
.
}
The exception statement traps errors that would normally cause
maildrop to terminate. If a fatal error is encountered anywhere within the
block of statements enclosed by the exception clause, execution will
resume immediately following the exception clause.
exit
The exit statement immediately terminates filtering. maildrop's
return code is set to the value of the EXITCODE
variable.
Normally, maildrop terminates immediately after successfully delivering the message to a mailbox. The
exit statement causes maildrop to terminate without delivering
the message anywhere.
The exit statement is usually used when maildrop is invoked in embedded mode, when message delivery instructions are not allowed.
flock expression {
...
}
maildrop automatically creates a lock when a message is delivered to a
mailbox. Depending upon your system configuration, maildrop will use
either dot-locks, or the flock() system call.
The flock statement creates a manual flock() lock. Use the dotlock statement to create a manual dot-lock file.
The expression is the name of the file that should be locked. maildrop creates the lock on the indicated file, executes the filtering instructions contained within the { ... } block, and removes the lock.
WARNING: with manual locking, it is possible to deadlock multiple maildrop processes (or any other processes that try to claim the same locks). The operating system will automatically break flock() deadlocks. When that happens, one of the maildrop processes will terminate immediately. Use the exception statement in order to trap this exception condition, and execute an alternative set of filtering instructions.
foreach /pattern/:options
{
...
}
foreach (expression) =~ /pattern/:options
{
...
}
The foreach statement executes a block of statements for each
occurrence of the given pattern in the given message, or expression. On every
iteration MATCH
variable will be set to the matched string. All
the usual options may be applied to the pattern match, EXCEPT the following:
MATCH
variable will be set. If the
pattern includes the ! operator, the statements will be executed once for
each section in the matched string, with the MATCH
variable
set to the contents of each section. if (expression)
{
...
}
else
{
...
}
Conditional execution. If the expression evaluates to a logical true (note -
parenthesis are required) then the first set of statements is executed. The
else keyword, and the subsequent statements, are optional. If present,
and the expression evaluates to a logical false, the else part is executed.
maildrop evaluates all expression as text strings. In the context of a logical expression, an empty string, or the number 0 constitutes a logical false value, anything else is a logical true value.
If the if part, or the else part consists of only one statement, the braces may be omitted.
NOTE: some grammatical contraptions here that may not be very obvious. If you get baffling syntax errors from maildrop, make sure that the braces, and the if statement, appear on separate lines. Specifically: the closing parenthesis, the closing braces, and the else statement, must be at the end of the line (comments are allowed), and there may not be any blank lines in between (not even ones containing comments only).
import variable
When maildrop starts up, it normally imports the contents of the
environment variables, and assigns them to internal maildrop
variables. For example, if there was an environment variable
FOO
, the internal maildrop variable FOO
will
have the contents of the environment variable. From then on, FOO
will be no different than any other variable, and when maildrop runs
an external command, the contents of maildrop's variables will be
exported as the environment for the command.
Except that certain variables, like HOME
and
PATH
, are always reset to fixed defaults, for security reasons.
Also, in delivery and embedded modes, the environment is not imported at all,
and you'll always started with only the fixed default variables.
The import
statement initializes the given maildrop
variable with the contents that the corresponding environment variable had
when maildrop started. For example:
echo "PATH is $PATH"
PATH="/bin"
echo "PATH is $PATH"
import PATH
echo "PATH is $PATH"
exit
This results in the following output:
PATH is /bin:/usr/bin:/usr/local/bin
PATH is /bin
PATH is /home/root/bin:/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/bin
This shows that when maildrop started, it set the variable
PATH
to the fixed default of
/bin:/usr/bin:/usr/local/bin
. However, the original contents of
the PATH
environment variable we different, and the
import
statement shows what it was.
include expression
The include statement reads a file, and executes filtering instructions
contained in that file. Note that the include statement is processed when the
current filter file is being executed. When maildrop reads the initial
filter file, any syntax errors in the filtering instructions are immediately
reported, and maildrop will terminate with a return code of
EX_TEMPFAIL
. Any errors in files specified by include
statements are NOT reported, because those files will not be read until the
include statement is itself executed.
If the specified file does not exist, or if there are any syntax errors in
the file, maildrop reports the error, and terminates with a return
code of EX_TEMPFAIL
.
logfile expression
log expression
Logging in maildrop is normally turned off. The logfile
statement will instruct maildrop to log how the message has been
disposed to the given file. The parameter is then name of the file. If the
file exists maildrop will append to the file.
For each delivery (which means the to and cc statements, including delivery by default) maildrop will record the From: and the Subject: fields, together with the current time, in the log file.
The log statement may be used to add additional logging text to the log file. The log statement works exactly like the echo statement, except that the text is written to the logfile, instead of standard output.
to expression
The to statement delivers the message to a mailbox. expression
must evaluate to a valid mailbox. A valid mailbox is either a mailbox file, a
maildir, or an external program (which includes forwarding to another
address).
The to statement is the final delivery statement. maildrop
delivers message, then immediately terminates, with the return code set to
the EXITCODE
environment variable. If there was an error while
delivering the message, maildrop terminates with the
EX_TEMPFAIL
exit code. A properly-written mail transport agent
should re-queue the message, and re-attempt delivery at some later time.
If expression begins with the | symbol, the remainder of the
expression specifies an external program to run to handle the actual
delivery. The SHELL
variable specifies the shell to execute the
given command. The message is provided to the command on standard input.
maildrop's exit code will be the process's exit code.
If expression begins with an exclamation mark - "!" - the remainder
of the expression specifies a list of E-mail addresses to forward the message
to. The list of E-mail addresses must be separated by spaces. The mail
delivery agent specified by the SENDMAIL
variable is run as an
external program, with the list of E-mail addresses provided as parameters to
the program.
Otherwise, maildrop delivers the message to the actual mailbox indicated. If expression is a directory, maildrop will assume that the directory is a maildir directory. maildir is a directory-based format used by Qmail. Otherwise, maildrop will deliver the message to a file, formatted in traditional mailbox format. maildrop will use either dot-locking, or flock()-locking when delivering the message to the file.
while (expression)
{
...
}
The expression is repeatedly evaluated. Each time it evaluates to a logical true, the statements inside the braces
are executed. When expression evaluates to a logical false, the while
loop is over. Take care to avoid infinite loops.
xfilter expression
maildrop will run the given program as a mail filter. The current
message will be piped to the filter program as standard input. The output of
the filter program replaces the current message being delivered. The external
program must terminate with an exit code of 0. If the external program does
not terminate with an exit code of 0, or if it does not read the message from
the standard input, maildrop will terminate with an exit code of
EX_TEMPFAIL
.
maildrop uses the following concept of true/false: an empty text literal, or a text literal that consists of the single character "0" is a logical false value. Anything else is a logical true value.
maildrop uses the following concept of true/false: an empty text literal, or a text literal that consists of the single character "0" is a logical false value. Anything else is a logical true value.
NOTE - comparisons are not associative: a < b < c is an error. If it is absolutely necessary, use (a < b) < c.
NOTE - comparisons are not associative: a lt b lt c is an error. If it is absolutely necessary, use (a lt b) lt c. (But why would you?).
See "Patterns" for more information.
See "Patterns" for more information.
maildrop uses the following concept of true/false: an empty text literal, or a text literal that consists of the single character "0" is a logical false value. Anything else is a logical true value.
The result of the ~ operator is a bitwise complement of its right hand side expression. The right hand side expression is evaluated as a 32 bit integer, and the result of this operator is a bitwise complement of the result.
|!$()[]\+*?.&;`'-~<>^{}"This can used when matching pattern sections, and then taking one section and matching it again. For example:
if ( /^From: *!.*/ )
{
MATCH2=escape($MATCH2)
if ( /^Subject:.*$MATCH2/ )
{
.
.
.
}
}
Performs the indicated activity if the contents of the From: header can also
be found in the Subject: header. If the escape function is not used, then any
special characters in the From: header that are also used in regular
expressions, such as * or +, would introduce unpredictable behavior, most
likely a syntax error.
The reason that this list of special characters also includes characters
not used in maildrop's regular expressions is to allow
maildrop's variables to be used on the command line of a shell command
executed by the xfilter
command, backtick characters, or
to
or cc
commands.
Although using data from an external data source is dangerous, and it may
result in inadvertent exploits, using the escape function should hopefully
result in fewer surprises.
maildropgdbm(5)
for more information.
Please note that GDBM functions may not be available on your site. The
system administrator can disable GDBM support in maildrop.
RFC822
addresses. It extracts the actual addresses from the
header, without any comments or extraneous punctuation. Each address is
followed by a newline character. For example, if string contains:
joe@domain.com (Joe Brown), "Alex Smith" <alex@domain.com>, tom@domain.com
The result of the getaddr function is the following string:
joe@domain.com<NL>alex@domain.com<NL>tom@domain.com<NL>
Where <NL> is the newline character.
Note - because getaddr() interprets RFC822 loosely, it is not necessary to
strip off the "To:" or the "Cc:" header from the string, before feeding it to
getaddr()
. For example, the following snippet of code takes all
addresses in the message, and concatenates them into a single string,
separated by spaces:
ADDRLIST=""
foreach /^(To|Cc): .*/
{
foreach (getaddr $MATCH) =~ /.+/
{
ADDRLIST="$ADDRLIST $MATCH"
}
}
Please note that in certain rare situations, RFC822
permits
spaces to be included in E-mail addresses, so this example is just
educational. string
" is of the form user@domain
. The hasaddr
function returns 1 if this address is included in any To:
,
Cc:
, Resent-To:
, or Resent-Cc:
, header
in the message, otherwise this function returns 0.
This is more than just a simple text search. Each header is parsed
according to RFC822
. Addresses found in the header are
extracted, ignoring all comments and names. The remaining addresses are
checked, and if "string
" is one of them, hasaddr returns 1,
otherwise it returns 0.
The comparison is case-insensitive. This actually violates
RFC822
(and several others) a little bit, because the user part
of the address may be (but is not required to be) case sensitive.
Leading whitespace (but not trailing whitespace, take care) is removed, and the remaining contents of each line are interpreted as a pattern which is matched against expr. As soon as the match is found, lookup returns "1". If no match is found after reading the entire file, lookup returns "0". For example:
if ( /^To: *!.*/ && lookup( $MATCH2, "badto.dat" )
{
exit
}
And the file badto.dat contains the following two lines:
friend@public
^[^@]*$
If a message has a To: header that contains the text "friend@public", or does
not contain at least one @ character, then the message will be silently
dropped on the floor ( maildrop will terminate without delivering the
message anywhere).
options are the pattern matching options to use. The only supported option is "D" (the rest are meaningless, in this case).
NOTE: be careful with discarding messages like that. Pattern matching can be tricky, and a slight miscalculation can cause mail to be unintentionally discarded. It is much desirable to first deliver message to a separate folder or mailbox, and once the filter is verified to work correctly, change it so the messages are discarded completely.
The time function returns the current time, in seconds, since January 1, 1970. This function is useful when using GDBM files. See maildropex(5) for an example of using the time function.
$HOME/.mailfilter
or another file) contains filtering
statements, one per line. The filtering language used by maildrop has
a loosely - defined grammatical structure.
Statements are listed one per line. Multiple statements may be listed on the same line by separating them with semicolons. To continue a long statement on the next line, terminate the line with a backslash character.
hasaddr() is completely case insensitive. This actually violates a few RFCs, because the userid portion of the address could be case-sensitive, but it's not in too many cases, so there.