procmailex - ejemplos de ficheros de recursos
Ejemplos de $HOME/.procmailrc
Para un descripción del formato del fichero de recursos véase
procmailrc(5).
La técnica de puntuación de peso se describe en detalle en la
página de manual de
procmailsc(5).
Esta página de manual muestra varios ejemplos de recetas. Por ejemplo
ficheros de recursos completos que puede comprobar en la sección NOTAS en
procmail(1), o mirar a la parte de ejemplos de ficheros de recursos de
la distribución fuente de procmail (procmail*/examples/?procmailrc).
Ordena todo el correo procedente de la lista de correo scuba-dive en la carpeta
de correo ficheroscuba (usa el fichero de bloqueo local scubafile.lock).
:0:
* ^TOscuba
ficheroscuba
Reenvía todo el correo de pedro sobre compiladores a guillermo (y mantiene
una copia aquí en petcompil).
:0
* ^From.*pedro
* ^Subject:.*compiladores
{
:0 c
! guillermo@algunsitio.edu
:0
petcompil
}
Una solución equivalente que realiza lo mismo:
:0 c
* ^From.*pedro
* ^Subject:.*compiladores
! guillermo@algunsitio.edu
:0 A
petcompil
Una solución equivalente, pero ligeramente más lenta que realiza lo
mismo:
:0 c
* ^From.*pedro
* ^Subject:.*compiladores
!guillermo@somewhere.edu
:0
* ^From.*pedro
* ^Subject:.*compiladores
petcompil
Si vd. es completamente nuevo en procmail y quiere experimentar un poquito, con
frecuencia ayuda tener una
red segura de algún tipo. Inserte las
dos siguientes recetas sobre todas las otras recetas para estar seguro de que
todo el correo que llega siempre conserva los últimos 32 mensajes. Para
que funcione como se prentende, tiene que crear un directorio llamado `backup'
en $MAILDIR antes de insertar estas dos recetas.
:0 c
backup
:0 ic
| cd backup && rm -f dummy `ls -t msg.* | sed -e 1,32d`
Si su sistema no genera o genera líneas `From' iniciales incorrectas en
cada mensaje, puede corregir esto llamando a procmail con la opción -f- .
Para corregir el mismo problema por medios distintos, podría haber
insertado las dos siguientes recetas sobre todas las otras del fichero de
recursos. Estas filtrarán la cabecera de cualquier mensaje mediante
formail que elimina cualquier `From' inicial y lo regenera
automáticamente a continuación.
:0 fhw
| formail -I "From " -a "From "
Añade las cabeceras de todos los mensajes que no vienen del postmaster a su
colección de cabeceras privadas (para uso estadístico o
depuración de correo); y usa el fichero de bloqueo `headc.lock'. Para
estar seguro de que el fichero de bloqueo no se elimina hasta que la
tubería ha finalizado, tendrá que especificar la opción `w'; en
otro caso el fichero de bloqueo sería eliminado tan pronto como la
tubería ha aceptado el correo.
:0 hwc:
* !^FROM_MAILER
| uncompress headc.Z; cat >>headc; compress headc
O, si usara gzip, más eficiente que compress:
:0 hwc:
* !^FROM_MAILER
| gzip >>headc.gz
Reenvía todos los mensajes de menos de 1000 bytes a mi dirección
personal (no se necesita fichero de bloqueo en esta receta).
:0
* < 1000
! myname@home
Divide las recopilaciones de la lista de correo surfing en mensajes individuales
y los almacena en surfing, usando como fichero de bloqueo local surfing.lock.
:0:
* ^Subject:.*surfing.*Digest
| formail +1 -ds >>surfing
Almacena todo lo que llega del postmaster o mailer-daemon (como correo rebotado)
en el fichero postm, usando como fichero de bloqueo local postm.lock.
:0:
* ^FROM_MAILER
postm
Una simple receta de respuesta automática. Se toma la seguridad que ni el
correo de cualquier demonio (como correo rebotado o correo de una lista), ni
las respuestas automáticas procedentes de usted mismo serán
respondidas automáticamente. Si no se toma esta precaución,
podrían suceder desastres (correo en anillo). Para que esta receta
responda a todo el correo entrante, desde luego, debería insertarla antes
que cualquier otra receta en su fichero de recursos. Sin embargo es
aconsejable ponerla
tras cualquier receta que procese los correos de
una lista de correo a la que estemos suscritos; generalmente no es buena idea
generar autorespuestas a las lista de correo(sí, la expresión
regular !^FROM_DAEMON debería coger esos, pero si la lista de correo no
sigue las convenciones aceptadas, esto podría
no ser
suficiente).
:0 h c
* !^FROM_DAEMON
* !^X-Loop: your@own.mail.address
| (formail -r -I"Precedence: junk" \
-A"X-Loop: su_propia@dirección.de.correo" ; \
echo "Mail recibido.") | $SENDMAIL -t
Una receta de autorespuesta más complicada que lleva a cabo funciones
equivalentes al bien conocido programa
vacation(1) Esta receta
está basada en los mismos principios que la última (previniendo el
correo en `anillo'). Además de eso, sin embargo, mantiene una base de
datos vacation extrayendo el nombre del remitente e insertandolo en el fichero
vacation.cache si el nombre es nuevo (el fichero vacation.cache lo mantiene
formail que estará seguro que siempre contiene los nombres más
recientes, el tamaño del fichero está limitado a un máximo de
aproximadamente 8192 bytes). Si el nombre es nuevo, se envía una
respuesta automática.
Como puede ver, la siguiente receta tiene comentarios
entre las
condiciones. Esto está permitido. Sin embargo
no ponga comentarios
en la misma línea que una condición.
SHELL=/bin/sh # para otras shells, esto podría necesitar ajustes
:0 Whc: vacation.lock
# Realiza un chequeo rápido para ver si el correo va dirigido a nosotros
* $^To:.*\<$\LOGNAME\>
# No responde a demonios ni a listas de correo
* !^FROM_DAEMON
# Los bucles de correo son un desastre
* !^X-Loop: your@own.mail.address
| formail -rD 8192 vacation.cache
:0 ehc # si el nombre no está en el caché
| (formail -rI"Precedence: junk" \
-A"X-Loop: your@own.mail.address" ; \
echo "He recibido tu correo,"; \
echo "pero no regresaré hasta el lunes."; \
echo "-- "; cat $HOME/.signature \
) | $SENDMAIL -oi -t
Almacena todos los mensajes referentes a TeX en un fichero único separado,
en un directorio llamado texmail (este directorio tiene que existir); no hay
necesidad de usar ficheros locales de bloqueo en este caso, por tanto no lo
haremos.
:0
* (^TO|^Subject:.*)TeX[^t]
texmail
Lo mismo que arriba, salvo que ahora almacenamos los mensajes en ficheros
numerados (carpeta de correo MH).
:0
* (^TO|^Subject:.*)TeX[^t]
texmail/.
O podría archivar el correo en varios carpetas directorios a la misma vez.
La siguiente receta entregará el correo a carpetas MH y una carpeta
directorio. Actualmente es sólo un fichero con dos enlaces duros extras.
:0
* (^TO|^Subject:.*)TeX[^t]
texmail/. wordprocessing dtp/.
Almacena todos los mensajes sobre encuentros en una carpeta que está en un
directorio que cambia cada mes. V. g. si fuera Enero de 1994, la carpeta
tendría el nombre `94-01/encuentros' y le fichero de bloqueo local
sería `94-01/encuentros.lock'.
:0:
* meeting
`date +%y-%m`/encuentros
Lo mismo que arriba, pero si el directorio `94-01' no existiera, se crearía
automáticamente
CARPETAMESUAL=`date +%y-%m`
:0 Wic
* ? test ! -d $CARPETAMESUAL
| mkdir $CARPETAMESUAL
:0:
* encuentro
${CARPETAMESUAL}/encuentro
Lo mismo que arriba, pero con medios ligeramente diferentes:
CARPETAMESUAL=`date +%y-%m`
DUMMY=`test -d $CARPETAMESUAL || mkdir $CARPETAMESUAL`
:0:
* encuentros
${CARPETAMESUAL}/meeting
Si está suscrito a varias listas de correo y la gente envía mesajes
cruzados a varias de ellas, normalmente recibe varios correos duplicados (uno
de cada lista). La siguiente receta simple elimina mensajes duplicados. Le
dice a formail que mantenga un fichero cache de 8Kb en el cual se almacenan
los identificadores de mensaje de los correos más reciente que ha
recibido. Como se garantiza que los identificadores de mensaje son únicos
para cada mensaje, son ideales para descartar los mensajes duplicados.
Simplemente ponga la siguiente receta al comienzo de su fichero de recursos y
ningún mensaje duplicado logratá pasarla.
:0 Wh: msgid.lock
| formail -D 8192 msgid.cache
Tenga cuidado si tiene problemas de entrega en las recetas debajo de esto
y procmail intenta reencolar el correo, entonces en la próxima
ejecución de la cola, este mensaje se considerará duplicado y
seráeliminado. Para quienes quieren seguridad pueden usar la siguiente
receta en su lugar. Esta pone los duplicados en una carpeta separada en lugar
de eliminarlos. Esto le obliga a vaciar periódicamente la carpeta, por
supuesto.
:0 Whc: msgid.lock
| formail -D 8192 msgid.cache
:0 a:
duplicates
Procmail puede entregar a carpetas MH directamente, pero no actualiza las
secuencias no vistas que el MH real gestiona. Si quiere que procmail actualice
estas también , use una receta como la siguiente que almacena todo lo que
tenga la palabra spam en el cuerpo del mensaje en una carpeta MH llamada
spamfold. Observe que el fichero de bloqueo local, que es necesario porque los
progamas MH no bloquean el ficher de secuencias. Las llamadas asíncronas
de los progamas MH que cambian el fichero de secuencias pueden corromper el
fichero o simplemente perder los cambios. Por desgracia, el fichero de bloqueo
no resuelve el problema completamente ya que rcvstore se podría llamar
mientras `show' o `mark' u otro programa MH está en ejecución. El
problema se epera corregir en alguna versión futura de MH, pero hasta
entonces tendrá que valorar el riesgo de perder o corromper las
secuencias contra lo beneficios de las secuencias no vistas.
:0 :spamfold/$LOCKEXT
* B ?? spam
| rcvstore +spamfold
Cuando entregue a carpetas emacs (i.e. carpetas de correo gestionadas por
cualquier paquete de correo de emacs, v.g. RMAIL o VM) directamente,
debería usar ficheros de bloqueo compatibles con emacs. Los programas de
correo de emacs son un poco descerebrados en ese respecto, se molestan mucho
si alguien entrega a carpetas de correo que ellos ya tienen en sus bufferes
internos. La siguiente receta supone que $HOME es igual a /home/john.
MAILDIR=Mail
:0:/usr/local/lib/emacs/lock/!home!john!Mail!mailbox
* ^Subject:.*loquesea
mailbox
De forma alternativa, puede hacer que procmail entrega en su propio conjunto de
carpetas, las cuales se pueden vaciar periódicamente yu copiarlas sobre
sus porpios ficheros emacs usando
movemail. Movemail usa ficheros de
bloqueo locales buzón.lock por buzón. Actualmente este es el modo de
operación preferido en conjunción con procmail.
Para extraer ciertas cabeceras de un correo y pponerlas en variables de entorno
puede usar cualquiera de las siguientes construcciones:
SUBJECT=`formail -xSubject:` # campo regular
FROM=`formail -rt -xTo:` # caso especial
:0 h # método alternativo
KEYWORDS=| formail -xKeywords:
Si usa ficheros temporales en un fichero procmailrc, y quieres estar seguro de
que se eliminan antes de que procmail termine, podría usar algo como las
líneas de:
TEMPORARY=$HOME/tmp/pmail.$$
TRAP="/bin/rm -f $TEMPORARY"
TRAP se puede usar para modificar el código de salida de procmail. I.e. si
quiere que procmail devuelva un código de salida de `1' en lugar de sus
códigos de salida regulares, podría usar:
EXITCODE=""
TRAP="exit 1;" # El punto y coma final es importante.
# ya que exit no es un programa standalone
O, si el código de salida no necesita depender de la ejecución de
programas de TRAP, puede usar un simple:
EXITCODE=1
La siguiente receta imprime cada correo de entrada que se parezca a un fichero
postscript.
:0 Bb
* ^^%!
| lpr
La siguiente receta hace lo mismo, pero un poco más selectiva. Sólo
imprime el fichero postscript si viene del servidor de impresión. La
primera condición concuerda sólo si se encuentra en la cabecera. La
segunda condición sólo concuerda al comienzo del cuerpo.
:0 b
* ^From[ :].*print-server
* B ?? ^^%!
| lpr
Lo mismo que arriba, pero por unos medios ligeramente diferentes:
:0
* ^From[ :].*print-server
{
:0 B b
* ^^%!
| lpr
}
Igualmente:
:0 HB b
* ^^(.+$)*From[ :].*print-server
* ^^(.+$)*^%!
| lpr
Supongamos que tiene dos cuentas y usa esas dos cuentas regularmente, pero
están en lugares distintos (i.e. sólo podría leer el correo que
llega a una de las cuentas). Le gustaría reenviar el correo que llega a
la cuenta uno a la cuenta dos y al contrario. Lo primero que se viene a la
mente es usar ficheros .forward en ambos sitios; esto no funcionará,
desde luego, ya que estará creando un bucle de correo. Este bucle se
puede evitar insertando la siguiente receta frente a todas las otras recetas
en los ficheros$HOME/.procmailrc de ambos sitios. Si está seguro que
añade el mismo campo X-Loop: en ambos sitios, el correo se puede reenviar
de una cuenta a otra con garantías.
:0 c
* !^X-Loop: yourname@your.main.mail.address
| formail -A "X-Loop: yourname@your.main.mail.address" | \
$SENDMAIL -oi yourname@the.other.account
Si alguien le envía un correo con la palabra `retrieve' en el campo
`subject', lo siguiente devolverá automáticamente el contenido del
fichero info_file al remitente. Como en todas las recetas donde enviamos
correo, tenemos que vigilar los bucles de correo.
:0
* !^From +YOUR_USERNAME
* !^Subject:.*Re:
* !^FROM_DAEMON
* ^Subject:.*retrieve
| (formail -r ; cat info_file) | $SENDMAIL -oi -t
A continuación un ejemplo para un simple servidor de ficheros accesible por
correo. Para aplicaciones con mayores exigencias, le sugiero que le eche un
vistazo a
SmartList (disponible en el mismo lugar que la
distribución de procmail). Como se indica, este servidor de ficheros
devuelve sólamente un fichero por petición, ignora el cuerpo del
mensaje recibido, la línea Subject: tiene que parecerse a "Subject:
envia fichero el_fichero_que_quiere" (los espacios en blanco son
significativos), no devuelve ficheros que empiezan por punto ni permite
recuperar ficheros que estén fuera del árbol de directorios del
servidor de ficheros (si decide usar este ejemplo, esté seguro de perder
esta última restricción por descuido).
:0
* ^Subject: send file [0-9a-z]
* !^X-Loop: yourname@your.main.mail.address
* !^Subject:.*Re:
* !^FROM_DAEMON
* !^Subject: send file .*[/.]\.
{
MAILDIR=$HOME/fileserver # cambiar al directorio del servidor de ficheros
:0 fhw # invierte las cabeceras y extrae el nombre
* ^Subject: send file \/[^ ]*
| formail -rA "X-Loop: yourname@your.main.mail.address"
FILE="$MATCH" # el fichero soliciatado
:0 ah
| cat - ./$FILE 2>&1 | $SENDMAIL -oi -t
}
El siguiente ejemplo pre-convierte todos los correos que llegan en texto simple
en cierto formato codificado MIME en otro formato de 8 bits más compacto
que se puede usar y mostrar con más facilidad por la mayoría de los
programas. El programa
mimencode(1) es parte del paquete metamail de
Nathaniel Borenstein.
:0
* ^Content-Type: *text/plain
{
:0 fbw
* ^Content-Transfer-Encoding: *quoted-printable
| mimencode -u -q
:0 Afhw
| formail -I "Content-Transfer-Encoding: 8bit"
:0 fbw
* ^Content-Transfer-Encoding: *base64
| mimencode -u -b
:0 Afhw
| formail -I "Content-Transfer-Encoding: 8bit"
}
El siguiente es más bien exótico, pero sólo sirve para demostrar
una característica. Suponga que tiene un fichero en su directorio HOME
llamado ".urgent", y la única persona incluida en ese fichero
es el remitente de un correo entrante, y le gustaría que el correo se
almacenara en $MAILDIR/urgent en lugar de cualesquiera de las otras carpetas
de correo normales en las que lo habría puesto. Esto es lo que
podría hacer (tenga cuidado con la longitud del fichero de $HOME/.urgent
que debería estar por debajo de $LINEBUF, incremente LINEBUF si es
necesario):
URGMATCH=`cat $HOME/.urgent`
:0:
* $^From.*${URGMATCH}
urgent
Una aplicación completamente diferente a procmail aplicaría
condicionalmente filtros a ciertos textos o mensajes (salientes). Un ejemplo
típico sería un filtreo a través del cual encauza todo su
correo saliente, para estar seguro que se codificará con MIME sólo
si se necesita.
cat newtext | procmail ./mimeconvert | mail chris@where.ever
El fichero de recursos
mimeconvert podría contener algo como (
=0x80= y =0xff= se deberían sustituir por caracteres reales de 8 bits):
DEFAULT=| # tubería a la salida estándar
# de entrega de correo como es normal
:0 Bfbw
* [=0x80=-=0xff=]
| mimencode -q
:0 Afhw
| formail -I 'MIME-Version: 1.0' \
-I 'Content-Type: text/plain; charset=ISO-8859-1' \
-I 'Content-Transfer-Encoding: quoted-printable'
procmail(1),
procmailrc(5),
procmailsc(5),
sh(1),
csh(1),
mail(1),
mailx(1),
binmail(1),
uucp(1),
aliases(5),
sendmail(8),
egrep(1),
grep(1),
biff(1),
comsat(8),
mimencode(1),
lockfile(1),
formail(1)
Stephen R. van den Berg
<srb@cuci.nl>