23.4 Use $( and $) in Rules
The
information in database maps is accessed in the RHS of rules. This is
the basic syntax:
$(name key $)
The key is looked up in the database map
whose symbolic name (declared with the K
configuration command, Section 23.2) is
name. If the
key is found, the entire expression,
including the $( and $), is
normally replaced with the value returned for that
key. Any
suffix, as specified with the
-a switch (-a) in the
K configuration declaration for
name, is appended to the data. If the
key is not found, the entire expression is
replaced with key. If the $) is
omitted, all tokens up to but excluding the tab and comment, or
end-of-line if there is no comment, are taken as the key. To
illustrate one use for $( and
$), see the following rule:
R$- . uucp $: $(uucp $1.uucp $)
and the following K command:
Kuucp hash /etc/mail/uucp
This associates the symbolic name uucp with a
hash-type file called
/etc/mail/uucp. If the uucp
database contained entries such as these:
lady.uucp lady.localuucp
sonya.uucp sonya.localuucp
a workspace of lady.uucp would match the LHS, so
the RHS would look up $1.uucp (thus,
lady.uucp) in the uucp.db
database. Because lady.uucp is found, the entire
$( to $) RHS expression is
replaced with lady.localuucp from the database.
Any UUCP hosts other than lady or
sonya would not be found in the database, so the
RHS expression would become the original workspace, unchanged.
Note that the
entire RHS is prefixed with a $:. This prevents
sendmail from retesting with the LHS after the
RHS rewrite. If this prefix were omitted, endless looping could
occur.
Also note that the -a switch of the
K command can be used to simplify the writing of
this rule. For example:
Kuucp hash -a.localuucp /etc/mail/uucp
The -a switch tells sendmail
to append the text .localuucp to all successful
lookups. Thus, the preceding database can be simplified to look like
this:
lady.uucp lady
sonya.uucp sonya
But the preceding rule remains the same:
R$- . uucp $: $(uucp $1.uucp $)
Beyond the simple macros and positional operators we have shown, the
key part can use other operators and forms
of macros. For example, delayed expansion macros can be useful:
R$&s $: $( uucp $&s $)
Here, the sender's host is looked up to see whether
it is a UUCP host. The $& prefix (Section 21.5.3) prevents the s macro from
being expanded as the configuration file is read. Instead, its value
will change with each piece of mail that is processed.
Additional examples of database lookups are given with the individual
type descriptions at the end of this chapter.
23.4.1 Specify a Default with $:
The $: operator can be
used as an alternative to the -a switch (or in
conjunction with it). The $: operator, when it
stands between the $( and $),
specifies a default to use instead of the
key, should a lookup fail:
R$- . uucp $: $(uucp $1 $: $1.uucp $)
Here, the $- part of the LHS is looked up in the
uucp database. If it is found, the
$( to the $) in the RHS
expression is replaced by the data from that database. If it is not
found, the $: causes the expression to be replaced
with the $- LHS part and a
.uucp suffix ($1.uucp).
This version of our rule further simplifies the contents of the
database file. With this rule, the database file would contain
information such as the following:
lady lady
sonya sonya
The -a is still used as before to append a
.localuucp to each successful match:
Kuucp hash -a.localuucp /etc/mail/uucp
In the RHS expression the $: must follow the
key or it loses its special meaning:
$(name key $: default $)
If the $:default wrongly
precedes the key, it is used as the key,
lookups fail, and replacements are not as expected. If the
$: is present but the
default is missing, a failed lookup
returns an empty workspace.
23.4.2 Specify Numbered Substitution with $@
For more complex substitutions, V8
sendmail offers use of the $@
operator in the RHS in conjunction with the $( and
$) expressions in database maps. There can be
multiple $@-prefixed texts
between the key and the $:
(if present) or the $):
$(name key $@ text1 $@ text2 $: default $)
Each $@text expression
is numbered by position (from left to right):
$(name key $@ text1 $@ text2 $: default $)
1 2
In this numbering scheme the key is always
number 0, even if no $@s are listed.
These numbers correspond to literal %
digit expressions in the data portion of a
database map. For example:
lady %0!%1@%2
When a lookup of the key in the RHS of the rule is
successful, the returned value is examined for
%digit expressions.
Each such expression is replaced by its corresponding
$@text from the rule.
In the case of the preceding database map, %0
would be replaced with lady (the
key), %1 with
text1, and %2 with
text2.
To illustrate, consider the earlier database entry and the following
rule:
R$- @ $-.uucp $: $(uucp $2 $@ $1 $@ mailhost $: $1@$2.uucp $)
If the workspace contains the address
joe@lady.uucp, the LHS matches. The RHS rewrites
only once because it is prefixed with the $:
operator. The expression between the $( and
$) causes the second $- from
the LHS (the $2, the
key) to be looked up in the database whose
symbolic name is uucp. Because
$2 references lady from the
workspace, lady is found and the data
(%0!%1@%2) is used to rewrite. The
%0 is replaced by lady (the
key via $2). The
text for the first $@
($1 or joe) then replaces the
%1. Then the second
text for the second $@
(mailhost) replaces the %2.
Thus, the address joe@lady.uucp is rewritten to
become lady!joe@mailhost.
If a host other than lady appeared in the
workspace, this RHS would use the
$:default part. Thus,
the address joe@foo.uucp would become (via the
$:$1@$2.uucp) joe@foo.uucp.
That is, any address that is not found in the database would remain
unchanged.
If there are more
$@text expressions in
the RHS than there are numbers in the value, the excess
$@text parts are
ignored. If a %digit in
the data references a nonexistent
$@text, it is simply
removed during the rewrite.
All $@text expressions must
lie between the key and the
$:default (if present).
If any follow the $:, they become part of the
default and cease to reference any
%digits.
23.4.3 $[ and $]: A Special Case
The special database-map type called
host can be declared to modify name-server
lookups with $[ and $]. The
special symbolic name and type pair, host and
host, is declared with the $(
and $) operators like this:
Khost host -a.
The -a switch was discussed earlier in
this chapter. Here, it is sufficient to note how it is used in
resolving fully qualified domain names with the $[
and $] operators in the RHS of rules. Under V8
sendmail, $[ and
$] are a special case of the following database
lookup:
$(host lookuphost $)
A successful match will ordinarily append a dot to a successfully
resolved hostname.
When a host type is declared with the
K command, any suffix of the -a
replaces the dot as the character or characters added. For example:
$[ lookuphost $] found, so rewritten as lookuphost.domain.
Khost host -a
$[ lookuphost $] found, so rewritten as lookuphost.domain
Khost host -a.yes
$[ lookuphost $] found, so rewritten as lookuphost.domain.yes
The first line shows the default action of the $[
and $] operators in the RHS of the rules. If
lookuphost can be fully qualified, its fully
qualified name becomes the rewritten value of the RHS and has a dot
appended. The next two lines show the -a with no
suffix (note that with no suffix the -a is
optional). In this configuration file, the fully qualified name has
nothing (not even a dot) appended. The last two lines show a
configuration file with a .yes as the suffix. This
time, the fully qualified name has a .yes appended
instead of the dot.
|