18.2 The R Configuration Command

Rules are declared in the configuration file with the R configuration command. Like all configuration commands, the R rule configuration command must begin a line. The general form consists of an R command followed by three parts:

Rlhs    rhs   comment
  tabs     tabs 

The lhs stands for lefthand side and is most commonly expressed as LHS. The rhs stands for righthand side and is expressed as RHS. The LHS and RHS are mandatory. The third part (the comment) is optional. The three parts must be separated from each other by one or more tab characters (space characters will not work).

Space characters between the R and the LHS are optional. If there is a tab between the R and the LHS, sendmail prints and logs the following error:

configfile: line number: R line: null LHS 

Space characters can be used inside any of the three parts: the LHS, RHS, or comment. They are often used in those parts to make rules clearer and easier to parse visually.

The tabs leading to the comment and the comment itself are optional and can be omitted. If the RHS is absent, sendmail prints the following warning and ignores that R line:

invalid rewrite line "bad rule here" (tab expected)

This error is printed when the RHS is absent, even if there are tabs following the LHS. (This warning is usually the result of tabs being converted to spaces when text is copied from one window to another in a windowing system using cut and paste.)

18.2.1 Macros in Rules

Each noncomment part of a rule is expanded as the configuration file is read.[2] Thus, any references to defined macros are replaced with the value that the macro has at that point in the configuration file. To illustrate, consider the following miniconfiguration file (which we will call test.cf):

[2] Actually, the comment part is expanded too, but with no effect other than a tiny expenditure of time.

R $A    $A.new
R $A    $A.new

First, note that as of V8.10 sendmail, rules (the R lines) cannot exist outside of rule sets (the S line). If you omit a rule set declaration, the following error will be printed and logged:

configfile: line number: missing valid ruleset for "bad rule here" 

Second, note that beginning with V8.9, sendmail will complain if the configuration file lacks a correct version number (the V line). Had we omitted that line, sendmail would have printed and logged the following warning:

Warning: .cf file is out of date: sendmail 8.12.6 supports version 10, .cf file is 
version 0

The first D line assigns the value value1 to the $A sendmail macro. The second D line replaces the value assigned to $A in the first line with the new value value2. Thus, $A will have the value value1 when the first R line is expanded and value2 when the second is expanded. Prove this to yourself by running sendmail in -bt rule-testing mode to test that file:

% echo =Stest | /usr/sbin/sendmail -bt -Ctest.cf
> =S0
R value1                 value1 . new
R value2                 value2 . new

Here, we use the =S command (Section 8.4.1) to show each rule after it has been read and expanded.

Another property of macros is that an undefined macro expands to an empty string. Consider this rewrite of the previous test.cf file in which we use a $B macro that was never defined:

R $A    $A.$B
R $A    $A.$B

Run sendmail again, in rule-testing mode, to see the result:

% echo =Stest | /usr/sbin/sendmail -bt -Ctest.cf
R value1                 value1 .
R value2                 value2 .

Beginning with V8.7, sendmail macros can be either single-character or multicharacter. Both forms are expanded when the configuration file is read:

R ${OURDOMAIN}    localhost.${OURDOMAIN}

Multicharacter macros can be used in the LHS and in the RHS. When the configuration file is read, the previous example is expanded to look like this:

R us . edu               localhost . us . edu

It is critical to remember that macros are expanded when the configuration file is read. If you forget, you might discover that your configuration file is not doing what you expect.

18.2.2 Rules are Treated Like Addresses

After each side (LHS and RHS) is expanded, each is then normalized just as though it were an address. A check is made for any tabs that might have been introduced during expansion. If any are found, everything from the first tab to the end of the string is discarded.

Then, if the version of the configuration file you are running is less than 9 (that is, if the version of sendmail you are running is less than V8.10), RFC2822-style comments are removed. An RFC2822 comment is anything between and including an unquoted pair of parentheses:

