Mailfromd 

GeneralPurpose Mail Filter 
Sergey Poznyakoff 
Expressions are language constructs, that evaluate to a value, that can subsequently be echoed, tested in a conditional statement, assigned to a variable or passed to a function.
Literals and numbers are constant expressions. They evaluate to string and numeric types.
A function call is an expression. Its type is the return type of the function.
Concatenation operator is ‘.’ (a dot). For example, if
$f
is ‘smith’, and $client_addr
is
‘10.10.1.1’, then:
$f . "" . $client_addr ⇒ "smith10.10.1.1"
Any two adjacent literal strings are concatenated, producing a new string, e.g.
"GNU's" " not " "UNIX" ⇒ "GNU's not UNIX"
The filter script language offers the common arithmetic operators: ‘+’, ‘’, ‘*’ and ‘/’. In addition, the ‘%’ is a modulo operator, i.e. it computes the remainder of division of its operands.
All of them follow usual precedence rules and work as you would expect them to.
The ‘<<’ represents a bitwise shift left operation, which shifts the binary representation of the operand on its left by the number of bits given by the operand on its right.
Similarly, the ‘>>’ represents a bitwise shift right.
Expression  Result 

x < y  True if x is less than y. 
x <= y  True if x is less than or equal to y. 
x > y  True if x is greater than y. 
x >= y  True if x is greater than or equal to y. 
x = y  True if x is equal to y. 
x != y  True if x is not equal to y. 
The relational expressions apply to string as well as to numbers. When a relational operation applies to strings, casesensitive comparison is used, e.g.:
"String" = "string" ⇒ False "String" < "string" ⇒ True
In addition to the traditional relational operators, described
above, mailfromd
provides two operators for regular
expression matching:
Expression  Result 

x matches y  True if the string x matches the regexp denoted by y. 
x fnmatches y  True if the string x matches the globbing pattern denoted by y. 
The type of the regular expression used by matches
operator
is controlled by #pragma regex
(see pragma regex). For example:
$f ⇒ "gray@gnu.org.ua" $f matches '.*@gnu\.org\.ua' ⇒true
$f matches '.*@GNU\.ORG\.UA' ⇒false
#pragma regex +icase $f matches '.*@GNU\.ORG\.UA' ⇒true
The fnmatches
operator compares its lefthand operand with a
globbing pattern (see glob(7)) given as its righthand side
operand. For example:
$f ⇒ "gray@gnu.org.ua" $f fnmatches "*ua" ⇒true
$f fnmatches "*org" ⇒false
$f fnmatches "*org*" ⇒true
Both operators have a special form, for ‘MX’ pattern matching. The expression:
x mx matches y
is evaluated as follows: first, the expression x is analyzed and, if it is an email address, its domain part is selected. If it is not, its value is used verbatim. Then the list of ‘MX’s for this domain is looked up. Each of ‘MX’ names is then compared with the regular expression y. If any of the names matches, the expression returns true. Otherwise, its result is false.
Similarly, the expression:
x mx fnmatches y
returns true only if any of the ‘MX’s for (domain or email) x match the globbing pattern y.
Both mx matches
and mx fnmatches
can signal the
following exceptions: e_temp_failure
, e_failure
.
The value of any parenthesized subexpression occurring within the
righthand side argument to matches
or mx matches
can be
referenced using the notation ‘\d’, where d is the
ordinal number of the subexpression (subexpressions are numbered from
left to right, starting at 1). This notation is allowed in the
program text as well as within doublequoted strings and
heredocuments, for example:
if $f matches '.*@\(.*\)\.gnu\.org\.ua' set message "Your host name is \1;" fi
Remember that the grouping symbols are ‘\(’ and ‘\)’ for basic regular expressions, and ‘(’ and ‘)’ for extended regular expressions. Also make sure you properly escape all special characters (backslashes in particular) in doublequoted strings, or use singlequoted strings to avoid having to do so (see singevsdouble, for a comparison of the two forms).
A boolean expression is a combination of relational or
matching expressions using the boolean operators and
, or
and not
, and, eventually, parentheses to control nesting:
Expression  Result 

x and y  True only if both x and y are true. 
x or y  True if any of x or y is true. 
not x  True if x is false. 
Binary boolean expressions are computed using shortcut evaluation:
x and y
If x ⇒
, the result is false
false
and y is not evaluated.
x or y
If x ⇒
, the result is true
true
and
y is not evaluated.
Operator precedence is an abstract value associated with each
language operator, that determines the order in which operators are
executed when they appear together within a single expression.
Operators with higher precedence are executed first. For example,
‘*’ has a higher precedence than ‘+’, therefore the
expression a + b * c
is evaluated in the following order: first
b
is multiplied by c
, then a
is added to the
product.
When operators of equal precedence are used together they are evaluated from left to right (i.e., they are leftassociative), except for comparison operators, which are nonassociative (these are explicitly marked as such in the table below). This means that you cannot write:
if 5 <= x <= 10
Instead, you should write:
if 5 <= x and x <= 10
The precedences of the mailfromd
operators where selected
so as to match that used in most programming languages.^{14}
The following table lists all operators in order of decreasing precedence:
(...)
Grouping
$ %
Sendmail
macros and mailfromd
variables
* /
Multiplication, division
+ 
Addition, subtraction
<< >>
Bitwise shift left and right
< <= >= >
Relational operators (nonassociative)
= != matches fnmatches
Equality and special comparison (nonassociative)
&
Logical (bitwise) AND
^
Logical (bitwise) XOR

Logical (bitwise) OR
not
Boolean negation
and
Logical ‘and’.
or
Logical ‘or’
.
String concatenation
When two operands on each side of a binary expression have
different type, mailfromd
evaluator coerces them to a
common type. This is known as implicit type casting. The rules
for implicit type casting are:
The construct for explicit type cast is:
type(expr)
where type is the name of the type to coerce expr to. For example:
string(2 + 4*8) ⇒ "34"
The only exception is ‘not’, whose precedence in MFL is much lower than usual (in most programming languages it has the same precedence as unary ‘’). This allows to write conditional expressions in more understandable manner. Consider the following condition:
if not x < 2 and y = 3
It is understood as “if x
is not less than 2 and y
equals 3”,
whereas with the usual precedence for ‘not’ it would have meant
“if negated x
is less than 2 and y
equals 3”.
This document was generated on January 3, 2019 using makeinfo.
Verbatim copying and distribution of this entire article is permitted in any medium, provided this notice is preserved.