# ''arith'' '''

 arith

 Perform arithmetic computations V8.10 and above

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

Operator

Description

+

-

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[7] and above)

&

The bitwise AND operation (V8.12[7] and above)

%

The modulo operator: lvalue modulo rvalue (V8.12 and above)

[7] To enable these operators for V8.10 and V8.11, define _FFR_BITOPS (_FFR...) when compiling sendmail.

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

Switch

§

Description

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

 Preface
 Chapter 1. Some Basics
 Part I: Build and Install