É possível limpar um pouco essa filtragem do procmail

É possível limpar um pouco essa filtragem do procmail

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, $MATCHou X-ClamAV: Virus Freedependendo 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 .virusse estiver infectado
  • Se já estiver marcado -> colocar .virusse 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 fhwsinalizadores 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" MATCHantes 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-Statusmesmo que já estivesse lá. Isso :0Eacontecerá 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ê PATHestá 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/

informação relacionada