当sendmail在0号规则集中选择了一个邮件发送器后,它将通过1号规则集(通常是空的)来处理寄件人的地址,然后把它们发送到由这个邮件发送器中的S=标志所提供的规则集。
类似地,sendmail将把收件人的地址发送到2号规则集(通常也是空的)中进行处理,然后再把它们发送到邮件发送器的标志R=所提供的规则集。
最后,sendmail将在4号规则集中对所有地址进行后处理。4号规则集将把在3号规则集中插入的尖括号删除。
为什么不同的邮件发送器具有不同的S=和R=标志呢?考虑前面向zhang@somedomain.gov和posthost!zhao发送信件的例子。如果li@othedomain.com发送邮件,它必须针对每个收件人以不同的形式出现。对于zhang,它应该是一个域地址li@otherdomain.com;对于zhao,由于otherdomain.com希望老式的UUCP地址(假设它具有一个连向posthost的UUCP链接并且otherdomain.com的UUCP主机名是posthost),因此返回地址应该是otherdomain!li。zhang的地址也必须为posthost的UUCP邮件发送器进行改写,并且zhang的副本必须包括他的邮件发送器可以处理的posthost的地址。
当sendmail把一个地址传递给某个规则集后,规则集中的每一个规则行将逐行地对它进行处理。如果某个规则行的lhs与地址相匹配,地址将被Ihs改写;如果它不匹配,sendmail将继续到下一个规则,直到达到规则集的末尾为止。在规则集的最后,sendmail将把被改写的地址返回给调用规则集的规则集或是固有执行顺序的下一个规则集。
如果某个地址与lhs相匹配并且被rhs改写,这一规则将再次被调用——一个隐式循环。
如前面介绍,每一个改写规则都由R命令引人并且具有三个字段——左端(lhs或匹配端)、右端(rhs或改写端)以及可选的注释,各个字段之间必须由制表符隔开:
Rlhs rhs coment
sendmail将把地址和规则的lhs解析成标记,然后再逐个标记地把地址和lhs进行比较。宏$o包含sendmail用来把地址分隔成标记的字符,它通常具有如下的定义:
#address delimiter characters
Do.:%@!^/[]
$o中的所有字符,既是标记分隔符,又是标记。sendmail获取像xie@rainbow.org这样的地址,然后根据宏o中的字符把它分解成多个标记,就像下面这样:
“xie”“@”“rainbow”“.”“org”
sendmail也把改写规则lhs分解为标记,从而使它们可以同输人的地址一个个地相比较,以确定是否匹配。例如,lhs $ -@rainbow.org分解后的内容如下:
$-”“@”“rainbow”“.”“org”
其中“$-”是一个模式匹配操作符,类似于shell通配符,它用来匹配任何单一的标记符。现在可以把两组标记放在一起来揭示sendmail如何确定一个地址是否与规则的lhs相匹配。
“xie”“@”“rainbow”“.”“org”
“$”“@”“rainbow”“.”“org”
在此例中,由于来自地址的每个标记都匹配一个常量字符串(例如rainbow)或一个模式匹配操作符($-),因此地址和lhs相匹配并且sendmail将使用rhs来改写这一地址。接下来,考查一个改变$o值的效果。sendmail把地址xie@rainbow.org分解为五个标记;然而,如果@字符不在$o中,这一地址将完全不同地被分解为三个标记:
“xie@rainbow”“.”“org”
由此看来,改变$o将对sendmail的地址解析产生极大的影响。因此除非用户对自己所做的事情非常有把握,否则应该保持它的原状。
· 规则的左端(lhs)
lhs是sendmail用来与输入地址进行对比的模式,lhs既可以包含普通的文本,又可以包含任何模式匹配操作符。
lhs的模式匹配操作符主要包括:$-(匹配一个标记)、$+(匹配一个或多个标记)、$ *(匹配零个或多个标记)、$@(匹配空的输入,用来调用错误邮件发送器)。
在lhs中,还可以利用下列宏和类的匹配操作符:$ X(匹配宏X的值)、$=C(匹配类C中的任何一个词)、$~C(匹配不属于类C的任何一个标记)。
模式匹配操作符以及宏和类的匹配操作符是十分必要的,因为大多数规则必须匹配许多不同的输入地址。例如,某个规则可能需要匹配所有以somedomain.gov结尾、以一个或多个其他任何内容开头的地址。
· 规则的右端(rhs)
rhs是改写规则,其作用是通知sendmail如何来改写一个与lhs相匹配的地址。lhs可以包含文本、宏及对匹配内容在lhs中的位置把它匹配的内容赋值给一个数字宏$ n。例如,假设地址zhang@hostl.somedomain.gov被传递给下面的规则:
R $+@$+$:$1<@ $ 2>foucus on domain
在此例中,由于zhang与$+(一个或多个任何内容的标记)相匹配,因此sendmail将字符串zhang赋值给$ l;地址中的@与lhs中的@相匹配,但常量字符串不被赋值给位置宏;字符串hostl.somedomain.gov中的标记与第二个$十相匹配,因此它被赋值给了$ 2。这样被改写后的地址是$ l<@$ 2>,也就是zhang<@ hostl.somedomain.gov>。





