我有这个 procmail 过滤器,它似乎可以工作,但我并不为此感到自豪。我相信我们可以使用嵌套部分进行更多优化和清理,但我无法实现任何功能结果。
:0
* !^X-ClamAV
VIRUS=|/usr/bin/clamdscan --no-summary --stdout -
:0fw
* !^X-ClamAV
* VIRUS ?? .*: \/.* FOUND
| formail -a "X-ClamAV: Yes, $MATCH"
:0Efw
* !^X-ClamAV
| formail -a "X-ClamAV: Virus Free"
:0
* ^X-ClamAV: Yes
$MAILDIR/.virus/
您可能已经理解,我尝试使用X-ClamAV: Yes, $MATCH
或X-ClamAV: Virus Free
根据 clamdscan 结果标记电子邮件标头,并将其放入 $MAILDIR /.virus/ 如果是肯定的。就这样。
编辑:
可能这样更好:
:0
* !^X-Virus-Status
VIRUS=|/usr/bin/clamdscan --no-summary --stdout -
:0
* !^X-Virus-Status
* VIRUS ?? .*: \/.* FOUND
{
:0fhw
| formail -a "X-Virus-Status: Infected, $MATCH"
}
:0Efw
| formail -a "X-Virus-Status: Virus Free"
:0
* ^X-Virus-Status: Infected
$MAILDIR/.virus/
(我更改了标签以便能够使用 clamav-filter 中的 AddHeader 进行过滤)
编辑2:
但我犯了一个错误,没有解释清楚,或者根本没有解释,事实上,电子邮件可以在 procmail (clamav-milter) 之前标记,因此已经包含X-Virus-Status: Infected
. 在这种情况下,重复扫描是没有意义的,但您必须将电子邮件放入.virus
. 这就是为什么我需要放
:0
* ^X-Virus-Status: Infected
$MAILDIR/.virus/
脱离大括号
但我的解决方案似乎不太好(procmail: Skipped "--no-summary --stdout -"
):
:0
* !^X-Virus-Status
{
VIRUS=|/usr/bin/clamdscan --no-summary --stdout -
:0
* VIRUS ?? .*: \/.* FOUND
{
VIRUSNAME=`echo "$MATCH" | sed 's/ FOUND$//'`
:0fhw
| formail -a "X-Virus-Status: Infected ($VIRUSNAME)"
}
:0Efw
| formail -a "X-Virus-Status: Virus Free"
}
:0
* ^X-Virus-Status: Infected
$MAILDIR/.virus/
我不想覆盖X-Virus-Status
.
.virus
如果未标记 -> 扫描 -> 标记(是否感染) ->如果感染则放入.virus
如果已经标记 ->如果被感染则放入
换句话说(也许更清楚):
1) tagged X-Virus-Status?
yes: go 2)
no: scan -> infected?
yes: tag infected
no: tag non infected
2) tagged X-Virus-Status: Infected?
yes: put in .virus
no: go 3)
3) continue procmail filters
编辑3:
我在 EDIT2 中尝试的解决方案与@tripleee 提出的相同,效果很好。问题在于未读取参数的过滤器。
我更换了
VIRUS=|/usr/bin/clamdscan --no-summary --stdout -
经过
VIRUS=`/usr/bin/clamdscan --no-summary --stdout -`
现在好像没问题了。
作为一个快速的风格说明,这里不需要大括号。
这些
fhw
标志适用于操作,并且仅在条件匹配时才会执行。另一方面,当这些条件成立时,我可能会在您想要采取的所有操作周围使用一组大括号。
作为修复语法错误的替代方法,请尝试在 VIRUS 赋值周围使用反引号。也可以使用
=|
赋值语法,但如果第一个语法不适合您,请尝试另一个。我在这里工作得很好。MATCH
也许在将最后一个“FOUND”标记写入标头之前将其删除也很有用。(我正在努力想出一个不需要外部过程来修剪字符串末端的解决方案。也许类似的事情可以通过巧妙地使用评分来完成,但对于这个简单的方法来说,这可能有点过分了。)
最后,我不确定您是否要覆盖
X-Virus-Status
即使它已经存在。:0E
当其中一个或两个条件都不成立时,您的情况就会发生。也许你的意思是这个;换句话说,仅当
X-Virus-Status:
标头中尚未存在时才执行这些操作;如果 Clamscan 的结果表明没有病毒,请添加标题“Virus Free”。我拿出了
/usr/bin
;可能比硬编码所有路径更好地确保你的PATH
理智,但当然,最终取决于你。根据您更新的问题,我想您想要的逻辑是