To better see what is happening inside each rule, rerun
sendmail
with a
-d21.12
debugging command-line switch:
%./sendmail -Cclient.cf -d21.12 -bt
The
-d21.12
switch tells
sendmail
to print each rule as it is processed. Run
sendmail
again with this new switch. This time, when you feed in a nested address, you get considerably more output:
>3 <a<b>c>
rewrite: ruleset 3 input: < a < b > c > ---trying rule: $* < > $* --- rule fails ---trying rule: $* < $* < $* > $* > $* ---rule matches: $2 < $3 > $4 rewritten as: a < b > c ---trying rule: $* < $* < $* > $* > $* --- rule fails ---trying rule: $* < $* > $* ---rule matches: $2 rewritten as: b ---trying rule: $* < $* > $* --- rule fails rewrite: ruleset 3 returns: b
This output may appear complicated, but it is really fairly straightforward. The first two lines and last line are what you have been seeing all along (when you
didn't
use the
-d21.12
switch):
>3 <a<b>c>
rewrite: ruleset 3 input: < a < b > c > rewrite: ruleset 3 returns: b
Everything in between those lines is new output caused by the
-d21.12
switch. That new output shows each rule in rule set 3 being called and processed in turn. The first rule looks for empty angle brackets:
R$* <> $* $n handle <> error address
The workspace (tokenized from the input of
<a<b>c>
) is compared to the LHS of this rule:
---trying rule: $* < > $* --- rule fails
The LHS doesn't match (the rule fails) because the angle brackets of the workspace are not empty. Consequently, the RHS of the first rule is not called, and the workspace is unchanged.
The second rule is the de-nesting one:
R$* < $* < $* > $* > $* $2<$3>$4 de-nest brackets
The workspace (still
<a<b>c>
) is compared to the LHS of this rule.
---trying rule: $* < $* < $* > $* > $*
The LHS matches the workspace, so the workspace is rewritten on the basis of the RHS of that rule, and the extra angle brackets are stripped away:
---rule matches: $2 < $3 > $4 rewritten as: a < b > c
The new workspace is then compared to the LHS of the same rule once again - that is, to the rule that just did the rewriting. If it were to match again, it would be rewritten again. This property (which in error can continue forever) can be useful in solving many configuration problems. We'll cover this property more fully in the next chapter.
So the rewritten workspace is compared once again to the second rule. The workspace (having been rewritten by the second rule) now contains
a < b > c
This time the comparison fails:
---trying rule: $* < $* < $* > $* > $* --- rule fails
The last of the three rules then gets a crack at the workspace. That rule is
R$* < $* > $* $2 basic RFC822 parsing
That workspace is still
a < b > c
The workspace is once again matched, so it is rewritten again on the basis of the RHS of the third rule:
---trying rule: $* < $* > $* ---rule matches: $2 rewritten as: b
After the third rule rewrites the workspace, it again tries to match that rewritten workspace and fails:
---trying rule: $* < $* > $* --- rule fails
As you can see, the
-d21.12
debugging switch can be very useful. It shows you exactly what each rule is trying to do. It shows you each rewrite of the workspace, and it shows you the order in which rules are being applied. (Note that in real rule sets, this output can easily span many screens.)