original in en Angel Lopez
en to nl Tom Uijldert
Na het ophalen van de broncode hiervan moet vóór het installeren de zaak nog even worden opgeblazen en uitgepakt. Geef hiertoe het volgende commando:
$ tar -xzvf procmail.tar.gzVervolgens moeten de bestanden Makefile en config.h aan worden gepast. Daar dit artikel slechts een introductie tot het programma vormt, gaan we niet in op alle mogelijke keuzes die de configuratie van het pakket biedt. De lezer die meer wil weten wordt daarvoor verwezen naar de man pagina's en de bijbehorende documentatie.
Desalniettemin is het nuttig te wijzen op de optie BASENAME in het bestand Makefile. Hier geven we aan in welke directory we procmail gaan installeren. Hieronder komen weer sub-directories te staan zoals bin en man.
Uiteindelijk kunnen we het pakket gaan compileren en installeren met het commando:
$ make installProcmail kan voor het hele systeem worden geïnstalleerd en vervolgens worden aangeroepen door een regel in sendmail(8) of voor slechts één gebruiker. In het laatste geval zal de betreffende gebruiker het gebruik van procmail aan moeten geven middels een bestand .forward waarin de volgende regel op moet worden genomen:
|IFS=' ' && exec /home/juan/procmail/bin/procmail -f- || exit 75 #juanIn deze regel is aangenomen dat gebruiker Juan procmail in zijn HOME directory heeft geïnstalleerd. Hiervoor had tijdens het installeren BASENAME de waarde /home/juan/procmail moeten hebben.
Procmail biedt ook de mogelijkheid inkomende berichten of opgeslagen email automatisch af te handelen.
Iedere regel die met een # begint wordt als commentaar beschouwd.
Regels die met :0 of :0: beginnen geven het begin van een nieuwe instructie aan die procmail vertelt wat hij met een bericht moet doen.
Een regel die met een * begint geeft een voorwaarde aan waaraan moet worden voldaan wil de instructie worden toegepast op het bericht. Dit is het mechanisme dat procmail gebruikt om te bepalen met welke berichten wat moet worden gedaan (of niet).
Andere regels, oftewel diegene die niet beginnen met een #, : of * , worden als instructies gezien. Dat zijn de acties die procmail uit moet voeren op berichten die aan de voorwaarde voldoen. Mogelijke acties kunnen zijn het weggooien van een bericht, doorsturen van een bericht, opslaan van een bericht...
Het eerste wat moet worden geregeld in een .procmailrc bestand is de instelling van een aantal omgevingsvariabelen. Hieronder een aantal variabelen die ik je aanraad in te stellen in je .procmailrc bestand.
MAILDIR
Geeft aan in welke directory procmail berichten op kan slaan. Meestal
zal dit $HOME/mail zijn of $HOME/Mail. Dit
hangt af van het programma dat je gebruikt om je berichten te lezen.
LOGFILE
Geeft de naam (en plaats) aan van het bestand waar procmail een log
bij kan houden van alle instructies die hij uit heeft gevoerd.
SENDMAIL
Geeft aan waar het sendmail programma staat, wat wordt
gebruikt voor het automatisch beantwoorden van email.
FORMAIL
Geeft aan waar het programma formail is te vinden. Dit
programma wordt meegeleverd met procmail en wordt gebruikt voor het
wijzigen van email enveloppen of het veranderen van berichten
vóór het versturen of opslaan.
DEFAULT
Bestand waar berichten in op worden geslagen waarvoor procmail geen
instructies kon vinden.
Overal in het .procmailrc bestand kan men een omgevingsvariabele definiëren. Als deze wordt gegeven met alleen een =-teken erachter, zonder waarde, dan verdwijnt de variabele.
Voor wat betreft de instructies, die zijn er in twee smaken: instructies die het bericht als afgeleverd beschouwen na het toepassen ervan en instructies die dit niet doen.
De eerste groep instructies zijn eenvoudig. Na het toepassen ervan is de conclusie dat er geen andere instructies meer van toepassing zijn en dus wordt het bericht afgeleverd.
De tweede groep is vooral handig wanneer je meerdere instructies op een zelfde bericht toe wilt passen voordat deze wordt afgeleverd.
Het abstracte formaat voor een instructie is als volgt:
:0 [opties] [ : [uitgesloten bestand] ] * voorwaarde 1 * voorwaarde 2 . . . * voorwaarde N commandoLaten we deze constructie eens analyseren. De instructie begint met een :0, waarna één van de volgende opties kan worden gegeven:
H De voorwaarde is van toepassing op de aanhef.
B De voorwaarde wordt gezocht in de inhoud van het
bericht.
D Maak tijdens zoeken onderscheid tussen
hoofd- en klein letters.
A Deze regel alleen toepassen als de vorige ook is
toegepast.
a Net als A maar dan alleen als de
uitvoering van de vorige regel foutloos was.
E Deze regel alleen toepassen als de vorige
niet is toegepast.
e Net als E maar dan alleen als de
uitvoering van de vorige regel fout ging.
h De aanhef van het bericht wordt doorgegeven aan het
commando.
b De inhoud van het bericht wordt doorgegeven aan het
commando.
f De instructie is een filter.
c Maak een kopie (cc) van het bericht. Indien
hier een instructie staat die het bericht als afgeleverd beschouwd na
uitvoering dan kan men met deze optie er omheen doordat volgende
instructies nog verder kunnen met de kopie.
w Wacht tot de vorige instructie klaar is met uitvoeren
en vang de foutcode op.
W Als in w maar rapporteert geen
fouten.
i Negeer mogelijke typefouten.
r Sla het bericht onveranderd op. Geen controle op het
eindigen met een lege regel.
Indien er geen opties op zijn gegeven dan zal de voorwaarde worden getest op de aanhef (H). Het commando krijgt op zijn standard input zowel aanhef als inhoud aangeleverd en er wordt geen onderscheid gemaakt tussen hoofd- en kleine letters.
Na het :0 en mogelijke opties kan een tweede :-teken volgen. Dit geeft aan dat het uitvoerbestand afgeschermd moet worden om te voorkomen dat twee processen tegelijk in hetzelfde bestand schrijven. Men kan daarbij het bestand opgeven wat als afscherming (lock) kan worden gebruikt.
Vervolgens de voorwaarden, één per regel en voorafgegaan door een *-teken. Voorwaarden zijn meestal in de vorm van reguliere expressies die bepaalde tekst-delen moeten vinden in de aanhef of de inhoud van een bericht. Onder andere de volgende symbolen kunnen worden gebruikt in reguliere expressies:
^ Begin van de regel.
$ Einde van de regel.
. Een (welke dan ook) teken, behalve 'nieuwe regel'.
* Nul of meerdere keren herhaald.
+ Eén of meer keren herhaald.
? Nul of één keer.
[a-z] Een tekenbereik, in dit voorbeeld van 'a' tot 'z'.
[^a-z] Een tekenbereik buiten het gegeven bereik (alles
behalve 'a' tot 'z').
a|b Het teken 'a' óf 'b'.
Na de voorwaarde volgt de instructie. Als deze begint met
één van de volgende tekens dan gedraagt de instructie zich
op een speciale manier:
! Het bericht gaat naar alle email adressen die zijn
opgegeven.
| Als hierachter een executeerbaar programma staat dan
wordt dit uitgevoerd als aan de voorwaarde is voldaan. Als er niets
achter staat dan wordt de volledige tekst van het bericht naar
standard output geschreven. Als de naam van een variabele er
achter staat dan wordt het resultaat van het commando in die variabele
gezet.
l-linux@calvo.teleco.ulpgc.es linux@nuclecu.unam.mx linux-security@redhat.comNormaal gesproken komen berichten van deze lijsten op gezette tijden aan in dezelfde postbus (mailbox) en daar staat dan alles door elkaar heen. Het zou veel mooier zijn als, wanneer email aankomt, alles netjes werd gesorteerd en in de juiste bestanden zou worden opgeslagen.
Procmail kan dit probleem eenvoudig oplossen. We zouden hierbij het volgende .procmailrc bestand kunnen gebruiken voor het sorteren van de Linux mailing lists:
:0 * ^From.*l-linux@calvo.teleco.ulpgc.es l-linux :0 * ^From.*linux@nuclecu.unam.mx linux-mx :0 * ^From.*linux-security@redhat.com linux-securityLaten we eens één van de instructies analyseren. Wanneer je de werking ervan begrijpt dan is het ook makkelijk om de rest te begrijpen omdat het basisprincipe hetzelfde is.
Allereerst de :0 die het begin van een nieuwe instructie aangeeft. Hier staan geen opties achter dus de standaard instellingen gelden: geen onderscheid tussen hoofd- en kleine letters, we grazen alleen de aanhef af en het commando geldt zowel de aanhef als de inhoud van het bericht.
De volgende regel bevat de voorwaarde, zoals altijd aangegeven met een '*' aan het begin. De volgende reguliere expressie vormt de voorwaarde:
^From.*linux@nuclecu.unam.mxHet gedeelte ^From geeft aan dat gezocht moet worden naar regels die beginnen met de tekst From.
De volgende (.*) expressie geeft aan, 'wat voor tekens dan ook'. We hebben hiervoor al gezien dat de punt staat voor 'ieder teken' en de asterisk voor 'nul of meerdere keren herhaald'. Dit betekent dat na From er een aantal tekens kan volgen.
Daarachter moet dan linux@nuclecu.unam.mx staan, wat het adres van de afzender van dit bericht moet zijn.
Even doordenkend op reguliere expressies zul je zien dat de volgende combinaties door deze voorwaarde worden herkend:
From: linux@nuclecu.unam.mx From:linux@nuclecu.unam.mx FROM linux@nuclecu.unam.mxMet deze voorwaarde kunnen we reeds onderscheid maken tussen berichten die van dit adres afkomstig zijn en anderen. Nu we het bericht dus hebben, wat zullen we er mee doen?
De volgende regel bevat het commando (de instructie) en geeft aan wat we met het bericht moeten doen. In dit geval moet het in het bestand linux-mx worden weggeschreven. Als je niet het volledige pad van het bestand opgeeft zal er standaard $MAILDIR voor worden geplakt.
Het moge duidelijk zijn dat berichten nu kunnen worden gescheiden in diverse bestanden, op basis van afzender (From-veld).
Om dit te doen maken we een instructie die er van uit gaat dat een bericht met de tekst "PGP" in het veld Subject: om de sleutel vraagt. De instructie kan er als volgt uitzien:
0: * ^Subject.*PGP | (formail -r ; cat $HOME/key.asc) | sendmail -tHetzelfde mechanisme kan toe worden gepast voor een automatisch antwoord op alle post met de mededeling dat we op vakantie zijn en zullen antwoorden zodra we terug zijn:
0: | (formail -r; cat $HOME/vacations.txt) | sendmail -tDeze instructie heeft geen voorwaarde omdat we op alle post willen antwoorden.
Als we antwoorden op een bericht dat afkomstig is van ons eigen adres dan zou het antwoord dus naar ons terug komen. Hierop zou dan weer automatisch een antwoord worden gegenereerd wat wederom terug zou komen... ad infinitum. Om dit te voorkomen kun je in het antwoord een extra regel in de aanhef opnemen om zo aan te geven dat op het bericht reeds een antwoord is gestuurd. Met de optie -A van formail wordt dit:
formail -r -A"X-Loop: dir@email.nl"Waarbij dir@email.nl staat voor je eigen email adres. Deze extra regel zal in het antwoord op worden genomen zodat onderstaande instructie hierop kan controleren:
:0 * !^X-Loop: dir@email.es | (formail -r -A"X-Loop: dir@email.es" ; cat $HOME/vacation.txt) | sendmail -tDe instructie voorkomt een lus doordat het antwoorden niet wordt toegepast op berichten die een regel met X-Loop in de aanhef hebben.
:0 B * ^begin 644 .* { MAILDIR=$HOME/files :0 | uudecode }Hier is met optie B expliciet aangegeven dat de voorwaarde alleen wordt getest op de inhoud van het bericht.
Als er een zin wordt gevonden die begint met "begin 644" dan heeft de instructie de start van een bestand gevonden wat met uuencode(1) is gecodeerd. Vervolgens zal de omgevingsvariabele MAILDIR een nieuwe waarde krijgen wat effectief betekent dat vanaf dat moment alle afdruk- en weergavecommando's effect hebben op de aangegeven directory, in dit geval $HOME/files.
Vervolgens een commando zonder voorwaarde die de inhoud van het bericht door uudecode(1) jaagt voor het decoderen. Het oorspronkelijke bericht verdwijnt in $HOME/files.