etc/maildroprc, $HOME/.mailfilter, $HOME/.mailfilters/*, and friends…
DESCRIPTION
本手册描述了被maildrop用来过滤 E-mail消息的语言.邮件过滤指令从一个文件中被读出来.该语言是宽松构成的,基于模式匹配.该语言有一个清楚的语法和句法结构,非常类似于Perl,但重要的是要记住它并非perl,并且在某些情况下非常不同于perl.
如果过滤指令不存在,maildrop在不做任何附加处理指令的情况下把消息递送给默认邮箱,和平常的MDA没什么不同.
注意:maildrop在做任何事之前先读取和解析过滤文件,这很重要。如果出现任何错误,maildrop打印一个错误信息,结束并将退出码设置为EX_TEMPFAIL.一个适当的MTA应该将该信息重新排队以便后面再次尝试投递.运气好的话,如果错误被捕捉到并很快地被修复,大多数简单的语法错误将不会导致邮件被弹回.
################################################################
环境
maildrop使用变量去访问和操作信件.变量是引用变量的名字来访问的任意文本,比如HOME,或DEFAULT.
文本通过一个赋值声明被放置到一个变量中,例如: FILE=”IN.junk”
这个语句将文本”IN.junk”(不带引号)放置到一个名为FILE的变量中去.之后,变量的内容通过使用$符号和变量名字来被使用,例如:to $FILE
这将投递当前的信件到一个名为”IN.junk”的mailbox文件(或者一个maildir目录)中。
除非maildrop运行在投递模式下,否则maildrop在最初会从操作系统的环境变量中创建变量.每个操作系统环境变量变成一个maildrop的变量.当运行在投递模式下时,maildrop出于安全原因不导入环境变量.在所有情况下,maildrop将下列变量重置为他们的默认值:
HOME, DEFAULT, SHELL, PATH, LOCKEXT, LOCKREFRESH, LOCKSLEEP, LOCKTIMEOUT, MAILDIRQUOTA, SENDMAIL 和 LOGNAME.
当连同Courier Mail Server一起使用的maildrop版本使用时,本规则有一个例外。下述不适用于maildrop的单用版:当在投递模式下运行的时候,如果 -d 标记不被使用,或者如果它指定与运行maildrop的用户相同的用户id,下列变量会被自动从环境中导入:HOME, SHELL, LOGNAME and MAILDIRQUOTA.这些环境变量在运行maildrop之前就被Courier初始化。还有,maildrop的变量 DEFAULT的初始值被从MAILDropDEFAULT环境变量中导入。这是因为 Courier 覆盖 DEFAULT 环境变量去存储本地邮箱地址的默认部分。请在Courier发行版查看dot-courier(5) man。 你可以通过使用import命令获取Courier的DEFAULT 值。记住,无论如何,那将会搞乱DEFAULT的旧有内容,那可能不是你所想要的。去做这个的正确方式是像这样:
SAVEDEFAULT=$DEFAULT
import DEFAULT
LOCALDEFAULT=$DEFAULT
DEFAULT=$SAVEDEFAULT
当maildrop作为一个外部命令运行时,所有的内部变量作为环境变量被导入回环境。由过滤文件造成的内部变量的改变,将被反映到被导入的环境中去。
################################################################
词法结构
大多数空白符通常被忽略。#字符引入了一个注释,一直到行末的整行都被忽略。不像其他的邮件过滤器一样,maildrop在针对信件进行任何动作之前先解析过滤文件。如果文件中有一个语法错误,maildrop显示一个错误信息,并返回EX_TEMPFAIL。这使得邮件信件保持在队列里面,并且,寄希望于使问题被纠正,而不弹回任何信件。
注意:在maildrop里面,行末是一个词法标记。为了在下一行继续一个长的语句块,结束本行的时候加上反斜杠符。
################################################################
字面文本值
maildrop 过滤语言中的字面文本值或者被单引号或者被双引号所环绕。为了在一个被单引号环绕的文本字面值中插入单引号,或者在被双引号环绕的文本字面值中插入双引号,在其前面加上反斜杠号。使用两个反斜杠字符来在字面文本值里插入一个反斜杠字符。
注意:一个反斜杠符后跟随一个反斜杠符或者一个对应的引号,仅仅是反斜杠字符被实际移除后剩下的字符在实际文本字面值中的本义。如果一个反斜杠后跟随其他任何字符,反斜杠不被移除。
一行中的多个文本字面值将被自动连接起来,哪怕他们使用了不同的引号。例如:
FOOBAR=”Foo”‘bar’
SAVEDEFAULT=$DEFAULT
import DEFAULT
LOCALDEFAULT=$DEFAULT
DEFAULT=$SAVEDEFAULT
This sets the variable FOOBAR to the text “Foobar”.
这设置了变量FOOBAR指向文本”Foobar”。
################################################################
变量替换
被双引号环绕的文本字面值的变量替换将被执行变量替换。”$”字符跟一个变量名,将被变量的内容所替换。
MAILBOX=”$HOME/Mailbox”
这设置了变量MAILBOX为 变量HOME的内容 加上”/Mailbox”,变量名必须以一个小写或大写字母或一个下划线开始。后面的所有字母,数字,和下划线被当作一个变量名,而它的内容取代$标记和变量名。访问名字包含其他字符的变量也是可能的,只要像下面这样使用括号:MAILBOX=”${HOME-WORD}/Mailbox” ,插入HOME-WORD变量的内容。如果变量不存在,空文本字面值被用来替换变量名。访问名字中不可能包含}字符的变量。
如果$字符后面不跟着一个左括号,字母或者一个下划线,$符号在文本字面值中就不会有麻烦。一个反斜杠后跟着一个$字符结果是一个文本字面值的$字符,不做任何变量替换。
在被单引号(即省略号,呼号)环绕的文本字面值里,变量替换不会进行。
################################################################
命令行参数
maildrop 使用在maildrop命令行中递增的参数来初始化指定变量:$1,$2,等等。过滤文件可以像使用其他变量一样使用这些变量。
预定义变量
下列变量被maildrop自动定义。下列变量的默认值可以被系统管理员改变。出于安全原因,下列变量的值总是被重设为他们的默认值,并且决不从环境中导入。
default
投递信件到的默认邮箱。如果过滤文件没有指明投递该信件到哪个邮箱,将被投递到这个邮箱。默认邮箱被定义为系统管理员。
FROM
信封发件人。这个一般和出现在From:头里的地址相同,但也可能不是。这个信息对于你系统上的maildrop可能可用也可能不可用。信件信封发件人一般通过maildrop的-f选项被指定。如果-f选项没有被给出,maildrop在信件里寻找From_行。作为最后的办法,From默认为调用maildrop的用户id。记住From可能是空的-对于弹回的邮件来说,邮件信封发件人就是空的。
HOME
运行maildrop的HOME用户目录
HOSTNAME
运行maildrop的机器的网络名,从gethostname(3)中获得的。
LOCKEXT
dot-lock文件的扩展名(默认: .lock)
LOCKREFRESH
点锁以秒计的刷新间隔(默认:15)。当maildrop 锁住一个邮箱后,maildrop为了防止别的程序移走失效的点锁,尝试周期性地刷新点锁。如果一个点锁存在了一段无论如何理应放弃的时间后,这只是必需的。
LOCKSLEEP
如果一个点锁文件已存在,等待再次尝试创建一个点锁文件的秒数(默认:5)。
LOCKTIMEOUT
移除一个失效的点锁文件前等待的秒数(默认:60)。如果一个点锁文件在 LOCKTIMEOUT 秒后仍然存在,maildrop假设持有锁的进程已不存在,点锁文件可以被安全地移除。移除点锁文件后,为了避免和别的进程产生竞争条件,maildrop 在尝试创建它自己的点锁文件之前等待LOCKSLEEP秒,——这些进程同一时刻也正在尝试着移除相同的失效点锁。
LOGNAME
信件讲被投递给的用户的名字。
MAILFILTER
被传给maildrop命令行的原始过滤文件的名字。这通常对 -frgsuly 过滤文件来说有用,允许他们获取在命令行上指定的-M选项的值。
PATH
命令执行路径。maildrop将其重设为系统默认(一般是 /bin:/usr/bin/:/usr/local/bin )
SENDMAIL
邮件投递代理。当maildrop被指示将邮件交付给一个名字以!字符起始的邮箱时,这被翻译为一个转寄信件的请求。SENDMAIL 命令被执行来转寄信件。
SHELL
登录shell。shell被用来执行所有被maildrop调用的命令。
VERBOSE
当前debug层(默认 0)。设置VERBOSE 为一个递增更大的值,介于1到9,在标准错误上产生一个调试输出。maildrop在 投递模式下忽略VERBOSE变量(为了不去弄乱邮件传送代理MTA)。
UMASK
以十进制的文件创建掩码。默认的077设置创建的仅拥有者可读可写的邮箱。使用007创建用户和同组可读可写的邮箱。使用037创建用户和同组都可读的邮箱,但是只有用户可写。已存在的邮箱权限不被改变,该设置仅作用于新邮箱。当投递到maildir时,该设置仅设定新邮件的权限。maildir里信件的访问权限也被maildir目录的权限所影响。
################################################################
其他特殊变量
下列变量当过滤文件被处理时,被maildrop自动使用。
EXITCODE
maildrop的返回值。当maildrop成功地投递一个信息后,它带着一个结束码终止,这个结束码默认为0。当to或cc命令被用来投递信息到一个外部进程的时候,通过pipe管道,maildrop将设置该变量为一个外部进程的退出码。因为maildrop完成to命令后立即终止,这就意味着maildrop的退出码就是外部进程的退出码。如果to命令不是把信件投递给一个进程,你必须在to命令前设置EXITCODE,既然maildrop结束了投递之后立即终止。
LINES
当前信件的行数。注意这可能是个大概值。它可能也可能不把-A选项或者任何mbox “From” 行算进去。为了过滤,使用这个作为标准而已.
MAILDIRQUOTA
为了手动地在任何信件投递的maildir上强制一个最大大小,设置这个变量。这是个必须被系统管理员启用的可选项,请见maildirquota(8)来获取更多的信息。
RETURNCODE
当maildrop运行xfilter命令或者一个由一对反点号字符指定的命令时,该变量被设置。RETURNCODE变量在命令结束后将被设为命令的退出码。
SIZE
信件的比特数。这可能也可能不包括-A选项,以及mbox From_行。为了过滤,使用这个作为标准而已
################################################################
未引号引用的文本
所有过滤文件中的文本字符串应该在单引号或者双引号内。可是,为了方便的缘故,引号在一定的情况下可以被忽略。
仅包括字母,数字和这些字符: _-.:/${}@ 的文本可不带引号而出现。注意,这不允许空格反斜杠介入,无论如何,文本仍然可以变量替换,并且替换文本可以包含其他字符。
还有,记住模式(下面提到)以斜杠字符开始。一般来说,任何以斜杠开始的东西都被解释成一个模式。但是,”VARIABLE=”后面紧随的文本被解释成字符串即使它以斜杠开始。这就是为什么一些像这样:MAILDIR=/var/spool/mail 会符合预期地工作。但是使用引号是被高度推荐的。你必须使用引号去设置一个变量为一个长斜杠,因为一个不被引住的斜杠被解释为一个除号。
################################################################
命令替换
被反点号`包住的文本被解释成一个shell命令.shell命令被maildrop作为一个子进程执行,它的输出被用来取代该命令.例如:DIR=`ls`将当前目录下的文件名字放入DIR变量.
命令的输出的新行字符 将被空格所取代,头尾空格将被去掉(虽然多个空格并不被移除).还有,被投递的信件的内容对于命令的标准输入来说将变得可用.
################################################################
模式
maildrop的模式语法和grep命令的语法是类似的,只有一些小小不同.一个模式在过滤文件中使用下述的格式: /pattern/:options 模式指定了在信件里要去寻找的文本.如果你必须搜索以空格开头的文本,请使用诸如 “/[ ] … /” 这样的格式,因为对模式而言,起始的斜杠字符将被解释为一个除号.
一个精确匹配被寻找时,下列字符有异常.下列的特殊字符被用来指定复杂模式.如果有必要在信件中去寻找下列字符中的一个,请逐字地在其之前放置一个反斜杠.(例子中的”x”和”abc”表示一个任意字符,或者一个也可以包括其他特殊字符的模式.)
x*
寻找0个或更多个单字符x的出现.
(abc)*
寻找0个或更多个 abc 的出现.
x+
寻找至少一个或更多个单字符x的出现.
(abc)+
寻找至少一次或更多次的 abc 的出现.
x?
寻找单字符x的0或1次的出现.
.
句点匹配除了新行符的任何字符.(这也适用于集合,见下)
(abc)?
寻找0或1次的 abc 的出现.
abc!def
感叹号被用来分隔被匹配的部分.请见下述的”模式匹配结果”一节.
[abc]
指定一个字符集合 — 上述匹配一个或者a或者b或者c或者所有括弧里列出的字符.
一个或多个字符可以被列出来.比如,[~=+]匹配或者一个 拉丁语发音符~,一个等号=,或者一个加号+.这完全等价于(~|=|+),但是和一个大清单比起来,这个更短.
另外,[a-b]匹配介于a和b之间的任何字符,包括自身.比如:[0-9]匹配一个数字,[0-9A-Za-z_] 匹配数字、字母或下划线。要在集合中包括连字号-,左括号或右括号字符,在他们前面加上反斜杠。使用两个反斜杠则包含了反斜杠自身。(不同的是,历史上包括这些特殊字符的方式是被允许的,但是不被鼓励使用)
[^abc]
指定一个不是给定字符的字符集合。如果集合以^符号开始,它匹配一个不是列出字符的单字符。
\x
当”x”是一个字符时,指定x必须精确匹配。为了逐字地匹配任何指定字符(例如,你想去匹配星号*)你必须在前面加一个反斜杠字符。使用两个反斜杠字符是为了匹配反斜杠。还有,这里有几个保留的匹配控制字符,没必要在模式中逐字地介入它们。请见下面的信息。
\nnn
指定一个十进制的字符,”nnn”是一个十进制数字。
下述的简化符号能够被用来指定一些普通的集合。注意,maildrop总是使用 “C” locale。
[:alnum:]
一个文字数字式字符,等于[0-9A-Za-z].
[:alpha:]
一个大小写字母,等于[A-Za-z].
[:cntrl:]
A control character.
一个控制字符。
[:digit:]
一个数字,等于[0-9].
[:graph:]
一个图形字符(一个不是空格的非控制字符)
[:lower:]
一个小写字母,等于[a-z].
[:print:]
一个可打印字符(非控制字符)
[:punct:]
一个标点符号字符。
[:space:]
任何空白字符
[:upper:]
一个大写字母,等于[A-Z].
[:wbreak:]
任何非字母,数字,或者下划线的字符,等于[^a-zA-Z0-9_].
[:xdigit:]
一个十六进制数字,等于[0-9A-Fa-f].
要匹配任何指定字符,就在它前面放置一个反斜杠。比如,\?匹配问号。要匹配一个反斜杠,使用\\ 。
正常情况下,模式能够在信件的信头和信体的任何地方被发现(见下)。尽管如此,在模式的开始放置字符^迫使模式仅去匹配行首。在模式结尾放置$字符迫使模式仅匹配行尾。
在模式的其他地方,$符号被用来变量替换(见上)。要在模式里包含$字符,前面加上反斜杠。
################################################################
其他的反斜杠转义
当被用作模式说明时,下述的反斜杠字符被解释如下。
\n
匹配新行符。记住,这仅在w选项被指定时生效,因为若没有这个选项,maildrop将不识别多行模式。
\r
匹配一个回车符。记住,maildrop在行末自动地忽略回车符。我不知道为什么你会去使用/r,但是若你需要的话它就在那。
\t
匹配一个tab。
\f
匹配一个换页符。
\v
匹配一个纵向tab。
在行末使用一个单独的反斜杠字符,长的双引号或单引号文本可以被打断跨过多行。像这样:
TEXT=”This is a long \
?text string”
新行上的反斜杠,新行符,和所有的起始的空格均被移除,结果是”This is a long text string”.
################################################################
模式选项
/pattern/之后,经常是一个可选的冒号,跟随一个或多个选项.下述的选项可以以任何顺序被指定.
h
在信头中匹配这个模式.
b
在信体中匹配这个模式.
w
在信头和/或信体中匹配这个模式.
D
这是一个大小写敏感的匹配.通常模式匹配或者是大写或者小写文本./john/将会匹配”John”, “john”, 或 “JOHN”.
指定D选项作为一个大小写敏感的搜索:模式中的小写字符必须匹配信件中的小写字符;大写字符一样。
请注意 ‘b’和’w'选项将会花费过多的CPU时间,可能的话应该尽量避免。
提示:如果可能,使用SIZE变量来避免用这些标记来对一个大邮件使用模式。
如果’h'或’b'都不被指定,模式仅去匹配信头。指定’b'选项时的模式去匹配信体。两个都指定使得模式去匹配整个信件。
通常,信件的每一行独立地进行模式匹配,当应用模式到信头上时,在模式应用之前,多行信头(信头被分成几行,每一个继续的行以空格开头)被悄悄地组合成一行。指定’w'标记使得模式被应用到被搜索的信件的整个部分([译注:指定信件的哪部分]这是通过h和b标记的出现与否来指定的)。还有,如果’w'被适用,但是’h'和’b'标记都没使用,’b'标记被默认指定,而不再是’h'标记被默认指定了。
该标记也改变了^和$在模式里被解释的方式。通常,这些字符在每行的行首或行末锚定模式。当’w'标记被指定时,^和$锚定或者信头或者信体或者两者均有的开始和末尾。
################################################################
权重打分
模式被maildrop求值作为任何别的数值表达式。如果一个模式被发现,出于过滤得目的,maildrop的过滤将模式匹配的结果作为数字1,或者真。如果模式没有被发现,模式搜索的结果是0。一旦一个模式被发现,搜索停止。第二个相同的模式和后面的模式都不再被搜索。
maildrop也能做权重打分。在权重打分时,相同模式的多个出现被用来累积数字分值。
要使用权重打分,像下面这样指定模式:
/pattern/:options,xxx,yyy
xxx和yyy是两个数字,yyy是可选的 –如果没写出的话,它将默认为1。
第一个出现的模式被评分为xxx。第二个出现的模式被评分为xxx*yyy,第三个出现的是xxx*yyy*yyy,等等。所有模式的出现被增加来累计最后的得分。
注意:当w选项没有被指定时,maildrop不能识别同一行内同一模式的多次出现。这是为了^和$操作符正确工作所必需的。例如:/^Received:/:1
该模式计算信件有多少 Received: 信头,并且不能识别文本”Received:”在信头其他任何地方的任何出现。
为了考虑同一信件内的相同模式的多次出现,你应该指定w选项。这也激活所有的’w'选项的惯用语义。例如:
/[:upper:]/:wbD,1
计算大写字母在信体内出现的次数。
################################################################
模式匹配结果
模式被成功地匹配之后,匹配的实际文本被放入MATCH变量内。比如:
/^From:.*/ 匹配一行这样的格式:From: postmaster@localhost
这里,变量MATCH将被设置为”From: postmaster@localhost“,该变量可被用到后面的语句中。在模式中使用!字符使得使用匹配字符串的可选部分成为可能。例如:/^From: *!.*/
匹配上面同一行会将MATCH设为”From: “并且MATCH2设为”postmaster@localhost“.多于一个的!字符也可以被使用,后面的匹配文本将被指派给MATCH3,MATCH4等等。
注意:请记住这个特征的弊端是将吃掉大量的CPU时间 — !字符为maildrop处理引入了大量复杂性。
当这里有不止一种方式去匹配字符串时,maildrop偏爱从最初尽可能多地匹配。例如:/^To:.*,!.*/
当匹配
To: joe@somewhere,bob@somewhere.else,gary@whoknowswhere
时,将MATCH设为”To: joe@somewhere,bob@somewhere.else,” 并且 MATCH2 设为”gary@whoknowswhere“.
当权重打分的时候,MATCH变量将不被设置,因为相同的模式被匹配了多次.
################################################################
===========
表达式
虽然用数字求表达式的值,但是表达式的结果被存储为一个文本字面值.当必要时,文本字面值被转换成数字,然后一个数学运算的结果被转换回一个文本字面值.
Operators
=========
操作符
下述操作符使用它们通常的含义,依照最低到最高优先级的顺序被列出来.
||
&&
< <= > >= == != lt le gt ge eq ne
|
&
+ -
* /
=~ /pattern/
/pattern/ ! ~ function()
Variable assignment
===================
变量赋值
VARIABLE=expression
将表达式的结果赋值给VARIABLE (记住没有在变量之前放置$)
注意: 如果VARIABLE不被引号引住,那么它仅可以包括字母,数字,下划线,连字符和一些可选的其他字符.为了初始化一个名字包含非标准标点符号的变量,使用引号将变量的名字引起来.
==================================
cc - 交付一个信件的副本
cc expression
cc 语句非常类似于 to 语句,只是一点除外:maildrop投递完信件后将会继续处理过滤文件,而不像to语句一样投递完成后立即终止maildrop.本质上,信件被复制到一个给定的邮箱,可以通过另一个cc或to语句来被再次投递到另一个邮箱.
请见to语句来获取更多的细节.当cc被用来投递一封信件到一个进程时,maildrop将EXITCODE变量设置为进程的退出码.
dotlock - create a manual dot-lock
==================================
创建一个手工的点锁
dotlock expression {
…
}
当信件被投递到一个邮箱时,maildrop自动创建一个锁.maildrop将根据你的系统配置来使用点锁或者flock()系统调用.
dotlock语句创建一个显式的点锁文件.使用flock语句来创建一个显式的flock锁.
表达式是一个应被用作点锁的文件名.maildrop创建指定的点锁,执行包含在{…}块中的过滤指令,并且移除锁.表达式必须是点锁文件自身的名字.而不是你想锁住的邮箱的名字.
注意:使用手动锁有可能死锁多个maildrop进程(或者任何其他试图获取相同的锁的进程)
对点锁来说没有死锁检测是可能存在的,并且既然maildrop自动地规律性地刷新所有的点锁,他们将决不会坏死失效。你将使maildrop进程半悬在死狱中,直到他们的监控计时器关闭的同时放弃邮件投递。
echo - output diagnostic information
====================================
echo - 输出诊断信息
echo expression
maildrop将打印给定的文本。这经常在maildrop运行在内嵌模式时使用,但是也能用作调试的目的。通常,一个新行符在文本之后被打印。如果文本以\c结束,新行符不会被打印。
exception - trap fatal errors
=============================
exception - 捕获致命错误
exception {
…
}
异常语句捕获那些通常将导致maildrop终止的错误。如果在任何被异常语句包含的语句块里碰到一个致命错误,异常语句之后紧随的语句将被执行。
exit - terminate filtering unconditionally
==========================================
exit
exit 语句立即终止过滤。maildrop的返回码被设为EXITCODE变量的值。通常,maildrop成功投递信件到一个邮箱后立即终止。exit语句使得maildrop不投递信件到任何地方而终止。
通常当maildrop运行在内嵌模式,当信件投递指令(译注:cc,to,xfilter?)不被允许时,exit语句被使用。
flock - create an manual flock() lock
=====================================
flock - 创建一个手动的flock()锁
flock expression {
…
}
当信件被投递到一个邮箱时,maildrop自动创建一个锁.maildrop将根据你的系统配置来使用点锁或者flock()系统调用.
flock 语句创建一个手动的flock()锁.使用 dotlock 语句来创建一个手动的点锁.
表达式是一个应被锁定的文件的名字.maildrop在指定的文件上创建锁,执行包含在{…}块中的过滤指令,并且移除锁.
注意:使用手动锁有可能死锁多个maildrop进程(或者任何其他试图获取相同的锁的进程)操作系统将自动地打破flock()的死锁状态。当此情况出现时,一个maildrop进程将立即终止。为了去捕获这个异常条件,请使用异常语句,并且执行一个二者择一的过滤指令集合。
foreach - iterate over text sections matched by a pattern
=========================================================
foreach /pattern/:options
{
…
}
foreach (expression) =~ /pattern/:options
{
…
}
foreach语句为每个给定模式在给定信件内的出现 执行一个语句块。在每个迭代里,MATCH变量将被设为匹配的字符串。所有通常的选项都可以被应用到模式匹配上,除了下面这些:
,xxx,yyy
在这种语境里,权重打分是无意义的。
!
模式里的!操作符不会像预期的那样工作。对每个迭代来说,只有MATCH变量将被设置。如果模式包含!操作符,语句将为了匹配字符串里的每个部份执行一次,MATCH变量也随之被设为每个部分的内容。
if - conditional execution
==========================
if (expression)
{
…
}
else
{
…
}
条件执行。如果表达式求值为逻辑真(记住-圆括号是必需的),然后,语句的第一个集合被执行。else关键字,以及下面的语句是可供选则。如果表达式出现且求值为逻辑假,else部分被执行。
maildrop 对所有的表达式作为文本字符串求值。在一个逻辑表达式的语境下,一个空字符串,或者数字0,构成了一个逻辑假的值,任何其他的情况都是逻辑真值。
如果if部分,或者else部分仅包括一个语句,括号可以忽略。
注意:这个if语句的文法比通常的更严格。如果你从maildrop得到了令人困惑的语法错误,保证括号和if语句,出现在不同的行上。特别的:闭括号,和else语句,必须在本行行末(允许注释),并且在其间不能有任何空行。
import - access original environment variable
=============================================
import - 访问原始环境变量
import variable
当maildrop开始时,它通常导入环境变量的内容,并且将他们赋值给maildrop的内部变量。比如,如果有一个环境变量FOO,内部的maildrop变量FOO将拥有环境变量的内容。从那之后,FOO将和别的变量没有什么不同,并且当maildrop运行一个外部命令时,maildrop变量的内容将为了命令被作为环境变量导入。
一定的变量,像 HOME和PATH,出于安全原因,总是重设为固定的默认值。在投递和内嵌模式下,环境一点都不被导入,并且maildrop仅随着固定的默认变量启动。
import语句当maildrop启动的时候,使用原始的环境变量初始化指定变量。例如:
echo “PATH is $PATH”
PATH=”/bin”
echo “PATH is $PATH”
import PATH
echo “PATH is $PATH”
exit
结果是下列输出:
PATH is /bin:/usr/bin:/usr/local/bin
PATH is /bin
PATH is /home/root/bin:/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/bin
这显示了maildrop启动的时候,PATH被设为固定的默认值 /bin:/usr/bin:/usr/local/bin。但是,我们可区分这和 import语句所展示的PATH环境变量的原始内容并不相同,。
include - execute filtering instructions from another file
==========================================================
include expression
include语句读一个文件,并且执行包含在文件中的过滤指令。注意include语句在当前过滤文件被执行的时候被处理。当maildrop读取初始过滤文件,任何在过滤指令中的语法错误将被立即报告,maildrop将随着EX_TEMPFAIL返回码而终止。任何被include语句指定的文件中的错误将不被报告,因为直到include语句被自身执行的时候这些文件才被读取。
如果指定的文件不存在,或如果在文件里有任何语法错误,maildrop报告这个错误,并且随着EX_TEMPFAIL返回码而终止。
log, logfile - log message deliveries
=====================================
log, logfile - 记录信件投递日志
logfile expression
log expression
maildrop的日志记录通常是关闭的。logfile语句指定了maildrop记录信件怎样被处理的文件。参数是文件的名字。如果文件存在,maildrop添加文件。
对于每个投递来说(to和cc语句,以及默认的投递),maildrop在日志文件里记录了From: 和 Subject: 头域,以及当前时间。
log语句将增加另外的日志文本到日志文件中。log语句完全就像echo语句一样工作,除了文本被写到日志文件中而不是标准输出。
to - deliver message to a mailbox
=================================
to - 投递信件到一个邮箱。
to expression
to语句将信件交付到一个邮箱。expression 的值必须是一个有效的mailbox。一个有效的mailbox或者是一个mailbox,一个maildir,或者一个外部的程序(该程序包括转寄到另一个地址)
to语句是最后的投递语句。maildrop投递邮件,然后产生一个返回码给EXITCODE变量并立即终止。如果当投递信件时有一个错,maildrop将伴随EX_TEMPFAIL退出码终止。一个编写得适当的邮件传送代理MTA应该重排邮件,并在一段时间之后再次尝试投递。
一个以”|”字符开始的expression 指定了一个外部程序来运行处理实际的投递。SHELL变量指定了shell来执行给定的命令。信件被通过标准输入提供给命令。maildrop的退出码将是该进程的退出码。
以一个感叹号”!”开始的 expression 指定了一个空格分隔的E-mail地址列表来将信件转寄出去。被SENDMAIL变量指定的程序被作为一个外部程序来运行,以及一个作为程序参数的 E-mail地址列表。
另外,expression 指定了maildrop将信件投递到的邮箱名。如果expression 是一个目录,maildrop假设目录是一个maildir目录。否则,maildrop将把信件以传统的mailbox格式投递到一个文件。maildrop在投递信件到一个文件时 将使用 点锁 或flock()锁 。
while - repeatedly execute a block of statements
================================================
while - 重复执行一个语句块
while (expression)
{
…
}
expression被重复地求值。若每次它的求值到一个逻辑真,括号里的语句将被执行。当expression 求值为一个逻辑假的时候,while循环完毕。注意避免无限循环。
xfilter - filter message through another program
================================================
xfilter - 通过其他程序过滤信件
xfilter expression
expression 指定了一个maildrop运行的过滤当前信件的外部程序。当前信件将被作为标准输入pipe给过滤程序。过滤程序的标准输出替代了当前的信件来被投递。外部程序必须以结束码0终止。如果外部程序没有以结束码0终止,或者如果它没有从标准输入读信件,maildrop将随着一个EX_TEMPFAIL退出码而终止。
|| - logical or
===============
|| - 逻辑或
expression1 || expression2
如果 expression1 求值为一个逻辑真,|| 的结果是expression1,否则是expression2的求值。
maildrop 使用下列的真/假概念:一个空的文本字面值,或者一个包含单独的字符”0″的文本字面值是一个逻辑假值。任何别的值是逻辑真值。
&& - logical and
================
&& - 逻辑与
expression1 && expression2
如果expression1 求值为一个逻辑假,&& 的结果是expression1,否则是expression2的求值。
maildrop 使用下列的真/假概念:一个空的文本字面值,或者一个包含单独的字符”0″的文本字面值是一个逻辑假值。任何别的值是逻辑真值。
<, <=, >, >=, ==, != - numerical comparison
=============================================
<, <=, >, >=, ==, != - 数字比较
expression1 < expression2
expression1 <= expression2
expression1 > expression2
expression1 >= expression2
expression1 == expression2
expression1 != expression2
这些操作符比较他们的左手表达式和右手表达式。这些操作符作为浮点数比较每一边的数字值,如果数字像所说的那样比较,比较的结果是文本字符串”1″,否则是文本字符串 “0″.
注意: 比较操作不符合结合律:”a<b<c” 是错的。如果必须需要,使用 “(a<b)<c”.
lt, le, gt, ge, eq, ne - text comparison
========================================
lt, le, gt, ge, eq, ne - 文本比较
expression1 lt expression2
expression1 le expression2
expression1 gt expression2
expression1 ge expression2
expression1 eq expression2
expression1 ne expression2
这些操作符比较它们的左手表达式和右手表达式。这些操作符作为文本字符串来比较两边(按字母顺序,虽然文本里可以包括任何东西)。如果文本字符串像所说的那样比较,比较的结果是文本字符串”1″,否则是文本字符串 “0″.
注意: 比较操作不符合结合律:”a lt b lt c” 是错的。如果必须需要,使用 “(a lt b) lt c”.
| - bitwise or
==============
| - 比特或
expression1 | expression2
这是比特或操作符。它的结果是一个32位的整数,该整数是左手值和右手值的比特或合并体。
& - bitwise and
===============
& - 比特与
expression1 & expression2
这是比特与操作符。它的结果是一个32位的整数,该整数是左手值和右手值的比特与合并体。
+, -, *, / - numerical operations
=================================
+, -, *, / - 数字操作
expression1 + expression2
expression1 - expression2
expression1 * expression2
expression1 / expression2
These are numerical, floating point, operators.
这些是数值,浮点数操作符。
=~ /pattern/:options - pattern match against string
===================================================
=~ /pattern/:options - 字符串的模式匹配
expression =~ /pattern:option
=~的左手值可以是任何表达式。右手值则始终是一个模式指定。该操作符的结果是左手值expression 的模式权重匹配(如果选项没指定任何权重打分,结果只是简单地在模式被发现时为1,没发现时则为0)。
请见”模式” 获取更多信息。
/pattern/:options - pattern match against message
=================================================
/pattern/:options - 信件的模式匹配
expression =~ /pattern:option
该操作符的结果是当前信件的权重模式匹配(如果选项没有指定权重打分,如果发现了模式结果简单地被设为1,未发现则为0)
See “Patterns” for more information.
!, ~ - logical/bitwise not operator.
====================================
!, ~ - 逻辑/比特 非操作符
! expression
~ expression
!操作符的结果是它右手表达式的逻辑相反值。如果右手表达式求值为逻辑真,结果是逻辑假。如果它求值为逻辑假,结果为逻辑真。
maildrop 使用下列的真/假概念:一个空的文本字面值,或者一个包含单独的字符”0″的文本字面值是一个逻辑假值。任何别的值是逻辑真值。
~操作符的结果是它右手表达式的比特补码。右手表达式估值为一个32比特的整数,这个操作符的结果是这个值的比特补码。
escape(string) - escape special characters in a string.
=======================================================
escape(string) - 逸出字符串里的特殊字符
escape(expression)
escape函数返回它唯一的参数以及每一个前面有反斜杠的特殊字符。特殊字符是指任何一个下列的字符:
|!$()[]\+*?.&;`’-~<>^{}”
当匹配模式分段的时候,这能被用到,然后取到一部分然后再匹配一次。比如:
if ( /^From: *!.*/ )
{
MATCH2=escape($MATCH2)
if ( /^Subject:.*$MATCH2/ )
{
…
}
}
该例子检验是否From:信头的内容也能够在Subject:信头中被发现。如果不使用escape函数,那么任何From:信头中的特殊字符也将被用在正则表达式中,比如 * 或 + ,将引发不可预知的行为,就像语法错误一样。
为什么这个特殊字符列表也包括那些不能被用在maildrop的正则表达式中的字符的原因是允许maildrop的变量被用在 shell命令的命令行中,这些shell命令被 xfilter 指令或`字符或to或cc指令所执行。
虽然从一个外部数据源使用数据是危险的,并且它可以导致疏忽的exploits,使用escape函数将有望更少导致的古怪问题。
gdbmopen, gdbmclose, gdbmfetch, gdbmstore - GDBM support in maildrop
====================================================================
gdbmopen, gdbmclose, gdbmfetch, gdbmstore - maildrop 对 GDBM 的支持。
这些函数提供了GDBM数据库文件的支持。请见 maildropgdbm(5)来获取更多信息。
注意: 系统管理员能够在maildrop中禁用GDBM支持,所以这些命令对你来说可能不可用。
getaddr(string) - extract RFC 2822 addresses from a header.
===========================================================
getaddr(string) - 从一个信头中萃取 RFC 2822 地址
if ( /^From: *!.*/ )
{
ADDR=getaddr($MATCH2)
}
该函数通常被应用到一个包含RFC2822地址的信头上。它从信头中抽取出实际的地址,不带任何注释和无关符号。每个地址跟随一个新行符。例如,如果字符串包含:joe@domain.com (Joe Brown), “Alex Smith” <alex@domain.com>, tom@domain.com
getaddr函数的结果是下列字符串:joe@domain.com<NL>alex@domain.com<NL>tom@domain.com<NL>
注意:因为getaddr()宽松地解释RFC2822,在字符串传递给getaddr()之前去掉”To:”或”Cc:”信头是没有必要的。例如,下列代码片段获取信件中所有的地址,并把它们连接成一个以空白分隔的单独字符串。
ADDRLIST=”"
foreach /^(To|Cc): .*/
{
foreach (getaddr $MATCH) =~ /.+/
{
ADDRLIST=”$ADDRLIST $MATCH”
}
}
注意:在一定的罕见情况下,RFC2822允许空格被包含在E-mail地址中,所以该例只是作为教学而已。
hasaddr(string) - Search for an address.
========================================
if ( hasaddr(string) )
{
…
}
“string” 使用user@domain的格式。如果该地址被包含在任何 To:,Cc:,Resent-To:,或Resent-Cc:信头中,hasaddr函数返回1,否则该函数返回0。
这不仅只是一个简单的文本查找。每个信头根据RFC822被解析。信头中发现的地址被抽取出来,忽略掉所有的注释和名字。剩下的地址被检验,并且如果”string”是其中一个的话,hasaddr返回1,否则它返回0。
这个比较是大小写敏感的。这实际上有点违背RFC2822(以及其他),因为地址的用户部分可以是(但不是必需)大小写敏感的。
length (string) - length of a string
====================================
if (length(string) > 80)
{
…
}
length函数返回字符串里的字符数目。
lookup (expr, ‘filename’, ‘options’) - read file for patterns
=============================================================
if (lookup(expr, file, “option”))
{
…
}
expr是任何表达式。filename是一个包含模式列表的文件的名字。记住filename是相关于当前目录的,当maildrop运行在投递模式下,当前目录一般是用户的home目录。maildrop然后读取文件。空行被忽略,任何以#字符开始的行(注释)也是这样。
先导空格(但不是尾部的空格,注意)被移除,每行剩下的内容被解释为一个模式,用来匹配expr。一当匹配被发现,lookup返回”1″。如果读完整个文件后都没有发现匹配,lookup返回”0″。
if ( /^To: *!.*/ && lookup( $MATCH2, “badto.dat” ))
{
exit
}
文件 badto.dat 包含下列两行:
friend@public
^[^@]*$
如果一封信件有一个包含文本 “friend@public” 的To:信头,或者一个@字符都不包括,那么信件将被静静地丢弃(maildrop将终止且不投递信件到任何地方)
options 就是用来模式匹配的选项。仅有的支持选项是”D”(在这种情况下,其余选项是无意义的)
注意:要当心这样丢弃信件。模式匹配可能是很诡异的,一个轻微的误算就可能导致邮件非故意地被丢弃。先将该信件投递到一个单独的文件夹或者邮箱会让人满意,一旦过滤被证明正确运行之后,再修改它以使得信件被完全丢弃。
substr(string,start [,count]) - return substring
================================================
foo=substr($foo, 1, 10)
substr函数从字符串里获取从第start个开始的字符。如果count被指定,从位置start开始的最多count个字符被保持住,任何多余的都被删掉。
time - return current time
==========================
foo=time
time函数返回以秒计算的自1970.1.1至今的当前时间,这个函数当使用GDBM文件时是有用的。请见maildrop(5)来得到一个使用此time函数的例子。
tolower(string) - Convert string to lowercase.
==============================================
foo=tolower(string)
该函数返回大写字符被小写字符替换后的 string。
toupper(string) - Convert string to uppercase.
==============================================
foo=toupper(string)
该函数返回小写字符被大写字符替换后的 string。
#####################################################
Statements
声明
过滤文件被maildrop读取,并且它包含了每行一个过滤指令。被maildrop所以用的过滤语言有一个宽松定义的语法结构。
语句被每个一行地列出来。多个语句可以通过用分号分隔来列出在同一行上。要在下一行继续一个长语句,终止本行的时候加上一个反斜杠符。
#####################################################
BUGS
如果getaddr() 或者 hasaddr() 函数被用在被破坏的信头上,结果是不可预知的。
hasaddr()完全是大小写敏感的。这实际上违背了一些RFC。因为一个地址的用户id部分可能是大小写敏感的,但这种情况不是很多,所以列在这里
自由广告区 |
分类导航 |
邮件新闻资讯: IT业界 | 邮件服务器 | 邮件趣闻 | 移动电邮 电子邮箱 | 反垃圾邮件|邮件客户端|网络安全 行业数据 | 邮件人物 | 网站公告 | 行业法规 网络技术: 邮件原理 | 网络协议 | 网络管理 | 传输介质 线路接入 | 路由接口 | 邮件存储 | 华为3Com CISCO技术 | 网络与服务器硬件 操作系统: Windows 9X | Linux&Uinx | Windows NT Windows Vista | FreeBSD | 其它操作系统 邮件服务器: 程序与开发 | Exchange | Qmail | Postfix Sendmail | MDaemon | Domino | Foxmail KerioMail | JavaMail | Winwebmail |James Merak&VisNetic | CMailServer | WinMail 金笛邮件系统 | 其它 | 反垃圾邮件: 综述| 客户端反垃圾邮件|服务器端反垃圾邮件 邮件客户端软件: Outlook | Foxmail | DreamMail| KooMail The bat | 雷鸟 | Eudora |Becky! |Pegasus IncrediMail |其它 电子邮箱: 个人邮箱 | 企业邮箱 |Gmail 移动电子邮件:服务器 | 客户端 | 技术前沿 邮件网络安全: 软件漏洞 | 安全知识 | 病毒公告 |防火墙 攻防技术 | 病毒查杀| ISA | 数字签名 邮件营销: Email营销 | 网络营销 | 营销技巧 |营销案例 邮件人才:招聘 | 职场 | 培训 | 指南 | 职场 解决方案: 邮件系统|反垃圾邮件 |安全 |移动电邮 |招标 产品评测: 邮件系统 |反垃圾邮件 |邮箱 |安全 |客户端 |