Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
MAILDROPFILTER(7)	    Double Precision, Inc.	     MAILDROPFILTER(7)

NAME
       maildropfilter -	maildrop's filtering language

SYNOPSIS
       /usr/local/etc/maildroprc, $HOME/.mailfilter, $HOME/.mailfilters/*, and
       friends...

DESCRIPTION
       This manual page	describes the language used by maildrop	to filter
       E-mail messages.	The mail filtering instructions	are read from a	file.
       The language is loosely structured, it is based on pattern matching.
       The language has	a distinct lexical and syntactical structure, very
       similar to Perl's, but it is important to note that it is not Perl, and
       is very different from Perl, in certain cases.

       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.

   Environment
       maildrop	uses variables to access and manipulate	messages. Variables
       are arbitrary text accessed by referring	to the name of the variable,
       such as 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
       operating system	environment variable becomes a maildrop	variable. When
       running in delivery mode, maildrop does not import the environment for
       security	reasons, except	for the	environment variables that define the
       process locale (LANG, LANGUAGE, and LC_*), which	are still imported.

       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[1]. 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 the
       Courier mail server prior to running maildrop. Additionally, the
       initial value for the DEFAULT maildrop variable is imported from	the
       MAILDROPDEFAULT environment variable. This is because the Courier mail
       server overloads	the DEFAULT environment	variable to store the
       defaulted portion of the	local mailbox address. See the
       dot-courier(5)[2] man page in the Courier mail server distribution. You
       can get the Courier mail	server's DEFAULT value by using	the import
       command.	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.

   Lexical structure
       Most whitespace is generally ignored. The # character introduces	a
       comment running to the end of the line, which is	also ignored. Unlike
       other mail filters, maildrop parses the filter file before taking any
       action with the message.	If there are syntax errors in the file,
       maildrop	displays an error message, and returns 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.

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

   Literal text
       Literal text in the maildrop filtering language is surrounded by	either
       single or double	quotes.	In order to enter a single quote into a	text
       literal surrounded by single quotes, or a double	quote into a literal
       surrounded by double quotes, prefix it with a backslash character. Use
       two backslash characters	characters to enter one	backslash character in
       the text	literal.

	   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'
	   SAVEDEFAULT=$DEFAULT
	   import DEFAULT
	   LOCALDEFAULT=$DEFAULT
	   DEFAULT=$SAVEDEFAULT

       This sets the variable FOOBAR to	the text "Foobar".

   Variable substitution
       Variable	substitution is	performed on text literals that's surrounded
       by double quotation marks. The "$" character, followed by a variable
       name, is	replaced by that variable's contents.

	   MAILBOX="$HOME/Mailbox"

       This 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	(apostrophes).

   Command line	arguments
       maildrop	initializes special variables: $1, $2, and so on, with
       additional parameters specified on the maildrop command line. A filter
       file may	use those variables just like any other	variables.

   Predefined variables
       The following variables are automatically defined by maildrop. The
       default values for the following	variables may be changed by the	system
       administrator. For security reasons, the	values of the following
       variables are always reset to their default values, and are never
       imported	from the environment:

       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
	   Return-Path:	header in the message. As the last resort, FROM
	   defaults to "MAILER-DAEMON".	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.

       MAILDROP_OLD_REGEXP
	   Revert to using the old legacy pattern matching engine. Versions of
	   maildrop prior to version 2.0 (included in the Courier mail server
	   0.51, and earlier), used a built-in pattern matching	engine,
	   instead of using the	PCRE library (see the "Patterns" section).
	   maildrop 1.x	used a different syntax	for patterns, which is no
	   longer described in this manual page. The old pattern matching
	   engine is still available, by setting MAILDROP_OLD_REGEXP to	"1".
	   Setting this	variable will use the legacy pattern matching engine
	   for the rest	of the maildrop	recipe file.

	   The pattern matching	engine will be removed completely in a future
	   version of maildrop.	This setting provides for a transitional
	   period of converting	old recipes.  MAILDROP_OLD_REGEXP can be set
	   to "1" in the global	maildroprc file, then reset to "0" in each
	   individual maildrop recipe file, after it gets converted to the new
	   syntax.

       MAILFILTER
	   This	is the name of the original filter file	that was given to
	   maildrop on the command line. This is mostly	useful to
	   -defaultfilter files, it allows them	to obtain the value of the -M
	   option[3] specified on the command line.

       PATH
	   Command execution path.  maildrop resets PATH to the	system default
	   (usually /bin:/usr/bin:/usr/local/bin).

       SENDMAIL
	   The 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
	   The login shell. The	shell is used to execute all commands invoked
	   by maildrop.

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

   Other special variables
       The following variables are automatically used by maildrop when the
       filter file is being processed:

       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.

       FLAGS
	   The FLAGS variable is used only when	delivering a message to	a
	   maildir, and	may contain only the following letters:	"D", "F", "R",
	   and "S". They may appear in any order. When the message gets
	   delivered to	the maildir, the message will be marked	with a draft,
	   flag, replied, or seen, attribute, correspondingly.

	   FLAGS must be set before the	message	is delivered to	a maildir. The
	   contents of FLAGS are ignored, when delivering on an	mbox folder.

       KEYWORDS
	   The KEYWORDS	variable is used only when delivering a	message	to a
	   maildir, and	implements the optional	IMAP keyword extension as
	   implemented in the Courier IMAP server[1]. It may be	optionally
	   initialized to contain a comma-separate list	of keywords. The to,
	   or the cc command, delivers the message to the maildir normally,
	   but also associated the list	of keywords in KEYWORDS	with the newly
	   delivered message.

	   KEYWORDS must be set	before the message is delivered	to a maildir.
	   The contents	of KEYWORDS are	ignored, when delivering on an mbox
	   folder.

       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.
	   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)[4] for more information.

       RETURNCODE
	   This	variable is set	when maildrop runs the xfilter[5] 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. Use this as a criteria for filtering, nothing more.

   Unquoted text
       All text	strings	in filter files	should be in single, or	double quotes.
       However,	for convenience	sake, quotes can be omitted under certain
       circumstances.

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

       Long double or singly-quoted text can be	broken across multiple lines
       by ending the line with a lone backslash	character, like	this:

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

   Command substitution
       Text enclosed in	back-tick characters is	interpreted as a shell
       command.	The shell command is executed as a child process by maildrop.
       Its output is used in place of the command. For example:

	   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.

   Patterns
       The pattern syntax in maildrop is similar to the	grep command's syntax,
       with some minor differences. A pattern takes the	following form in the
       filter file:

	   /pattern/:options

       pattern specifies the text to look for in the message, in the UTF-8
       codeset.	 pattern must not begin	with a space, otherwise	the leading
       slash will then be interpreted as a division sign. If you must search
       for text	that starts with a space, use something	like "/[ ] ... /".

       The general syntax of maildrop's	patterns is described in the
       pcrepattern(3) manual page, with	certain	exceptions noted below.
       maildrop	uses the PCRE[6] library to implement pattern matching.	Not
       all features in PCRE are	available in maildrop, and the "options" part,
       which follows the pattern specification,	changes	the pattern matching
       further.	Consult	the pcrepattern(3) manual page for more	information,
       but note	the following exceptions:

       o   Internal options settings are not supported (but see	the "D"
	   maildrop option, below). Do not include option settings in the
	   pattern, doing so will lead to undefined results.

       o   Named subpatterns are not implemented. Numbered subpatterns are
	   implemented,	see "Pattern Match Results", below.

       o   The search pattern gets executed not	against	the raw	message	text,
	   but the message transcoded into a canonical UTF-8-based format.
	   This	process	involves transcoding any non-UTF-8 message content
	   into	UTF-8. Additionally, message headers get converted into	a
	   canonical format before the search pattern gets executed.

	   For structured headers with email addresses,	the process involves
	   removing extraneous punctuation, or adding missing ones (in
	   situations where a missing punctuation character can	be deduced).
	   Additionally	certain	pre-RFC822 obsolete header formats get
	   converted to	canonical form.

	   This	means that header search patterns that include punctuation
	   character may appear	not to work against obviously-matching message
	   text. Use "reformime	-u <message.txt", with message.txt containing
	   the sample message, to see exactly the actual text that gets
	   searched by patterns.

   Pattern options
       Following /pattern/, there may be an optional colon, followed by	one.
       or more options.	The following options may be specified in any order:

       h
	   Match this pattern against the message header.

       b
	   Match this pattern against the message body.

       D
	   This	is a case sensitive match. Normally the	patterns match either
	   uppercase or	lowercase text.	 /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.

       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.

   MIME	encoding
       The pattern must	be a valid text	string in the UTF-8 codeset, and
       maildrop	should handle messages that use	MIME encodings in other	known
       character sets.	Options	that specify a message header search result in
       maildrop	searching the initial message headers, and any headers of
       additional MIME sections, in a multipart	MIME message. Options that
       specify a message body search will search through all "text" MIME
       content.

       For a MIME search to succeed, the message must be a well-formed MIME
       message (with a Mime-Version: 1.0 header).

   Weighted scoring
       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
       score.

       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.

	   Note
	   maildrop does not recognize multiple	occurrences of the same
	   pattern in the same line. Multiple occurences of the	same pattern
	   in one line count as	one occurence.

   Pattern Match Results
       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

       Here the	variable MATCH will be set to "From: postmaster@localhost",
       which can be used in subsequent statements.

       If the pattern contains subpatterns, the	portions of the	text that
       match the first subpattern is placed in the MATCH1 variable. The	second
       subpattern, if any, is placed in	MATCH2,	and so on:

	   /^From:\s+(.*)@(.*)/

       matched against the same	line will set MATCH to "From:
       postmaster@localhost", MATCH1 to	"postmaster", and MATCH2 to
       "localhost". Of course, in real world the "From:" header	is usually
       much more complicated, and can't	be handled that	easily.	This is	just
       an illustrative example.

	   Note
	   Subpatterns are not processed in the	foreach	statement.

   Conversion of maildrop 1.x patterns to 2.0
       Although	the new	PCRE-based pattern matching code in maildrop is
       completely different from the built-in pattern matching code in
       maildrop	1.x, very few changes will be required to convert recipes to
       the new syntax. The only	major differences are:

       o   The subexpression format has	changed. Any pattern that uses
	   subexpression needs to be converted.	Additionally, references to
	   MATCH2 must be replaced with	MATCH1,	MATCH3 to MATCH2, and so on.
	   References to plain old MATCH will remain the same.

       o   The "w" pattern option is no	longer possible, with PCRE. The	very
	   few recipes that use	this option, if	any actually exist, will have
	   to be rewritten in some other fashion.

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

       Operators
	   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	assignment
	       VARIABLE=expression

	   Assigns the result of the expression	to VARIABLE (note no leading $
	   in front of variable).

	       Note
	       If VARIABLE is NOT surrounded by	quotes,	then 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 - deliver a copy of the message
	       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 another cc or to statement.

	   See the to statement[7] 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 - create	a manual dot-lock
	       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[8] 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.

	       Note
	       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 - output diagnostic	information
	       echo expression

	   maildrop will print the given text. This is usually used when
	   maildrop runs 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 - trap	fatal errors
	       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 - terminate	filtering unconditionally
	       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[7] to a mailbox. The	exit statement causes maildrop to
	   terminate without delivering	the message anywhere.

	   The exit statement is usually used when maildrop runs in embedded
	   mode[9], when message delivery instructions are not allowed.

       flock - create an manual	flock()	lock
	       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[10] 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.

	       Note
	       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 - iterate over text sections matched by a pattern
	       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:

	   ,xxx,yyy
	       Weighted	scoring	is meaningless,	in this	context.

	   ( ... )
	       Subpatterns are not processed. Only the MATCH variable will be
	       set for each found pattern.

       if - conditional	execution
	       if (expression)
	       {
		  ...
	       }
	       else
	       {
		  ...
	       }

	   Conditional execution. If 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
	       The grammar of this if statement	is stricter than usual.	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).

	   If the else part contains a single if, and nothing else, this may
	   be combined into an elsif:

	       if (expression)
	       {
		  ...
	       }
	       elsif (expression)
	       {
		  ...
	       }

	   The above example is	logically identical to:

	       if (expression)
	       {
		  ...
	       }
	       else
	       {
		  if (expression)
		  {
		     ...
		  }
	       }

	   Consecutive elsif sequences are allowed:

	       if (expression)
	       {
		  ...
	       }
	       elsif (expression)
	       {
		  ...
	       }
	       elsif (expression)
	       {
		  ...
	       }

	   Consecutive occurences of elsif commands eliminate a	significant
	   amount of indentation, and the resulting code is more readable.

       import -	access original	environment variable
	       import variable

	   When	maildrop starts, 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.

	   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 (with the exception
	   of system locale environment	variables), and	maildrop starts	with
	   only	the fixed default variables.

	   The import statement	initializes the	specified variable with	the
	   contents of the original environment	variable 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 starts	PATH is	set 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 - execute filtering instructions	from another file
	       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.

       log, logfile - log message deliveries
	       logfile expression

	       log expression

	   Logging in maildrop is normally turned off. The logfile statement
	   specifies the file where maildrop will log how the message has been
	   disposed of.	The parameter is then name of the file.	If the file
	   exists maildrop appends to the file.

	   For each delivery (the to[7]	and cc[11] statements, and default
	   deliveries) maildrop	records	the From: and the Subject: fields,
	   together with the current time, in the log file.

	   The log statement adds 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 - deliver message to a mailbox
	       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 its return code
	   set to the EXITCODE 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.

	   An expression that begins with the "|" character 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.

	   An expression that begins with an exclamation mark, "!" specifies a
	   whitespace-delimited	list of	E-mail addresses to forward the
	   message to. The program 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, expression names the mailbox where maildrop delivers the
	   message. If expression is a directory, maildrop assumes that	the
	   directory is	a maildir directory. 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 - repeatedly execute a block of statements
	       while (expression)
	       {
		  ...
	       }

	   The expression is repeatedly	evaluated. Each	time it	evaluates to a
	   logical true[12], 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 - filter	message	through	another	program
	       xfilter expression

	   expression specifies	an external program that maildrop runs to
	   filter the current message. 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 terminates
	   with	an exit	code of	EX_TEMPFAIL.

       || - logical or
	       expression1 || expression2

	   If expression1 evaluates to a logical true, the result of the || is
	   expression1,	otherwise it's expression2, which is evaluated.

	   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.

       && - logical and
	       expression1 && expression2

	   If expression1 evaluates to a logical false,	the result of the &&
	   is expression1, otherwise it's expression2, which is	evaluated.

	   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.

       <, <=, >, >=, ==, != - numerical	comparison
	       expression1 < expression2

	       expression1 <= expression2

	       expression1 > expression2

	       expression1 >= expression2

	       expression1 == expression2

	       expression1 != expression2

	   These operators compare their left hand side	expression against
	   their right hand side. These	operators compare the numerical	values
	   of each side, as floating point numbers. If the numbers compare as
	   indicated, the result of the	comparison is the text string "1",
	   otherwise it	is the text string 0.

	       Note
	       Ccomparisons are	not associative: "a < b	< c" is	an error. If
	       it is absolutely	necessary, use "(a < b)	< c".

       lt, le, gt, ge, eq, ne -	text comparison
	       expression1 lt expression2

	       expression1 le expression2

	       expression1 gt expression2

	       expression1 ge expression2

	       expression1 eq expression2

	       expression1 ne expression2

	   These operators compare their left hand side	expression against
	   their right hand side. These	operators compare each side as text
	   strings (alphabetically, although the text may include anything).
	   If the text strings compare as indicated, the result	of the
	   comparison is the text string "1", otherwise	it is the text string
	   0.

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

       | - bitwise or
	       expression1 | expression2

	   This	is the bitwise or operator. Its	result is a 32 bit integer,
	   which is a bitwise-or combination of	the left hand side and the
	   right hand side.

       & - bitwise and
	       expression1 & expression2

	   This	is the bitwise and operator. Its result	is a 32	bit integer,
	   which is a bitwise-and combination of the left hand side and	the
	   right hand side.

       +, -, *,	/ - numerical operations
	       expression1 + expression2

	       expression1 - expression2

	       expression1 * expression2

	       expression1 / expression2

	   These are numerical,	floating point,	operators.

       =~ /pattern/:options - pattern match against string
	       expression =~ /pattern/:option

	   The left hand side of the =~	operator can be	any expression.	The
	   right hand side is always a pattern specification. The result of
	   the operator	is the weighted	match of the pattern against
	   expression (if the options do not specify weighted scoring, the
	   result is simply 1 if the pattern was found,	0 if not).

	   See "Patterns[13]" for more information.

       /pattern/:options - pattern match against message
	       /pattern/:option

	   The result of this operator is the weighted match of	the pattern
	   against the current message (if the options do not specify weighted
	   scoring, the	result is simply 1 if the pattern was found, 0 if
	   not).

	   See "Patterns[13]" for more information.

       !, ~ - logical/bitwise not operator.
	       ! expression

	       ~ expression

	   The result of the !	operator is a logical opposite of its right
	   hand	side expression. If the	right hand side	expression evaluated
	   to a	logical	true, the result is a logical false. If	it evaluated
	   to a	logical	false, the result is a logical true.

	   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.

       escape(string) -	escape special characters in a string.
	       escape(expression)

	   The escape function returns its sole	argument with every occurrence
	   of a	special	character prefixed by a	backslash. A special character
	   is any of the following characters:

	       |!$()[]\+*?.&;`'-~<>^{}"

	   This	can used when matching pattern sections[14], and then taking
	   one section and matching it again. For example:

	       if ( /^From:\s*(.*)/ )
	       {
		  MATCH1=escape($MATCH1)
		  if ( /^Subject:.*$MATCH1/ )
		  {
		     ...
		  }
	       }

	   This	example	checks if the contents of the From: header can also be
	   found in the	Subject: header. If the	escape function	were 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 why 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.

       gdbmopen, gdbmclose, gdbmfetch, gdbmstore - GDBM	support	in maildrop
	   These functions provide support for GDBM database files. See
	   maildropgdbm(5)[15] for more	information.

	       Note
	       The system administrator	can disable GDBM support in maildrop,
	       so these	commands may not be available to you.

       getaddr(string) - extract RFC 2822 addresses from a header.
	       if ( /^From:\s*(.*)/ )
	       {
		  ADDR=getaddr($MATCH1)
	       }

	   This	function is usually applied to a header	that contains RFC
	   2822[16] 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>

	       Note
	       Because getaddr() interprets RFC	2822[17] 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"
		       }
		   }

	       Note
	       In certain rare situations, RFC 2822[17]	allows spaces to be
	       included	in E-mail addresses, so	this example is	just
	       educational.

       hasaddr(string) - Search	for an address.
	       if ( hasaddr(string) )
	       {
		  ...
	       }

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

       length (string) - length	of a string
	       if (length(string) > 80)
	       {
		  ...
	       }

	   The length function returns the number of characters	in string.

       lookup (expr, 'filename', 'options') - read file	for patterns
	       if (lookup(expr,	file, "option"))
	       {
		  ...
	       }

	   expr	is any expression.  filename is	a name of a file containing a
	   list	of patterns. Note that filename	is relative to the current
	   directory, which is the home	directory of the user when maildrop
	   runs	in delivery mode, or embedded mode.  maildrop then reads the
	   file. Blank lines will be ignored, as well as any lines that	begin
	   with	the # character	(comments).

	   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:\s*(.*)/ && lookup( $MATCH1, "badto.dat" ))
	       {
		   exit
	       }

	   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.

       substr(string,start [,count]) - return substring
	       foo=substr($foo,	1, 10)

	   The substr function extracts	characters from	string beginning with
	   character #start. If	count is specified, at most count characters
	   starting at position	start are kept,	any excess is trimmed.

       time - return current time
	       foo=time

	   The time function returns the current time, in seconds, since
	   January 1, 1970. This function is useful when using GDBM files. See
	   maildropex(7)[18] for an example of using the time function.

       tolower(string) - Convert string	to lowercase.
	       foo=tolower(string)

	   This	function returns the string with all uppercase characters
	   replaced by lowercase characters.

       toupper(string) - Convert string	to uppercase.
	       foo=toupper(string)

	   This	function returns the string with all lowercase characters
	   replaced by uppercase characters.

   Statements
       The filter file is read by maildrop ($HOME/.mailfilter or another
       file), and it 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.

BUGS
       If getaddr() or hasaddr() functions are used on broken headers, the
       results are unpredictable.

       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.

SEE ALSO
       lockmail(1)[19],	maildrop(1)[20], maildropgdbm(5)[15],
       maildirquota(8)[4], reformail(1)[21], egrep(1), sendmail(8).

AUTHOR
       Sam Varshavchik
	   Author

NOTES
	1. Courier mail	server
	   http://www.courier-mta.org/

	2. dot-courier(5)
	   http://www.courier-mta.org/maildrop/dot-courier.html

	3. value of the	-M option
	   http://www.courier-mta.org/maildrop/maildrop.html#moption

	4. maildirquota(8)
	   http://www.courier-mta.org/maildrop/maildirquota.html

	5. xfilter
	   http://www.courier-mta.org/maildrop/#xfilter

	6. PCRE
	   http://www.pcre.org

	7. See the to statement
	   http://www.courier-mta.org/maildrop/#to

	8. flock statement
	   http://www.courier-mta.org/maildrop/#flock

	9. embedded mode
	   http://www.courier-mta.org/maildrop/maildrop.html#embedded

       10. dotlock statement
	   http://www.courier-mta.org/maildrop/#dotlock

       11. cc
	   http://www.courier-mta.org/maildrop/#cc

       12. evaluates to	a logical true
	   http://www.courier-mta.org/maildrop/#if

       13. Patterns
	   http://www.courier-mta.org/maildrop/#patterns

       14. matching pattern sections
	   http://www.courier-mta.org/maildrop/#patmatch

       15. maildropgdbm(5)
	   http://www.courier-mta.org/maildrop/maildropgdbm.html

       16. RFC 2822
	   http://www.rfc-editor.org/rfc/rfc2822.txt

       17. RFC 2822
	   http://www.rfc-editor.org/rfc/rfc822.txt

       18. maildropex(7)
	   http://www.courier-mta.org/maildrop/maildropex.html

       19. lockmail(1)
	   http://www.courier-mta.org/maildrop/lockmail.html

       20. maildrop(1)
	   http://www.courier-mta.org/maildrop/maildrop.html

       21. reformail(1)
	   http://www.courier-mta.org/maildrop/reformail.html

Courier	Mail Server		  12/19/2015		     MAILDROPFILTER(7)

NAME | SYNOPSIS | DESCRIPTION | BUGS | SEE ALSO | AUTHOR | NOTES

Want to link to this manual page? Use this URL:
<https://www.freebsd.org/cgi/man.cgi?query=maildropfilter&sektion=7&manpath=FreeBSD+12.0-RELEASE+and+Ports>

home | help