¿Es posible limpiar un poco este filtrado de procmail?

¿Es posible limpiar un poco este filtrado de procmail?

Tengo este filtro de procmail que parece funcionar, pero del que realmente no estoy orgulloso. Estoy convencido de que podemos optimizar y limpiar mucho más con secciones anidadas, pero no puedo lograr ningún 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/

Quizás lo hayas entendido, trato de etiquetar los encabezados de correo electrónico con X-ClamAV: Yes, $MATCHo X-ClamAV: Virus Freedependiendo del resultado de clamdscan y colocarlo en $MAILDIR /.virus/ si es positivo. Eso es todo.

EDITAR:

Quizás esto sea mejor:

: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/

(Cambié la etiqueta para poder filtrar con AddHeader de clamav-filter)

EDITAR2:

Pero cometí el error de no explicar bien, o no explicar nada, que en realidad el correo electrónico se puede etiquetar antes de procmail (clamav-milter) y por lo tanto ya contiene X-Virus-Status: Infected. En este caso no tiene sentido repetir el escaneo, sino que debes colocar el correo electrónico en formato .virus. Por eso necesito poner

:0
* ^X-Virus-Status: Infected
$MAILDIR/.virus/

sin frenillos

Pero mi solución no parece buena ( 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/

No quiero sobrescribir el X-Virus-Status.

  • Si no está etiquetado -> escanear -> etiquetar (infectado o no) -> colocar .virussi está infectado
  • Si ya está etiquetado -> colocarlo .virussi está infectado

En otras palabras (quizás más 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:

La solución que probé en EDIT2, la misma propuesta por @tripleee, fue buena. El problema estaba en el filtro cuyos argumentos no se leyeron.

reemplacé

VIRUS=|/usr/bin/clamdscan --no-summary --stdout -

por

VIRUS=`/usr/bin/clamdscan --no-summary --stdout -`

y parece estar bien ahora.

Respuesta1

Como nota estilística rápida, los tirantes son innecesarios aquí.

:0fhw
* !^X-Virus-Status
* VIRUS ?? .*: \/.* FOUND
| formail -a "X-Virus-Status: Infected, $MATCH"

Las fhwbanderas se aplican a la acción y sólo se realiza si las condiciones coinciden.

Por otro lado, probablemente usaría un conjunto de llaves alrededor de todas las acciones que desee realizar cuando estas condiciones sean verdaderas.

Como alternativa para corregir los errores de sintaxis, pruebe con comillas invertidas alrededor de la asignación VIRUS. =|También es posible utilizar la sintaxis de asignación, pero si la primera no te funciona, prueba la otra. Aquí me funciona bien.

: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"

Quizás también sería útil eliminar el último token "ENCONTRADO" MATCHantes de escribirlo en el encabezado.

:0
* !^X-Virus-Status
* VIRUS ?? .*: \/.* FOUND
{
    VIRUSNAME=`echo "$MATCH" | sed 's/ FOUND$//'`
    :0fhw
    | formail -a "X-Virus-Status: Infected, $VIRUSNAME"

(Estaba luchando por encontrar una solución que no requiriera un proceso externo para recortar el extremo de la cuerda. Tal vez algo así podría lograrse con un uso inteligente de la puntuación, pero probablemente sea excesivo para esta receta simple).

Finalmente, no estoy seguro de si desea sobrescribir el archivo X-Virus-Statusincluso si ya estaba allí. Sucederá :0Ecuando una o ambas condiciones sean falsas. Quizás quisiste decir esto;

: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"
}

En otras palabras, sólo realice estas acciones aquí si X-Virus-Status:aún no estaban presentes en los encabezados; Si el resultado de Clamscan indica que no había virus, agregue el encabezado "Libre de virus".

Saqué el /usr/bin; Probablemente sea mejor asegurarse de que PATHestá cuerdo que codificar todas las rutas, pero, por supuesto, en última instancia, depende de usted.

Con tu pregunta actualizada, supongo que la lógica que quieres es

: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/

información relacionada