Provided by: maildrop_2.0.3-1_i386 bug

NAME

       maildropfilter - maildrop’s filtering language

SYNOPSIS

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

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

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

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

       · UTF-8 string matching is not presently supported.

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

       · Named  subpatterns  are  not  implemented.   Numbered subpatterns are
         implemented, see ‘‘Pattern Match Results’’, below.

   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.

   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:

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

       · 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 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 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  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,
       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 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).

   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, 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 and cc 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, 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" for more information.

   /PATTERN/:OPTIONS - PATTERN MATCH AGAINST MESSAGE
              expression =~ /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" 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,  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) 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
       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  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 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 takes start number of characters  from  string.  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) 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),     maildrop(1),     maildropgdbm(5),     maildirquota(8),
       reformail(1), egrep(1), sendmail(8).