K doručování elektronických poštovních zpráv (emailů) je na poštovních serverech FEKT a FIT používán doručovací program (Mail Delivery Agent - MDA) Procmail. Procmail umožňuje příchozí emaily filtrovat libovolnými programy, ukládat do různých schránek (mailboxů), předávat na jiné adresy apod. Procmail manipuluje s emaily na základě pravidel (recipes) uložených v souboru $HOME/.procmailrc. (Proměnná $HOME určuje uživatelův domovký adresář na příslušném UNIXovém serveru.) Kromě pravidel pro doručování může soubor .procmailrc obsahovat i definici proměnných. Jestliže soubor .procmailrc v uživatelově domovském adresáři není přítomen, Procmail ukládá všechny emaily do souboru /var/mail/login_name, kde login_name je uživatelovo přihlašovací jméno.
Poznámka: Přesměrování pošty pomocí souboru .forward se zásadně nedoporučuje, neboť může způsobit zacyklení doručování pošty.
Soubor .procmailrc lze vytvořit a upravovat přímo na příslušném UNIXovém serveru (v případě studentů server fest.stud.feec.vutbr.cz) nebo prostřednictvím webového rozhraní Horde (http://email.feec.vutbr.cz). V Horde lze přesměrování nastavit v záložce Filtry -> Přeposlat.
Email se skládá z hlaviček (headers) a těla (body). Vlastní text emailu je uložen v těle, jehož formát není rigidně předepsán. Hlavičky jsou skupina speciálních řádků na začátku emailu, které obsahují strojově čitelné informace o emailu. Formát hlaviček je přesně definován. Mnoho hlaviček je určeno pouze pro poštovní programy, některé mají význam i pro uživatele (např. Subject nebo From). Poštovní klienti běžně zobrazují pouze hlavičky určené pro uživatele. Každá hlavička začíná klíčovým slovem následovaným dvojtečkou (např. From:). Jednoduchý email může vypadat následovně:
Received: from ant.feec.vutbr.cz (ant.feec.vutbr.cz [147.229.192.10]) by kazi.fit.vutbr.cz (8.12.11/8.12.11) with ESMTP id i2U8aPQJ027280 (version=TLSv1/SSLv3 cipher=EDH-RSA-DES-CBC3-SHA bits=168 verify=OK) for <novak@kazi.fit.vutbr.cz>; Tue, 30 Mar 2004 10:36:25 +0200 (CEST) Received: from PC4032133 (PC4032-133.ubmi.feec.vutbr.cz [147.229.194.157]) by ant.feec.vutbr.cz (8.12.11/8.12.11) with SMTP id i2U8aL1I088974 for <novak@feec.vutbr.cz>; Tue, 30 Mar 2004 10:36:22 +0200 (CEST) Message-ID: <000801c41632$003892e0$9dc2e593@ubmi.feec.vutbr.cz> From: "Jan Opicka" <opicka@feec.vutbr.cz> To: <novak@feec.vutbr.cz> Subject: Test Date: Tue, 30 Mar 2004 10:35:47 +0200 Toto je tělo emailu.
Pravidla se skládají z příznaků (flags), podmínek (conditions) a řádku akce (action). Pravidlo má obecný tvar:
:0 [flags] [: [LockfileName] ] < žadná, jedna nebo více podmínek (každá podmínka na samostatném řádku) > < požadovaná akce (jeden řádek) >
Každé pravidlo začíná :0. Za znakem nula mohou být uvedeny volby (flags). Je-li za znakem nula resp. za flagy uvedna dvojtečka, znamená to, že Procmail má pro danou podmínku použít lokální zamykací soubor. Jméno zamykacího souboru lze explicitně určit. Není-li určeno, Procmail použije jméno souboru (schránky) uvedené na řádku akce nebo jméno souboru za prvním znakem << (soubor, do kterého bude přesměrován výstup externího programu), a na konec připojí obsah proměnné $LOCKEXT (defaultně .lock). Lokální zamykací soubor se vztahuje pouze k dané podmínce.
Zamykání je třeba provádět při doručování do poštovní schránky (tedy zapisování do souboru), nebo jestliže je jako akce spuštěn externí program, který zapisuje do souboru. Při přeposílání emailu na jinou adresu zamykání není třeba a nemělo by se používat.
Jaký je význam zamykání? Procmail běží ve více procesech. Může se stát, že několik procesů chce současně zapisovat do stejného souboru (např. emailové schránky). Tím by ovšem došlo k promíchání obsahu emailů a k poškození schránky. Tento problém ošetřuje Procmail tak, že první proces, který přistupuje k pravidlu vytvoří zamykací soubor. Když se jiný proces dostane na začátek stejného pravidla, pokusí se též vytvořit zamykací soubor. To se mu však nepovede, neboť zamykací soubor již existuje. Druhý proces pak čeká až první proces dokončí zpracování pravidla a smaže zamykací soubor.
Podmínky jsou nepovinné. Není-li uvedena ani jedna podmínka, je akce aplikována na všechny emaily. Je-li naopak uvedeno více podmínek (tj. více řádků s podmínkami), jsou jednotlivé podmínky spojeny logickým operátorem AND. Pak se akce provede pouze v případě, že jsou splněny (pravdivé) všechny podmínkové řádky. Podmínky jsou rozšířené regulární výrazy kompatibilní s programem egrep(1). Kromě regulárních výrazů egrepu lze použít i další speciální podmínky, které musí začínat některým z následujících znaků:
| ! | Negace podmínky. |
| ? | Používá návratový kód zadaného programu. |
| < | Porovnává, zda celková délka emailu je menší než zadané dekadické číslo. |
| > | Porovnává, zda celková délka emailu je menší než zadané dekadické číslo. |
| prom ?? | Porovnává zbytek podmínky oproti hodnotě proměnné okolí prom. |
Poznámka 1: Standardně jsou podmínky vyhodnocovány pouze pro halvičky emailu,
nikoli pro tělo. Toto chování lze změnit pomocí flagů B a H.
Použijeme-li samotný flag B, je prohledáváno pouze tělo, při BH
jsou prohledávány hlavičky i tělo.
Poznámka 2: Procmail implicitně nerozlišuje velká a malá písmena.
Toto chování lze změnit pomocí flagu D.
Řádek s akcí určuje co se má s emailem provést v případě splnění všech podmínek. Chceme-li uložit dopis do určité schránky, uvedeme na řádku akce jméno poštovní schránky. V případě přeposílání emailu, začíná řádek s akcí vykřičníkem a za ním následuje adresa, na níž má být email přeposlán. Pro předání emailu externímu programu je třeba, aby řádek akce začínal znakem roura |.
Existují dva druhy pravidel - doručovací a nedoručovací. Jestliže je vykonáno doručovací pravidlo, Procmail již nezpracovává další pravidla. (Email je považován za doručený.) Toto chování lze změnit pomocí flagu c Po vykonání akce nedoručovacího pravidla Procmail pokračuje zpracováním následujícího pravidla. Doručovací pravidla jsou taková která způsobí uložení emailu (nebo jeho hlavičky či těla) do souboru nebo jeho absorbování programem či přeposlání na jinou adresu. Nedoručovací pravidla jsou taková, kde akce prožene email programem či filtrem, ale výstup je opět vrácen zpět do Procmailu.
Jestliže podmínka v pravidle není splněna, pak akce není spuštěna (email není doručen) a procmail pokračuje následujícím pravidlem. Projde-li Procmail již všechna pravidla v souboru .procmailrc (tj. nebyla provedena akce u žádného doručovacího pravidla), je email doručen do schránky definované proměnnou $DEFAULT. Proměnná $DEFAULT je na severech FEKT/FIT nastavena na /var/mail/login_name.
# Emaily od opicky do schranky opicka :0: * ^From: opicka@feec\.vutbr\.cz opicka
Vysvětlení:
:0 * !^FROM_MAILER # neposílat chyby ! petr.novak@email.cz
Vysvětlení:
:0 c * !^FROM_MAILER # neposílat chyby ! petr.novak@email.cz
Použití flagu c způsobí, že procmail neukončí provádění příkazového souboru .procmailrc po vykonání akce doručovacího pravidla, ale pokračuje dál. Nenajde-li další pravidlo, uloží email do defaultního lokálního mailboxu.
:0 * !^FROM_MAILER # neposílat chyby * < 1000 # na mobil jen malé dopisy ! petr.novak@sms.oscar.cz
Pravidlo je obdobné předchozímu. Navíc je zde pouze podmínkový řádek < 1000, který zabrání přeposílání emailů delších než 1000 znaků.
Nejjednodušším regulárním výrazem je jeden znak nebo řetězec znaků (string). Složitější regulární výrazy obsahují i metaznaky.
Význam metaznaků v regulárních výrazech:
| Metaznak | Význam v regulárním výrazu |
|---|---|
| . | Libovolný znak kromě znaku nový řádek. |
| * | Libovolný (i nulový) počet opakování výskytu předchozího znaku. |
| ? | Žádný nebo jeden výskyt předchozího znaku (položky). |
| + | Minimálně jeden výskyt předchozího znaku (položky). |
| ^ | Začátek řádku. |
| $ | Konec řádku. |
| [seznam znaků] | Libovolný jeden znak ze seznamu. |
| [^seznam znaků] | Libovolný jeden znak kromě znaků uvedených v seznamu. |
| (řetězec) | Řetězec je považován za jednu položku. |
| | | OR. Např. (abc|cde) znamená buď řetězec abc nebo cde. |
| \<řetězec\> | Slovo. Slovo je řetězec obsahující pouze písmena, číslice a podtržítka. Ostatní znaky slovo ohraničují (vymezují). |
| \metaznak | Zpětné lomítko vypíná funkci metaznaku. Např. \. má význam normální tečky nikoli "zpětného lomítka následovaného libovolným znakem". Neplatí však pro znak <, jehož speciální význam je třeba potlači jiným způsobem. |
| \nový řádek | Výraz pokračuje i na následujícím řádku. Znaky mezera na začátku následujícího řádku jsou ignorovány. |
| \/ | Rozdělí výraz na dvě části. Vše co odpovídá reg. výrazu vpravo od \/ je uloženo do proměnné prostředí $MATCH |
Přílady regulárních výrazů:
| a* | Libovolný počet opakování znaku a (i nulový). |
| a+ | Jeden nebo více znaků a. |
| a? | Žádný nebo jeden znak a. |
| [abuv12] | Libovolný ze znaků a,b,u,v,1,2. |
| [0-9] | Číslice. |
| [^abx12] | Libovolný znak kromě a,b,u,v,1,2 |
| [^-a-d] | Libovolný znak, který není pomlčka, nebo písmeno a,b,c,d |
| de|abc | Buď řetězec 'de' nebo 'abc'. |
| (abc)* | Nulové nebo vícenásobné opakování řetězce 'abc'. |
Předpokládejme, že požadujeme třídění zpráv z mailing listů:
mlist1@xxx.cz mlist2@yyy.cz mlist3@zzz.cz
do mailboxů mlist1, mlist2, mlist3. Pak není třeba psát tři různá pravidle, ale je lepší (např. vzhledem k rychlejší zpracování Procmailem) použít jedno pravidlo:
:0: * ^TO_\/(subscription1|subscription2|subscription3) $MATCH
Regulární výrazy Procmailu nejsou "hladové", což znamená, že se nesnaží "pozřít" co největší část textu, ale spokojí se s nejkratší částí, která regulárnímu výrazu vyhovuje. Vyjímkou je pouze pouze pravá část operátoru extrakce \/, která je hladová. Např. regulární výraz M*.i aplikovaný na řetězec Mailing list bude v případě nehladového regulárního stroje roven Mai, ale v případě hladového regulárního stroje (perl, grep) bude roven Mailing li.
Vnitřní proměnná H obsahuje hlavičky (headers) emailu, zatímco vnitřní proměnná B obsahuje tělo (body). Proměnným H a B by měla být dávána přednost před používáním flagů H a B.
Příklad použití:
:0: * H ?? ^Subject:.*money * B ?? call toll free smeti
Výše uvedené řetězce mají význam maker, které Procmail nahrazuje poměrně komplikovanými regulárními výrazy. Řetězec ^TO_ (obě písmena velká !) by měl zahrnovat hlavičky obsahující místo určení emailu ve formě konkrétní adresy. Typicky jde o halvičky To, Cc, Resent-To. Obdobnou funkci má i řetězec TO (měl by zahrnovat hlavičky obsahující místo určení emailu ve formě konkrétního slova), ale jeho používání se již nedoporučuje (upřednostňujte TO_). Řetězec ^FROM_DEAMON by měl zachytávat zprávy od většiny démonů a řetězec ^FROM_MAILER by měl zachytávat zprávy od většiny poštovních démonů.
^TO_ je nahrazeno:
(^((Original-)?(Resent-)?(To |Cc |Bcc) |(X-Envelope |Apparently(-Resent)?)-To) :(.*[^-a-zA-Z0-9_.])?)
Hledá hlavičku, které: začíná To, Cc, Resent-To, nebo jinou specifikací cíle, následuje znak :, libovolný počet znaků (i nulový) a může následovat emailová adresa, která začíná řetězcem s počátečním znakem -a-zA-Z0-9_..
^TO je nahrazeno:
(^((Original-)?(Resent-)?(To |Cc |Bcc) |(X-Envelope |Apparently(-Resent)?)-To) :(.*[^a-zA-Z])?)
^FROM_DEAMON je nahrazeno:
(^(Mailing-List : |Precedence :.*(junk |bulk |list) | To : Multiple recipients of |(((Resent-)?(From |Sender) |X-Envelope-From) : | >?From )([^>]*[^(.%@a-z0-9])?(Post(ma?(st(e?r)? |n) |office) |(send)?Mail(er)? | daemon |m(mdf |ajordomo) |n?uucp |LIST(SERV |proc) |NETSERV |o(wner |ps) | r(e(quest |sponse) |oot) |b(ounce |bs\.smtp) |echo |mirror |s(erv(ices? |er) | mtp(error)? |ystem) |A(dmin(istrator)? |MMGR |utoanswer)) (([^).! :a-z0-9][-_a-z0-9]*)?[%@>\t ][^<)]*(\(.*\).*)?)?$([^>] |$)))
^FROM_MAILER je nahrazeno:
(^(((Resent-)?(From |Sender) |X-Envelope-From) : | >?From )([^>]*[^(.%@a-z0-9])?(Post(ma(st(er)? |n) |office) |(send)?Mail(er)? | daemon |mmdf |n?uucp |ops |r(esponse |oot) |(bbs\.)?smtp(error)? | s(erv(ices? |er) |ystem) |A(dmin(istrator)? |MMGR)) (([^).! :a-z0-9][-_a-z0-9]*)?[%@>\t ][^<)]*(\(.*\).*)?)?$([^>] |$))
Další podrobnosti o souboru procmailrc lze získat z manuálových stránek man procmailrc. Příkladů konstrukce pravidel lze nalézt v man procmailex. Pro podrobné seznámení se s funkcí programu Procmail a psaním pravidel lze doporučit Proctut: Procmail Tutorials nebo Nancy McGough's "Procmail Quick Start".