
У меня есть этот фильтр 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/
(Я изменил тег, чтобы иметь возможность фильтровать с помощью AddHeader из clamav-filter)
ПРАВКА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"
Возможно, также было бы полезно удалить последний токен «FOUND» MATCH
перед записью его в заголовок.
: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 показывает, что вируса нет, добавьте заголовок «Вирус свободен».
Я убрал /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/