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.