
私には、機能しているように見える 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
条件のどちらかまたは両方が false の場合に発生します。代わりにこれを意味しているのかもしれません。
: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 の結果でウイルスが存在しないことが示された場合は、「ウイルスなし」というヘッダーを追加します。
私は ; を削除しました。すべてのパスをハードコードするよりも、正しい/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/