
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, $MATCH
o X-ClamAV: Virus Free
dependiendo 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
.virus
si está infectado - Si ya está etiquetado -> colocarlo
.virus
si 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 fhw
banderas 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" MATCH
antes 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-Status
incluso si ya estaba allí. Sucederá :0E
cuando 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 PATH
está 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/