procmailex - przykłady plików rc procmaila
przykłady $HOME/.procmailrc
Opisu formatu pliku rc znajduje się w
procmailrc(5).
Technika punktów ważonych jest opisana szczegółowo na
stronie
procmailsc(5).
Ta strona podręcznika pokazuje kilka przykładowych reguł.
Przykłady kompletnych plików rc znajdują się w sekcji
UWAGI podręcznika
procmail(1); można też
zajrzeć do przykładowych plików rc w katalogu
/usr/share/doc/procmail/examples.
Sortuje pocztę przychodzącą z listy dyskusyjnej scuba-dive do
folderu pocztowego scubafile (używa lokalnego pliku blokującego
scubafile.lock).
:0:
* ^TOscuba
scubafile
Forwarduje pocztę o kompilatorach od petera do williama (i zachowuje
kopię lokalnie w pliku petcompil).
:0
* ^From.*peter
* ^Subject:.*compilers
{
:0 c
! william@somewhere.edu
:0
petcompil
}
Równoważne rozwiązanie, które robi to samo:
:0 c
* ^From.*peter
* ^Subject:.*compilers
! william@somewhere.edu
:0 A
petcompil
Równoważne, lecz trochę wolniejsze rozwiązanie, robiące
to samo:
:0 c
* ^From.*peter
* ^Subject:.*compilers
! william@somewhere.edu
:0
* ^From.*peter
* ^Subject:.*compilers
petcompil
Nowicjusze w temacie procmaila, planujący trochę z nim
poeksperymentować, powinni zapewnić sobie jakiś rodzaj
sieci
bezpieczeństwa. Wstawienie następujących dwóch
reguł przed wszystkimi innymi regułami, zapewni, że ostatnie 32
wiadomości będą chronione. Aby działało to zgodnie z
oczekiwaniami, należy przed dodaniem tych dwóch reguł, w
katalogu
$MAILDIR utworzyć katalog o nazwie "backup".
:0 c
backup
:0 ic
| cd backup && rm -f dummy `ls -t msg.* | sed -e 1,32d`
Jeśli system nie generuje początkowych linii "From " lub
generuje je w nieprawidłowy sposób, to można to naprawić,
wywołując procmail z opcją -f-. Innym sposobem naprawienia tego
problemu jest wstawienie następujących dwóch reguł
powyżej wszystkich innych reguł pliku rc. Będą one
filtrować nagłówek dowolnego listu za pomocą
formail(1), który obetnie wszelkie początkowe "From
" i automatycznie je odtworzy.
:0 fhw
| formail -I "From " -a "From "
Dodaje nagłówki wszystkich wiadomości, które nie
przyszły od postmastera, do prywatnej kolekcji nagłówków
(dla statystyk lub debuggowania poczty); używa pliku blokującego
"headc.lock". Aby zapewnić, że plik blokujący nie
zostanie usunięty przed zakończeniem potoku, trzeba podać
opcję "w"; w przeciwnym wypadku plik blokujący
zostałby usunięty w momencie przyjęcia poczty przez potok.
:0 hwc:
* !^FROM_MAILER
| uncompress headc.Z; cat >>headc; compress headc
Lub aby użyć efektywniejszego gzip-a zamiast compress-a:
:0 hwc:
* !^FROM_MAILER
| gzip >>headc.gz
Forwarduje wszystkie wiadomości krótsze niż 1000 bajtów na
podany adres domowy (w tej regule nie jest potrzebny plik blokujący).
:0
* < 1000
! myname@home
Dzieli pochodzącą z listy dyskusyjnej surfing kolekcję
wiadomości (ang. digest) na pojedyncze wiadomości i zachowuje je w
pliku surfing, używając lokalnego pliku blokującego
surfing.lock.
:0:
* ^Subject:.*surfing.*Digest
| formail +1 -ds >>surfing
Zachowuje w pliku postm wszystkie e-maile pochodzące od postmastera lub
mailer-deamona. Użyje pliku postm.lock jako lokalnego pliku
blokującego.
:0:
* ^FROM_MAILER
postm
Prosta reguła auto-odpowiadająca. Upewnia się, że nie
odpowiada na pocztę od jakiegoś demona (np. odbita poczta lub poczta
z list dyskusyjnych), ani na listy pochodzące od Ciebie samego. Bez tych
zabezpieczeń mogłaby się zdarzyć katastrofa. Aby
reguła odpowiadała na pocztę przychodzącą, powinno
się ją wstawić przed wszystkie inne reguły pliku rc. Radzi
się jednak wstawiać ją
za wszelkimi regułami,
które obsługują pocztę pochodzącą z list
dyskusyjnych; zazwyczaj nie jest dobrym pomysłem generowanie
automatycznych odpowiedzi na pocztę z list dyskusyjnych (tak, regexp
!^FROM_DAEMON powinien je wyłapać, jednak jeśli lista
dyskusyjna nie pracuje zgodnie z przyjętymi konwencjami, to może to
być
niewystarczające).
:0 h c
* !^FROM_DAEMON
* !^X-Loop: twój@własny.adres.pocztowy
| (formail -r -A"Precedence: junk" \
-A"X-Loop: twój@własny.adres.pocztowy" ; \
echo "Poczta odebrana.") | $SENDMAIL -t
Bardziej skomplikowana reguła auto-odpowiadająca, która
implementuje funkcjonalność znanego programu
vacation(1).
Reguła ta jest oparta na tych samych zasadach, co poprzednia
(zapobieganie odbijania maili od demonów). Dodatkowo utrzymuje bazę
danych vacation, wyciągając nazwę nadawcy i wstawiając
ją do pliku
vacation.cache, o ile była to nowa nazwa (plik
vacation.cache jest obsługiwany przez
formail(1),
który będzie się upewniał, że zawiera tylko najnowsze
nazwiska; rozmiar pliku jest ograniczony do 8192 bajtów). Jeśli
nazwisko było nowe, wysłana zostanie automatycznie wygenerowana
odpowiedź.
Jak można zauważyć następująca reguła zawiera
komentarze
pomiędzy warunkami. Jest to dozwolone. Jednakże
nie można wpisywać komentarzy w linii zawierającej
warunek.
SHELL=/bin/sh # dla innych powłok trzeba to poprawić
:0 Whc: vacation.lock
# Szybkie sprawdzenie, czy poczta jest adresowana do nas
* $^To:.*\<$\LOGNAME\>
# Nie odpowiadaj na maile od usług lub z list pocztowych
* !^FROM_DAEMON
# Pętle pocztowe to zło
* !^X-Loop: your@own.mail.address
| formail -rD 8192 vacation.cache
:0 ehc # jeśli nazwiska nie było w cache
| (formail -rA"Precedence: junk" \
-A"X-Loop: twój@własny.adres.pocztowy" ; \
echo "Odebrałem Twój list,"; \
echo "lecz nie wrócę do poniedziałku."; \
echo "-- "; cat $HOME/.signature \
) | $SENDMAIL -oi -t
Zachowuje wszelkie wiadomości dotyczące TeX-a w oddzielnych plikach o
unikatowych nazwach w katalogu o nazwie texmail (katalog musi istnieć);
nie ma potrzeby używać w tym wypadku plików blokujących,
więc ich nie używamy.
:0
* (^TO|^Subject:.*)TeX[^t]
texmail
To samo, co powyżej, lecz teraz zapisuje listy w plikach numerowanych
(folder pocztowy MH).
:0
* (^TO|^Subject:.*)TeX[^t]
texmail/.
Można także zapisać list w kilku folderach naraz.
Następująca reguła dostarczy pocztę do dwóch
folderów MH i jednego folderu katalogowego. Jest to w rzeczywistości
tylko jeden plik z dwoma dodatkowymi dowiązaniami twardymi (hardlinks).
:0
* (^TO|^Subject:.*)TeX[^t]
texmail/. wordprocessing dtp/.
Zachowuje wszystkie listy o spotkaniach (meetings) w folderze znajdującym
się w katalogu, którego nazwa się zmienia co miesiąc. Np.
jeśli był styczeń 1994, folder miałby nazwę
"94-01/meeting", a lokalny plik blokujący nazywałby
się "94-01/meeting.lock".
:0:
* meeting
`date +%y-%m`/meeting
To samo, co wyżej, lecz jeśliby katalog "94-01" nie
istniał, toby został automatycznie utworzony:
MONTHFOLDER=`date +%y-%m`
:0 Wic
* ? test ! -d $MONTHFOLDER
| mkdir $MONTHFOLDER
:0:
* meeting
${MONTHFOLDER}/meeting
To samo, co powyżej, lecz z użyciem innych środków:
MONTHFOLDER=`date +%y-%m`
DUMMY=`test -d $MONTHFOLDER || mkdir $MONTHFOLDER`
:0:
* meeting
${MONTHFOLDER}/meeting
Jeśli jest się zapisanym do kilku list dyskusyjnych, a ludzie
wysyłają te same maile na niektóre z nich, to może
się zdarzyć, że otrzyma się zduplikowane listy (po jednym
z każdej listy). Następująca reguła eliminuje
powtórzone maile. Mówi formailowi, by trzymał 8-kilobajtowy
plik bufora, w którym będzie zapisywał Message-ID ostatnio
odbieranych listów. Ponieważ elementy te muszą być
unikatowe dla każdego nowego listu, to są idealnym rozwiązaniem
na duplikaty. Wystarczy wstawić następującą
regułę na początek pliku rc i gotowe.
:0 Wh: msgid.lock
| formail -D 8192 msgid.cache
Uwaga: jeśli wystąpią problemy z dostarczaniem poczty w
regułach występujących po tej regule i procmail spróbuje
wrzucić mail z powrotem do kolejki, to w czasie następnego
uruchomienia kolejki mail zostanie uznany za duplikat i wyrzucony. Ktoś,
kto nie ma zbyt dużych umiejętności w pisaniu skryptów,
może spróbować użyć następującej
reguły, która zapisze duplikaty w osobnym folderze zamiast
wyrzucać je całkowicie. Folder ten można od czasu do czasu
przeglądać i opróżniać.
:0 Whc: msgid.lock
| formail -D 8192 msgid.cache
:0 a:
duplicates
Procmail może dostarczać pocztę bezpośrednio do
folderów MH, ale nie aktualizuje pliku sekwencji, którym
zarządza prawdziwe MH, zawierającego informacje o nieprzeczytanej
poczcie. Aby procmail aktualizował ten plik także, należy
użyć reguły podobnej do poniższej. Reguła ta zapisze
wszystko, co zawiera w treści maila słowo "spam" do
folderu MH zwanego spamfold. Proszę zwrócić uwagę na
lokalny plik blokujący, który jest potrzebny, ponieważ programy
MH nie blokują pliku sekwencji. Asynchroniczne uruchomienia
programów MH, które zmieniają plik sekwencji, mogą
spowodować jego uszkodzenie. Niestety plik blokady nie rozwiązuje
całkowicie problemu, ponieważ
rcvstore(1) może
zostać uruchomiony w czasie działania poleceń "show"
lub "mark" lub jakiegoś innego programu MH. Problem ma
zostać rozwiązany w przyszłych wersjach MH, zanim to jednak
nastąpi należy się liczyć z ryzykiem uszkodzenia
plików sekwencji.
:0 :spamfold/$LOCKEXT
* B ?? spam
| rcvstore +spamfold
Podczas bezpośredniego dostarczania do folderów emacsa (np.
folderów pocztowych obsługiwanych przez dowolny pocztowy pakiet
emacsowy, np. RMAIL czy VM), powininno się używać
kompatybilnych z emacsem plików blokujących. Mailerom emacsowym
brakuje piątej klepki pod tym względem, denerwują się
bardzo, jeśli ktoś dostarcza pocztę do folderów,
które znajdują się już w ich buforach wewnętrznych.
Następująca reguła zakłada, że $HOME jest równy
/home/john.
MAILDIR=Mail
:0:/usr/local/lib/emacs/lock/!home!john!Mail!mailbox
* ^Subject:.*cokolwiek
mailbox
Inaczej, można kazać procmailowi dostarczać pocztę do swoich
własnych mailboxów, a następnie periodycznie
opróżniać je i kopiować do plików emacsowych przy
użyciu
movemail(1). Movemail używa lokalnych plików
blokujących
mailbox.lock dla danego mailboxa. Jest to preferowany
tryb współpracy emacsowych mailerów z procmailem.
Aby wyciągnąć określone nagłówki z listu i
wstawić je do zmiennych środowiskowych, można użyć
dowolnej z następujących konstrukcji:
SUBJECT=`formail -xSubject:` # pole regularne
FROM=`formail -rt -xTo:` # przypadek specjalny
:0 h # metoda alternatywna
KEYWORDS=| formail -xKeywords:
Jeśli w pliku .procmailrc używane są pliki tymczasowe, to aby
upewnić się, że zostaną one usunięte zaraz przed
zakończeniem pracy procmaila, można użyć linijek podobnych
do tych:
TEMPORARY=$HOME/tmp/pmail.$$
TRAP="/bin/rm -f $TEMPORARY"
Słowo kluczowe
TRAP może być także użyte do
zmiany kodu wyjścia procmaila. Np. aby procmail zakończył
pracę z kodem wyjścia "1" zamiast standardowego kodu,
można użyć:
EXITCODE=""
TRAP="exit 1;" # Kończący średnik jest istotny
# gdyż exit nie jest samodzielnym programem
Albo też, jeśli kod wyjścia nie musi zależeć od
programów uruchamianych z
TRAP, można użyć
zwykłego:
EXITCODE=1
Następująca reguła drukuje każdy nadchodzący list,
który wygląda jak plik postscriptowy.
:0 Bb
* ^^%!
| lpr
Następująca reguła robi to samo, lecz jest trochę bardziej
selektywna. Drukuje tylko te pliki postscriptowe, które pochodzą od
serwera drukarki. Pierwszy warunek dopasowuje tylko, jeśli zostanie
znaleziony w nagłówku. Następny dopasowuje tylko na
początku ciała wiadomości.
:0 b
* ^From[ :].*print-server
* B ?? ^^%!
| lpr
To samo, co powyżej, lecz z użyciem innych środków:
:0
* ^From[ :].*print-server
{
:0 B b
* ^^%!
| lpr
}
Podobnie:
:0 HB b
* ^^(.+$)*From[ :].*print-server
* ^^(.+$)*^%!
| lpr
Załóżmy, że mamy dwa konta i że oba są
używane regularnie, lecz znajdują się w całkowicie
różnych miejscach (tj. można czytać pocztę tylko z
jednego z dwóch kont). Chcielibyśmy przekazywać pocztę
przybywającą na konto pierwsze do konta drugiego i odwrotnie.
Pierwszą rzeczą, która przychodzi na myśl jest użycie
na obydwu komputerach plików
.forward, lecz to nie zadziała,
gdyż utworzy się w ten sposób pętlę pocztową.
Można uniknąć pętli przez wstawienie
następującej reguły na początku wszystkich innych
reguł w plikach
$HOME/.procmailrc obydwu komputerach. Jeśli
dodane zostanie dokładnie to samo pole "X-Loop:" na obydwu
komputerach, to poczta może już być bezpiecznie przekazywana z
jednego z tych kont na drugie.
:0 c
* !^X-Loop: twojlogin@twoj.adres.pocztowy
| formail -A "X-Loop: twojlogin@twoj.adres.pocztowy" | \
$SENDMAIL -oi twojlogin@drugie.konto
Jeśli ktoś prześle pocztę ze słowem
"retrieve" w temacie, to następująca reguła
automatycznie odeśle z powrotem zawartość pliku info_file. Jak
we wszystkich regułach, należy uważać na pętle
pocztowe.
:0
* !^From +TWOJ_USERNAME
* !^Subject:.*Re:
* !^FROM_DAEMON
* ^Subject:.*retrieve
| (formail -r ; cat info_file) | $SENDMAIL -oi -t
A teraz przykład bardzo prostego serwera plików dostępnego przez
pocztę. Dla bardziej wymagających aplikacji, sugeruję
zapoznanie się z programem
SmartList (dostępnym w tym samym
miejscu, co dystrybucja procmaila). Ten serwer plików odsyła
najwyżej jeden plik na żądanie, ignoruje ciało
nadchodzących listów, a linia tematu
Subject: musi
wyglądać jak "Subject: send file plik_którego_chcesz"
(spacje są istotne), nie zwraca plików, które mają nazwy
rozpoczynające się od kropki i nie umożliwia odbioru
plików spoza drzewa katalogów serwera plików (dostosowując
ten przykład do własnych potrzeb, prosimy pamiętać o tym,
by nieumyślnie nie zdjąć ostatniego z wymienionych
ograniczeń).
:0
* ^Subject: send file [0-9a-z]
* !^X-Loop: twojlogin@twoj.adres.pocztowy
* !^Subject:.*Re:
* !^FROM_DAEMON
* !^Subject: send file .*[/.]\.
{
MAILDIR=$HOME/fileserver # zmień katalog do katalogu serwera plików
:0 fhw # odwróć nagłówek listu i wyciągnij nazwę
* ^Subject: send file \/[^ ]*
| formail -rA "X-Loop: twojlogin@twoj.adres.pocztowy"
FILE="$MATCH" # żądany plik
:0 ah
| cat - ./$FILE 2>&1 | $SENDMAIL -oi -t
}
Następujący przykład zamienia wstępnie wszystkie
przychodzące listy w czystym tekście, kodowane w formatach MIME na
ładniejszy format 8-bitowy, który może być używany i
wyświetlany w prostszy sposób przez większość
programów. Program
mimencode(1) jest częścią
pakietu metamail Nathaniela Borensteina.
: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"
}
Następujący przykład jest raczej egzotyczny, lecz służy
tylko ilustracji właściwości. Załóżmy, że
masz w swoim katalogu domowym plik o nazwie ".pilne", a osoba
wymieniona w tym pliku jest nadawcą nadchodzącego listu i
chciałbyś, by ten list był zachowany w skrzynce
"$MAILDIR/pilne" zamiast w dowolnym z normalnych folderów
pocztowych. Można wówczas zrobić tak (uwaga:
długość pliku $HOME/.pilne powinna być mniejsza niż
$LINEBUF, jeśli to konieczne, należy zwiększyć
wartość LINEBUF):
URGMATCH=`cat $HOME/.pilne`
:0 B:
* $^From.*${URGMATCH}
pilne
Całkowicie innym zastosowaniem procmaila byłoby warunkowe
dołączanie filtrów do niektórych (wychodzących)
tekstów lub listów. Typowym przykładem byłoby filtrowanie,
w którym używane byłyby potoki dla wszystkich wychodzących
e-maili, aby ustawić kodowanie MIME tylko wtedy, gdy to konieczne. W
takim przypadku można uruchomić procmaila wewnątrz potoku na
przykład w taki sposób:
cat newtext | procmail ./mimeconvert | mail chris@where.ever
Plik rc
mimeconvert powinien zawierać coś w rodzaju (=0x80= i
=0xff= powinny być zastąpione prawdziwymi znakami 8-bitowymi):
DEFAULT=| # potok na stdout zamiast
# dostarczania pocztę jak zwykle
: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),
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>
Philip A. Guenther
<guenther@sendmail.com>
TŁUMACZENIE¶
Autorami polskiego tłumaczenia niniejszej strony podręcznika man
są: Przemek Borys (PTM) <pborys@dione.ids.pl> i Robert Luberda
<robert@debian.org>.
Polskie tłumaczenie jest częścią projektu manpages-pl;
uwagi, pomoc, zgłaszanie błędów na stronie
http://sourceforge.net/projects/manpages-pl/. Jest zgodne z wersją
3.22 oryginału.