DAroot@my.site (Operator)
R $A  tabRHS 
R root@my.site (Operator)  tabRHS expanded  
R root@my.site  tabRHS comment stripped prior to version 8 configs only  

Finally, a check is made for balanced quotation marks, and for right angle brackets balanced by left.[3] If any righthand character appears without a corresponding lefthand character, sendmail prints one of the following errors (where configfile is the name of the configuration file that is being read, number shows the line number in that file, and expression is the part of the rule that was unbalanced) and attempts to make corrections:

[3] The $> operator isn't counted in checking balance.

configfile: line number: expression ...Unbalanced '"' 
configfile: line number: expression ...Unbalanced ''

Here, an unbalanced quotation mark has been corrected by appending a second quotation mark, and an unbalanced angle bracket has been corrected by removing it. As a further example, consider the following test.cf confirmation file:

R x      RHS"
R y      RHS>

When you run sendmail in rule-testing mode on this file, the following errors and rules are printed:

% echo =Stest | /usr/sbin/sendmail -bt -Ctest.cf
test.cf: line 3: RHS"... Unbalanced '"'
test.cf: line 4: RHS>... Unbalanced '>'
R x              RHS ""
R y              RHS

Note that prior to V8.7 sendmail, only an unbalanced righthand character was checked.[4] Beginning with V8.7 sendmail, unbalanced lefthand characters are also detected, and sendmail attempts to balance them for you. Consider, the following rewrite of our test.cf file:

[4] That is, for example, there must not be a > before the < character, and they must pair off.

R x      "RHS
R y      <RHS

Here, sendmail detects and fixes the unbalanced characters but does so with warnings:

% echo =Stest | /usr/sbin/sendmail -bt -Ctest.cf
test.cf: line 3: "RHS... Unbalanced '"'
test.cf: line 4: <RHS... Unbalanced '<'
R x            "RHS"
R y            < RHS >

If you get one of these Unbalanced errors, be sure to correct the problem at once. If you leave the faulty rule in place, sendmail will continue to run but will likely produce erroneous mail delivery and other odd problems.

Note that prior to version 9, configuration files had to have pairs of parentheses that also had to balance. That is, with version 8 and lower configuration files, the following rules:

R x      (RHS
R y      RHS)

would produce the following errors:

% echo =Stest | /usr/sbin/sendmail -bt -Ctest.cf 
test.cf: line 3: (RHS... Unbalanced '('
test.cf: line 3: R line: null RHS          RFC2822 comment removed
test.cf: line 4: RHS)... Unbalanced ')'

Line 3 (the second line of output in this example) shows that with configuration files prior to version 9, a parenthesized expression was interpreted as an RFC822 comment and removed. Backslashes in rules

Backslash characters are used in addresses to protect certain special characters from interpretation (Section 25.3.2). For example, the address blue;jay would ordinarily be interpreted as having three parts (or tokens, which we'll discuss soon). To prevent sendmail from treating this address as three parts and instead allow it to be viewed as a single item, the special separating nature of the ; can be escaped by prefixing it with a backslash:


V8 sendmail handles backslashes differently than other versions have in the past. Instead of stripping a backslash and setting a high bit (as discussed later), it leaves backslashes in place:

blue\;jay      becomes   blue\;jay

This causes the backslash to mask the special meaning of characters because sendmail always recognizes the backslash in that role.

V8 sendmail strips backslashes only when a delivery agent has the F=s flag (F=s) set, and then only if they are not inside full quotation marks. V8 sendmail also strips backslashes when dequoting with the dequote dbtype (dequote).

Mail to \user is delivered to user on the local machine (bypassing further aliasing) with the backslash stripped. But for mail to \user@otherhost the backslash is preserved in both the envelope and the header.

    Part I: Build and Install
    Part II: Administration
    Part III: The Configuration File
    Chapter 21. The D (Define a Macro) Configuration Command
    Chapter 24. The O (Options) Configuration Command