Beginning with V8.10,
sendmail supports arithmetic computations in
rule sets via a database-map type called arith.
This form of database map is always present for your use, without the
need for special compile-time macros. To illustrate one use for
arith, consider this mini-configuration file:
V10
Kmath arith
SCalculate
R $+ $+ $+ $@ $(math $2 $@ $1 $@ $3 $: EXCEPTION $)
The K configuration command declares that a
database map named math will be of the
database-map type arith. To use this database map
we declare a rule set. We call that rule set
Calculate so that rule-set testing will be
mnemonically clear.
The rule is the crux of how this math database map
is used:
R $+ $+ $+ $@ $(math $2 $@ $1 $@ $3 $: EXCEPTION $)
operator lvalue rvalue
The arith database-type database maps (such as
math here) take three arguments. The first, in the
position of the key that would otherwise be used
for lookups, is the arithmetic operator. The legal operators, as of
V8.12, are shown in Table 23-5.
Table 23-5. Operators for the arith database-map type
+
|
Addition: add lvalue to rvalue
|
-
|
Subtraction: subtract rvalue from lvalue
|
*
|
Multiplication: multiply lvalue by rvalue
|
/
|
Division: divide lvalue by rvalue
|
l
|
Less-Than: if lvalue is less than rvalue return literal TRUE,
otherwise literal FALSE
|
=
|
Equality: if lvalue is equal to rvalue return literal TRUE, otherwise
literal FALSE
|
|
|
The bitwise OR operation (V8.12 and above)
|
&
|
The bitwise AND operation (V8.12 and
above)
|
%
|
The modulo operator: lvalue modulo rvalue (V8.12 and above)
|
If the arithmetic operator used is not one of those shown in the
table (such as an illegal ! operator), the lookup
(calculation) fails and the value following the $:
operator is returned (the EXCEPTION). If the arithmetic operator is
legal (is shown in the table), a calculation is performed and the
result returned.
The two values used in the computation are passed following the first
and second $@ operators. The
lvalue follows the first $@
operator, and the rvalue follows the second. The
arithmetic operation specified is performed on the two values and the
result is returned.
Computations are always performed using integer calculations, and the
values are always interpreted as integer values. A division by 0
always returns a failed lookup (the EXCEPTION). The less-than and
equality arithmetic operators return the literal token TRUE or FALSE,
indicating the truth of the comparison.
To demonstrate this arith database-map type, you
can run sendmail on the mini-configuration file
listed earlier. If that file were called demo.cf
you might test it like this:
% /usr/sbin/sendmail -Cdemo.cf -bt
ADDRESS TEST MODE (ruleset 3 NOT automatically invoked)
Enter <ruleset> <address>
> Calculate 1 + 1
Calculate input: 1 + 1
Calculate returns: 2
> Calculate 5 / 0
Calculate input: 5 / 0
Calculate returns: EXCEPTION
> Calculate 5 / 2
Calculate input: 5 / 2
Calculate returns: 2
> Calculate -1 * 4
Calculate input: -1 * 4
Calculate returns: -4
> Calculate 2 = 2
Calculate input: 2 = 2
Calculate returns: TRUE
> Calculate 0xff / 2
Calculate input: 0xff / 2
Calculate returns: 0
The last three lines show that only decimal integer values can be
used. Also note that negative values work properly.
One example of a real use for this type of database map might be a
test to see if the ETRN command should be run if the
machine's load average is too high:
D{OurMaxLoad}20
Scheck_etrn
R $* $: $(math l $@ $&{load_avg} $@ ${OurMaxLoad} $) $1
R FALSE $#error $@ 4.7.1 $: "450 The load average is currently too high."
The check_etrn rule set is called by V8.10 and
above sendmail each time the remote site sends
an ETRN command, and before any reply is sent to the remote site.
The $& prevents the
{load_avg} macro (${load_avg})
from being interpreted too early (when the configuration file was
read). Consequently, its current value is
compared to the value in the ${OurMaxLoad} macro.
If the truncated integer value of the load average is higher than our
limit, the request is denied. Note that if
${OurMaxLoad} is undefined, the rule will return a
failed lookup, but not the literal token FALSE. Thus, by undefining
${OurMaxLoad} you disable this test.
Only a few database switches are useful with the
arith database-map type. They are listed in Table 23-6.
Table 23-6. The arith database-map type K command switches
-a
|
-a
|
Append tag on successful match
|
-D
|
-D
|
Don't use this database map if DeliveryMode=defer
|
-S
|
-S
|
Space replacement character
|
-s
|
|
Synonym for -S
|
Although these switches are allowed, it will take some inventiveness
to devise a use for them with this arith
database-map type. If you specify a switch that is not listed in the
table, it will be silently ignored.