
Eu tenho esse filtro procmail que parece funcionar, mas do qual não estou orgulhoso. Estou convencido de que podemos fazer muito mais otimização e limpeza com seções aninhadas, mas não consigo obter nenhum resultado funcional.
: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/
Você deve ter entendido, tento marcar os cabeçalhos de e-mail com X-ClamAV: Yes, $MATCH
ou X-ClamAV: Virus Free
dependendo do resultado do clamdscan e coloco-o em $MAILDIR /.virus/ se positivo. Isso é tudo.
EDITAR:
Pode ser que seja melhor:
: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/
(Mudei a tag para poder filtrar com AddHeader do clamav-filter)
EDITAR2:
Mas cometi o erro de não explicar bem, ou não explicar de jeito nenhum que na verdade o email pode estar marcado antes do procmail (clamav-milter) e portanto já conter X-Virus-Status: Infected
. Neste caso não adianta repetir a digitalização, mas você deve colocar o e-mail no formato .virus
. É por isso que preciso colocar
:0
* ^X-Virus-Status: Infected
$MAILDIR/.virus/
sem aparelho
Mas minha solução não parece boa ( 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/
Não quero sobrescrever o X-Virus-Status
.
- Se não estiver marcado -> verificar -> marcar (infectado ou não) -> colocar
.virus
se estiver infectado - Se já estiver marcado -> colocar
.virus
se estiver infectado
Em outras palavras (talvez mais claro):
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
EDITAR3:
A solução que tentei no EDIT2, a mesma proposta pelo @tripleee, foi boa. O problema era sobre o filtro cujos argumentos não foram lidos.
eu substituí
VIRUS=|/usr/bin/clamdscan --no-summary --stdout -
por
VIRUS=`/usr/bin/clamdscan --no-summary --stdout -`
e parece estar tudo bem agora.
Responder1
Como uma observação estilística rápida, os colchetes são desnecessários aqui.
:0fhw
* !^X-Virus-Status
* VIRUS ?? .*: \/.* FOUND
| formail -a "X-Virus-Status: Infected, $MATCH"
Os fhw
sinalizadores se aplicam à ação e só são executados se as condições corresponderem.
Por outro lado, eu provavelmente usaria um conjunto de chaves em torno de todas as ações que você deseja realizar quando essas condições forem verdadeiras.
Como alternativa para corrigir os erros de sintaxe, tente crases em torno da atribuição de VIRUS. Também é possível usar a =|
sintaxe de atribuição, mas se a primeira não funcionar para você, tente a outra. Funciona bem para mim aqui.
: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"
Talvez também fosse útil eliminar o último token "FOUND" MATCH
antes de gravá-lo no cabeçalho.
:0
* !^X-Virus-Status
* VIRUS ?? .*: \/.* FOUND
{
VIRUSNAME=`echo "$MATCH" | sed 's/ FOUND$//'`
:0fhw
| formail -a "X-Virus-Status: Infected, $VIRUSNAME"
(Eu estava lutando para encontrar uma solução que não exigisse um processo externo para cortar a ponta da corda. Talvez algo assim pudesse ser conseguido com o uso inteligente da pontuação, mas provavelmente é um exagero para esta receita simples.)
Por fim, não tenho certeza se você deseja substituir o X-Virus-Status
mesmo que já estivesse lá. Isso :0E
acontecerá quando uma ou ambas as condições forem falsas. Talvez você quisesse dizer isso;
: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"
}
Em outras palavras, execute essas ações aqui apenas se X-Virus-Status:
ainda não estiver presente nos cabeçalhos; se o resultado do Clamscan indicar que não houve vírus, adicione o cabeçalho "Virus Free".
Eu tirei o /usr/bin
; provavelmente é melhor ter certeza de que você PATH
está sensato do que codificar todos os caminhos, mas é claro, em última análise, depende de você.
Com sua pergunta atualizada, acho que a lógica que você deseja é
: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/