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.cfADDRESS TEST MODE (ruleset 3 NOT automatically invoked) Enter <ruleset> <address> >0 fredrewrite: 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.