
我有這個 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
您可能已經明白,我嘗試使用或根據 clamdscan 結果標記電子郵件標頭X-ClamAV: Virus Free
,並將其放入 $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 -`
現在好像沒問題了。
答案1
作為一個快速的風格說明,這裡不需要大括號。
:0fhw
* !^X-Virus-Status
* VIRUS ?? .*: \/.* FOUND
| formail -a "X-Virus-Status: Infected, $MATCH"
這些fhw
標誌適用於操作,並且僅在條件匹配時才會執行。
另一方面,當這些條件成立時,我可能會使用一組大括號來包圍您想要採取的所有操作。
作為修復語法錯誤的替代方法,請嘗試在 VIRUS 賦值周圍使用反引號。也可以使用=|
賦值語法,但如果第一個語法不適合您,請嘗試另一個。在這裡對我來說效果很好。
:0
* !^X-Virus-Status
{ VIRUS=`clamdscan --no-summary --stdout -` }
:0
* !^X-Virus-Status
* VIRUS ?? .*: \/.* FOUND
{
:0fhw
| formail -a "X-Virus-Status: Infected, $MATCH"
:0
$MAILDIR/.virus/
}
:0Efw
| formail -a "X-Virus-Status: Virus Free"
MATCH
也許在將最後一個“FOUND”標記寫入標頭之前將其刪除也很有用。
:0
* !^X-Virus-Status
* VIRUS ?? .*: \/.* FOUND
{
VIRUSNAME=`echo "$MATCH" | sed 's/ FOUND$//'`
:0fhw
| formail -a "X-Virus-Status: Infected, $VIRUSNAME"
(我正在努力想出一個不需要外部過程來修剪字串末端的解決方案。也許類似的事情可以透過巧妙地使用評分來完成,但對於這個簡單的方法來說,這可能有點過分了。)
最後,我不確定您是否要覆蓋X-Virus-Status
即使它已經存在。:0E
當其中一個或兩個條件都不成立時,您的情況就會發生。也許你的意思是這個;
:0
* !^X-Virus-Status
{
VIRUS=`clamdscan --no-summary --stdout -`
:0
* VIRUS ?? .*: \/.* FOUND
{
VIRUSNAME=`echo "$MATCH" | sed 's/ FOUND$//'`
:0fhw
| formail -a "X-Virus-Status: Infected, $VIRUSNAME"
:0
$MAILDIR/.virus/
}
:0Efw
| formail -a "X-Virus-Status: Virus Free"
}
換句話說,僅當X-Virus-Status:
標頭中尚未存在時才執行這些操作;如果 Clamscan 的結果顯示沒有病毒,請新增標題「Virus Free」。
我拿出了/usr/bin
;可能比硬編碼所有路徑更好地確保你的PATH
理智,但當然,最終取決於你。
根據您更新的問題,我想您想要的邏輯是
:0
* !^X-Virus-Status
{
VIRUS=`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/