[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.2 Conditional Statements

A conditional statement defines control flow within the section. It allows to execute arbitrary actions depending on whether a certain condition is met. The conditional statement in its simplest form is:

if condition
  action-list-1
fi

If condition evaluates to true, then the list of statements action-list-1 is executed.

A simple condition has the following syntax:

part [sep] [op] [pattern-match-flags] regex

(square brackets denoting optional parts). Its parts are:

part

Specifies which part of the input should be considered when evaluating the condition. It is either ‘command’, meaning the text of the SMTP command issued while sending the message, or ‘header’, meaning the value of an RFC822 header. Either of the two may be followed by the name of the corresponding command or header enclosed in square brackets. If this part is missing, all command or headers will be searched.

sep

Optional concatenation separator. See section Concatenations, for its meaning.

op

Either ‘=’, meaning “match”, or ‘!=’, meaning “does not match”. Missing op is equivalent to ‘=’.

pattern-match-flags

Optional pattern-match-flags alter the pattern matching type used in subsequent conditional expression. It will be described in detail in the section Regular Expressions.

regex

Regular expression enclosed in double quotes.

The condition yields true if regex matches the part (if op is ‘=’), or does not match it (if op is ‘!=’).

For example:

if header [Subject] "^ *Re:"
  ...
fi

The actions represented by … will be executed only if the ‘Subject:’ header of the message starts with ‘Re:’ optionally preceded by any amount of whitespace.

A more elaborate form of the conditional allows you to choose among the two different action sets depending on a given condition. The syntax is:

if condition
  action-list-1  
else
  action-list-2
fi

Here, action-list-1 is executed if the condition is met. Otherwise, action-list-2 is executed.

Note, that both action-list-1 and action-list-2 can in turn contain conditionals, so that the conditional statements may be nested. This allows for creating very sophisticated rule sets. As an example, consider the following statement:

if [List-Id] :re ".*<anubis-commit@gnu.org>"
  modify [Subject] "[Anubis Commit Notice] &"
else
  if [List-Id] :re ".*<bug-anubis@gnu.org>"
    modify [Subject] "[Anubis Bug Notice] &"
  else
    add [X-Passed] "Subject checking"
  fi
fi  

The effect of this statement is: depending on the value of List-Id header, prepend the Subject header with an identification string, or add an X-Passed header if no known List-Id was found.

To simplify writing such nested conditional statements, the ‘elif’ keyword is provided:

if condition-1
  action-list-1
elif condition-2  
  action-list-2
else
  action-list-3
fi

This statement is equivalent to:

if condition
  action-list-1
else
  if condition-2  
    action-list-2
  else
    action-list-3
  fi
fi

Any number of ‘elif’ branches may appear in a conditional statement, the only requirement being that they appear before the ‘else’ statement, if it is used.


[ << ] [ < ] [ Up ] [ > ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.2.1 Concatenations

It is important to understand that conditional expressions choose the first match. To illustrate this, lets suppose you wish to store all recipient emails from the envelope in the ‘X-Also-Delivered-To’ header. A naive way to do so is:

if command [rcpt to:] = "(.*)"
  add header [X-Also-Delivered-To] "\1"
fi

However, this will store only the very first RCPT TO value, so you will not achieve your goal.

To help you in this case, anubis offers a concatenation operator, whose effect is to concatenate the values of all requested keys prior to matching them against the regular expression. Syntactically, the concatenation operator is a string enclosed in parentheses, placed right after the key part of a condition. This string is used as a separator when concatenating values. For example:

if command [rcpt to:] (",") = "(.*)"
  add header [X-Also-Delivered-To] "\1"
fi

This fragment will first create a string containing all RCPT TO addresses, separated by commas, and then match it against the regular expression on the right hand side. Since this expression matches any string, the ‘\1’ will contain a comma-separated list of addresses.


[ << ] [ < ] [ Up ] [ > ] [ >> ]

This document was generated on January 6, 2024 using texi2html 5.0.