Not only is it possible to use defined macros in rule sets, as of
V8.10 sendmail it is also possible to place new
values into defined macros from inside rule sets. This marvel is
accomplished using the macro type database map. It
is an internal type, always available regardless of how
sendmail was compiled.
The macro type can be used in three ways. For
example:
Kstore_it_in macro
R$* $: $(store_it_in {MyMacro} $@ $1 $) store new value into macro
R$* $: $(store_it_in {MyMacro} $@ $) clear macro to empty string
R$* $: $(store_it_in {MyMacro} $) undefine the macro
The first line declares store_it_in to be the name
of a macro database-map type that is used in the
rules that follow. Those three rules show three different ways to
affect the value stored in the macro {MyMacro}.
Note that the macro name must not be prefixed with a
$. If it is, its value will be used as the name,
instead of its actual name. We cover the use of
$& later.
The first rule shows that the value to be stored into the macro is
passed as the first $@ argument, the
$1. If this value is that of an undefined macro,
the stored result is an empty string. Otherwise, the value is stored
as-is into the {MyMacro} macro. If the value
contains macro-like expressions (such as $x),
their values are copied used. If {MyMacro} was
previously undefined, it becomes defined.
The second rule shows what happens when the value to be stored is
missing (or undefined). A missing value has the effect of clearing
the value stored in the {MyMacro} macro to that of
an empty string. If {MyMacro} was previously
undefined, it becomes defined.
The third rule shows what happens when the argument part (the
$@ part) is omitted. The effect is to undefine the
{MyMacro} macro.
Regardless of how you update the value in the macro, an empty string
is returned. This can cause the original workspace to be lost. If you
need to preserve the original workspace (or part of it), consider a
variation such as the following:
R$* $: $(store_it_in {MyMacro} $@ $1 $) $1
return original workspace
This macro type can also be used as an indirect
way to store values into different sendmail
macros. To illustrate, consider the following mini-configuration file
and its use of $&:
V10
Kput macro
D{Target}{LocalTarget}
Stest
R $* $: $(put $&{Target} $@ $1 $)
Here the intention is to store the value (the $@
$1) into the macro whose name is stored in
{Target}. The D line
initializes that name as {LocalTarget}. To witness
this indirect method in action run this mini-configuration file in
rule-testing mode:
% /usr/sbin/sendmail -Cdemo.cf -bt
ADDRESS TEST MODE (ruleset 3 NOT automatically invoked)
Enter <ruleset> <address>
> test foo in local target
test input: foo in local target
test returns:
> ${LocalTarget}
foo in local target
> .D{Target}{NewTarget}
> test foo in new target
test input: foo in new target
test returns:
> ${NewTarget}
foo in new target
This sort of indirection can be useful in rules that might, for
example, cause one relay host to be selected under high load and
another under low load. Another use might be to reject certain
outside mail during business hours, but accept it after business
hours.
No database-map switches are useful with this type.