Each individual rule (
R
command) in the configuration file can be thought of as a while-do statement.
Recall that rules are composed of an
LHS
(left-hand side) and an
RHS
(right-hand side), separated from each other by tabs. As long as (while) the
LHS
matches the workspace, the workspace is rewritten (do) by the
RHS
. (see
Figure 28.1
).
Consider a rule in which we want the name
tom
in the workspace changed into the name
fred
. One possible rule to do this might look like this:
Rtom fred
If the workspace contains the name
tom
, the
LHS
of this rule matches exactly. As a consequence, the
RHS
is given the opportunity to rewrite the workspace. It does so by placing the name
fred
into that workspace. The new workspace is once again compared to the
tom
in the
LHS
, but now there is no match because the workspace contains
fred
. When the workspace and the
LHS
do not match, the rule is skipped, and the
current
contents of the workspace are carried down to the next rule. Thus, in our example, the name
fred
in the workspace is carried down.
Clearly, there is little reason to worry about endless loops in a rule when using names like
tom
and
fred
. But the
LHS
and
RHS
can contain pattern-matching and replacement operators, and those operators
can
lead to loops. To illustrate, consider this example from the
x.cf
file:
Rfred fred
Clearly. the
LHS
will always match
fred
both before and after each rewrite. Here's what happens in testing this rule in
-bt
rule-testing mode:
%/usr/lib/sendmail -bt -Cx.cf
ADDRESS TEST MODE (ruleset 3 NOT automatically invoked) Enter <ruleset> <address> >0 fred
rewrite: ruleset 0 input: fred Infinite loop in ruleset 0, rule 1 rewrite: ruleset 0 returns: fred >
V8 sendmail discovers the loop and breaks it for you. Earlier versions of sendmail would hang forever.