freeX: Wann kommt die Flut?
|
Mails mit procmail sortieren
| |
Wer nicht nur passiv am Netz der Netze teilnimmt, muß meist nicht
lange warten, bis er eine wahre Flut von Mails zu lesen oder zu
Bearbeiten hat. Wer sich regelmäßig oder unregelmäßig an Diskussionen
über Software beteiligt, trägt sich auf sogenannte Mailing-Listen ein.
Wer selbst freie Software entwickelt und im Internet zur Verfügung
stellt, wird sogar selbst eigene Mailing-Listen anbieten.
|
|
1. Ertrinken oder nicht? |
Hinzu kommen Statusmails von den betreuten Rechnern: Cronjobs spucken Fehlermeldungen aus, die per Mail verschickt werden, News- und UUCP-Systeme generieren täglich Statusberichte, Mirror-Skripte auf FTP-Servern verschicken Erfolgsmeldungen, Fax-Benachrichtigungen treffen ein etc.
Kurzum, nach einer gewissen Zeit wird man man schier überflutet mit Mails, dessen Inhalt mehr oder weniger wichtig ist. Für weniger geübte Menschen reichen schon 100 Mails pro Tag, um sie effektiv von ihrer Arbeit abzuhalten. Bei erfahrenen Netzteilnehmern liegt die Grenze höher, vielleicht bei 500 oder 1000 Mails pro Tag, bis auch sie kapitulieren und eine Lösung suchen müssen.
Benötigt wird eine Möglichkeit, Mails vorzusortieren. Die meisten Programme zum Lesen und Schreiben von Mails sind zudem nicht nur in der Lage, eine einzige Mailbox zu verwalten, sondern können angewiesen werden, auf weiteren Dateien zu arbeiten.
Eine große Hilfe wäre es bereits, wenn eintreffende Mails in unterschiedlichen Mailboxen gespeichert werden könnten. Damit würden unnötige Gedankensprünge vermieden und Mails können schneller bearbeitet werden.
Einige Mailing-Listen setzen den Namen der jeweiligen Liste in eckigen
Klammern vor den Betreff (so daß z.B. "[gtk-list] New version of foo"
entsteht). Das erleichtert zwar das Erkennen der jeweiligen Liste,
ist jedoch überflüssig, wenn Mails sowieso automatisch vorsortiert
werden. Überdies wird der Betreff dadurch verlängert, was teilweise
zur Folge hat, daß er nicht mehr komplett angezeigt werden kann, wenn
nicht mehr als 80 Zeichen pro Zeile zur Verfügung stehen. In dem Fall
wäre es sinnvoll, diesen Zusatz löschen zu können.
Ertrinken oder nicht?
Eine Lösung für die oben beschriebenen Szenarien heißt "procmail" (von:
process mail). Stephen van den Berg bemerkte diese Probleme bereits
1990 und entwickelte ein äußerst vielseitiges Programm, um wieder Herr
über seine Mails zu werden.
Procmail filtert Mail, es verarbeitet eine einzige Mail anhand vorgegebene Regeln. Dabei kann die Mail gemäß verschiedener Gesichtspunkte in unterschiedlichen Mailboxen gespeichert, via als Eingabe (stdin) für Programme dienen oder umgeleitet werden. Es können außerdem Daten extrahiert und Mails dupliziert werden.
Eine Mail wird solange weiterbearbeitet wie sie innerhalb von procmail
existiert. Wird sie in einer Datei gespeichert ohne vorher dupliziert
zu werden, war das die letzte Stufe und procmail beendet sich. Wird
sie stattdessen als Eingabe für ein Programm verwendet, so beendet sich
procmail anschließend ebenfalls, wenn die Mail nicht dupliziert wurde
und procmail nicht angewiesen wurde, auf die Beendigung des Programms
zu warten oder mit dessen Ausgabe fortzufahren.
Gesteuert wird procmail über ein oder mehrere sogenannte
procmailrc-Dateien (rc = run-commands, Startbefehle). Diese sind in
einer recht einfachen, jedoch effizienten, Syntax geschrieben. Mit
einigen Kniffen lassen sich sogar Kontrollstrukturen wie Schleifen und
Verzweigungen implementieren, ganz genau wie bei herkömmlichen
Programmiersprachen.
Woher nehmen?
Bei den meisten Linux-Distributionen ist procmail bereits im
Lieferumfang enthalten, da die Entwickler meist ohne procmail selbst
in der Mailflut ertrinken würden. Ist procmail nicht auf ihrem System
enthalten, dann holen Sie sich das zugehörige Quellcode-Archiv einfach
aus dem Internet, und zwar via FTP von
<ftp.informatik.rwth-aachen.de/pub/packages/procmail/>. Die neueste
Version ist procmail-3.11pre7.tar.gz.
Um es zu installieren, wechseln Sie ins /tmp-Verzeichnis und packen die Datei mit dem Befehl "tar xfz procmail-3.11pre7.tar.gz" (bzw. mit gunzip und tar xf, falls kein GNU tar vorliegt) aus. Im Verzeichnis procmail-3.11pre7 befindet sich nun der Quellcode. Jetzt wechseln Sie in dieses Verzeichnis und compilieren das Paket mit dem Befehl "make". Als "root" installieren Sie das Paket aus dem gleichen Verzeichnis heraus mit dem Befehl "make install".
Procmail kann als Local-Delivery-Agent eingesetzt werden und zusammen
mit dem installierten Mailsystem (sendmail, smail, exim etc.)
arbeiten. Ist das gewünscht, so sei auf die beigelieferte
Dokumentation von procmail verwiesen. Für unsere Zwecke wird procmail
aus der Datei ".forward" im Heimatverzeichnis aufgerufen. Die
folgende Zeile ruft procmail für jede neue Mail auf.
"|IFS=' ' && exec /usr/bin/procmail -f- || exit 75"
Einfache Regeln
Wie bereits erwähnt, durchläuft die Mail die in den procmailrc-Dateien beschriebenen Regeln, solange keine dieser Regeln die Mail quasi herausnimmt. Die eigentliche RC-Datei ist ".procmailrc" in ihrem Benutzerverzeichnis. Wenn die Mail zum Schluß noch existiert, wird sie in der regulären Mailbox (meistens /var/spool/mail/$user) gespeichert.
Eine procmail-Regel besteht aus drei Teilen. Eingeleitet wird sie mit ":0"
gefolgt von Flags (siehe Tabelle 1). Der mittlere Teil enthält keine,
eine oder mehrere reguläre Ausdrücke, denen die Mail entsprechen muß.
Jeder Ausdruck wird mit einem Stern "*" eingeleitet. Den Schluß einer
Regel bildet genau eine Aktion, die ausgeführt werden soll, wenn alle
angegebenen Ausdrücke passen. Im folgenden einige einfache Regeln:
:0c
inbox
:0
* ^From:.*chef@firma\.de
! ich@buero.com
:0
* ^From:.*root@logster\.firma\.de
* ^Subject: cisco01 down
| /usr/local/sbin/sms-mail
| |
Einfache Regeln mit procmail |
|
Die erste Regel enthält keinen regulären Ausdruck, dafür jedoch das
Flag 'c'. Es weist procmail an, die Mail nach dieser Regel nicht
wegzuwerfen, auch wenn die Aktion erfolgreich ausgeführt wurde. Die
auszuführende Aktion besteht lediglich aus einem Dateinamen. Damit
ist die Bedeutung klar: procmail legt eine Kopie aller Mails in der
Datei "inbox" an. Falls nicht weiter beschrieben, wird die Datei im
Benutzerverzeichnis angelegt.
Wenn Sie sich nicht sicher sind, ob ihre Regeln auch so funktionieren, wie sie sollen, dann speichern Sie jede eingehende Mail zuerst als Kopie in einer Mailbox. Sie lesen die dort gespeicherten Mails z.B. mit "elm -f inbox" oder "mutt -f inbox".
| c | Verarbeitet die Mail als Kopie, nach dieser Regel kann sie von weiteren Regeln bearbeitet werden |
| H | Der reguläre Ausdruck bezieht sich auf den Mail-Header (Voreinstellung) |
| B | Der reguläre Ausdruck bezieht sich auf den Inhalt der Mail |
| f | Diese Regel fungiert als Filter, die Eingabe wird anschließend durch die Ausgabe des Programs ersetzt |
| b | Der Inhalt der Mail wird als stdin für das Filter verwendet (Voreinstellung) |
| h | Der Kopf der Mail wird als stdin für das Filter verwendet (Voreinstellung) |
| w | Procmail wartet auf die Beendigung des Filters oder Programms |
| i | Ignoriert Schreibfehler des Programms oder Filters |
| D | Reguläre Ausdrücke unterscheiden zwischen Groß- und Kleinschreibung |
| A | Diese Regel wird nur dann ausgeführt, wenn die Bedingungen der vorherigen Regel ebenfalls paßten |
| a | Wie A, jedoch muß die Aktion der vorherigen Regel erfolgreich gewesen sein |
| E | Diese Regel wird nur dann ausgeführt, wenn die vorherige nicht ausgeführt wurde |
| Tabelle 1: Flags in procmail-Regeln | |
Die zweite Regel im obigen Beispiel schickt die Mail an eine weitere Adresse. Das Ausrufezeichen steht für "Bounce" (prellen, hier: weiterleiten). Nach einem Ausrufezeichen werden Mail-Adressen angegeben, an die die Mail geschickt werden soll.
Der reguläre Ausdruck schränkt diese Regel auf die Mails ein, die von Ihrem Chef geschrieben wurden. Da sie Zuhause nicht mit Firmenproblemen belästigt werden möchten, sollen diese gleich ins Büro geschickt werden. Das Caret im regulären Ausdruck bedeutet, daß der Ausdruck am Zeilenanfang ansetzt. Der Punkt "." ist ein Platzhalter für jedes beliebige Zeichen, weshalb ihm in der Adresse ein Backslash vorgeschaltet werden muß, wenn ein Punkt selbst erwartet wird.
Die Regel wird angewendet auf Mails, in denen im Kopf die Zeile
From: chef@firma.de (Hans Wurst)
steht, oder auch
From: Hans Wurst
Jedoch nicht auf Mails, in denen die Adresse des Chefs nur im Betreff vorkommt:
Subject: From: chef@firma.de
Die dritte Regel würden Sie natürlich nicht Zuhause sondern nur im Büro einsetzen. Der Sinn dieser Regel besteht darin, eine Nachricht (SMS) an den Firmen-Pieper zu schicken, damit der Bereitschaftsdienst die gerade ausgefallene Leitung wieder hochfährt.
Der erste reguläre Ausdruck legt fest, daß die Mail von root@logster.firma.de kommen muß. Außerdem muß der Betreff lauten "cisco01 down". Nur wenn beide Ausdrücke auf die Mail passen, wird sie als als Eingabe (stdin) an das angegebene Programm übergeben, welches die Subject:-Zeile herausfiltert und den Inhalt an den Pieper schickt.
Ein regulärer Ausdruck wird negiert, wenn ihm das Ausrufezeichen
vorangestellt wird. Darüberhinaus hat procmail einige reguläre
Ausdrücke bereits eingebaut, die in Form von Makros zur Verfügung
stehen.
Wenn man alle Mails herausfiltern möchte, die an einen persönlich geschickt wurden, kann man es mit folgender Regel versuchen:
:0 * ^(To|Cc):.*joey@ personal
Die meisten persönlichen Mails erwischt man damit sicherlich. Wenn eine Mail gebounct wird, greift diese Regel jedoch nicht, da die eigene Adresse weder in der To- noch in dern Cc-Zeile steht. Anders sieht es aus, wenn man das Makro ^TO benutzt. Damit sieht die Regel wie folgt aus
:0 * ^TO.*joey@ personal
Das Makro ^TO wird zu folgendem Text expandiert, wenn procmail ihn
liest: `(^((Original-)?(Resent-)?(To|Cc|Bcc)|
(X-Envelope|Apparently(-Resent)?)-To):(.*[^-a-zA-Z0-9_.])?)'. Damit
werden selbst Mails erkannt, die via Bounce weitergeschickt wurden.
Überdies fangen die Makros ^FROM_MAILER und ^FROM_DAEMON die Mails auf, die von Mailer-Daemonen oder Daemonen allgemein verschickt wurden. Da die Ausdrücke fünf bis zehn Zeilen lang sind, sei der geneigte Leser an dieser Stelle auf die Manpage procmailrc(5) verwiesen. Um derartige Mails auszuschließen, würde man anstelle der obigen Regel eher die folgende verwenden:
:0
* ! ^FROM_DAEMON
* ^TO.*joey@
personal
Wenn Sie den Artikel bis zu dieser Stelle verstanden haben, kennen Sie
procmail bereits und können mit dem Programm umgehen. Im Prinzip wird
dieser Artikel nichts neues mehr beschreiben. Die Regeln werden
lediglich verfeinert. Nichtsdestotrotz sollten Sie den Artikel zuende
lesen, denn er wird Ihnen Anregungen und Ideen liefern.
Üblicherweise wird procmail dazu eingesetzt, Mailing-Listen in eigenen
Mailboxen zu speichern. Zum Schluß wird gezeigt, wie man dieses
generisch erreichen kann. Der folgende Auszug extrahiert zwei Listen
in eigene Mailboxen:
:0 * ^X-Mailing-Lists:.*gnome-list@ gnome-list :0 * ^Sender: owner-postfix-users@postfix\.org postfix-users | |
| Filtern von Mailing-Listen in eigene Mailboxen | |
Im Dateinamen dürfen externe Programme aufgerufen werden. So läßt sich z.B. ziemlich einfach ein jährliches Archiv der gesamten eingehenden Mail vom Chef erstellen:
:0 c * ^From:.*chef@firma\.de Mail/archive/chef.`date +%Y`
Variablen
Procmail wäre nicht so flexibel, wenn es nicht auch normale Variablen unterstützen würde. Sie werden genauso benutzt wie in einem normalen Shell-Skript (Bourne Shell). Mit "$VAR" oder ¨${VAR}" wird der Wert der Variablen VAR an der aktuellen Position eingesetzt. Zuweisungen erfolgen - wie in der Shell - mit einem Gleichheitszeichen.
HOSTNAME=`hostname`
FOO=bar
MAILDIR=$HOME/Mail/IN
skiplists=(debian-(user|changes))
| |
| Setzen von wichtigen Variablen | |
Wie in diesen Beispielen zu sehen ist, können den Variablen sogar Ausgaben externer Programme und Inhalte weiterer Variablen zugewiesen werden. Den Namen der Variablen dürfen Sie ebenfalls frei wählen. Die Bedeutung einiger Variablen ist jedoch vorgegeben, diesen werden beim Programmstart bereits Werte zugewiesen. In Tabelle 2 sind die wichtigsten aufgelistst.
Mit den obigen Einstellungen, werden die Mailboxen nicht im Homeverzeichnis, sondern in einem speziellen Verzeichnis für eingehende Mails gespeichert.
| HOME | Heimatverzeichnis des Benutzers, der procmail aufruft |
| LOGNAME | Login des Benutzers |
| HOST | Rechnername (ohne Domain), auf dem procmail läuft |
| MAILDIR | Verzeichnis, in dem Mailboxen liegen, ist vorgegeben |
| DEFAULT | Fallback-Mailbox, wenn die Mail zum Ende der RC-Dateien noch existiert, /var/spool/mail/ ist voreingestellt |
| LOGFILE | Logdatei |
| SENDMAIL | Pfad zum sendmail-Programm, meist /usr/lib/sendmail |
| SENDMAILFLAGS | Zusätzliche Argumente für sendmail |
| Tabelle 2: Vorgegebene Variablen von procmail | |
In einem procmailrc lassen sich die Variablen natürlich auch abfragen und nicht nur innerhalb von Aktionen verwenden. Mit dem ??-Operator wird eine Variable auf Gleichheit mit einer Zeichenkette getestet. Der folgende Ausschnitt legt z.B. nur dann eine Kopie aller Mails an, wenn die Variable "backup" entsprechend gesetzt ist:
backup= :0 c * backup ?? y Mail/backup
Wenn eine Variable innerhalb eines regulären Ausdruckes verwendet
werden soll, dann muß procmail am Zeilenanfang mitgeteilt werden, daß
im Rest der Zeile Variablensubstitution stattfinden soll und das
Dollarzeichen kein Zeilenende symbolisiert. Zu diesem Zweck muß der
Ausdruck mit einem Dollarzeichen eingeleitet werden.
Das folgende Beispiel verdeutlicht dieses. Die Variablen steuern die nachfolgende Regel. Sie wird nur dann angewendet, wenn "use_inbox" nicht gesetzt ist und die Mail entweder "X-Loop: debian-private@" oder "X-Loop: debian-devel@" enthält:
use_inbox=n inboxlists=(debian-(devel|private)) :0 * ! use_inbox ?? y * $^X-Loop: $inboxlists@ inbox | |
| Dynamische Regeln mit Variablen-Auswertung | |
Eingangs wurde erwähnt, daß man mit procmail-Regeln auch
Kontrollstrukturen erzeugen kann, wie bei herkömmlichen
Programmiersprachen. Um Verzweigungen zu erhalten, wird das Flag E
benötigt. Das obige Beispiel läßt sich damit einfach so umformen, daß
man folgendes Ergebnis erziehlt:
IF (use_inbox == y) THEN speichere in inbox ELSE IF (X-Loop in inboxlists) THEN speichere in inbox FI FI ... | |
| Einfaches IF-THEN-ELSE-Konstrukt | |
In procmail-Syntax geschrieben sieht dieses wie folgt aus:
use_inbox=n inboxlists=(debian-(devel|private)) :0 * use_inbox ?? y inbox :0 E * $^X-Loop: $inboxlists@ inbox | |
Einfaches IF-THEN-ELSE-Konstrukt mit procmail |
|
Ebenfalls interessant in diesem Zusammenhang ist das Flag A, das
bewirkt, daß eine Regel nur dann beachtet wird, wenn die vorherige
Regel der gleichen Ebene ebenfalls ausgeführt wurde. Das Flag a ist
eine Verschärfung dessen, denn in diesem Fall muß die vorherige Aktion
gleichzeitig erfolgreich gewesen sein. Im Falle eines Programms darf
das Programm also keinen Fehlercode ungleich 0 zurückgegeben haben.
Auf diese Weise lassen sich Ketten von Regeln aufstellen, ohne daß
reguläre Ausdrücke mehrfach überprüft werden müssen.
Anweisungsblöcke
Überdies lassen sich Regeln schachteln. Die Aktion einer Regel darf nicht nur aus einer Datei, einer Adresse oder einem Programm bestehen. Es darf auch ein neuer Block angefangen werden. Dieser wird mit einer geöffneten geschweiften Klammer eingeleitet und mit einer geschlossenen beendet.
Innerhalb eines Blockes können die gleichen Anweisungen gemacht werden wie im restlichen procmailrc. Flags wie E und A beziehen sich immer auf Regeln der gleichen Ebene, die letzte Regel innerhalb eines neuen Blocks beeinflußt daher ein nachgeschaltetes A oder E nicht unbedingt. So lassen sich z.B. auch umfangreiche If-Then-Else-Konstrukte erzeugen.
Im folgenden Beispiel wird von dieser Technik Gebrauch gemacht. Prinzipiell sollen alle Mails in der Mailbox "inbox" gespeichert werden, wenn "use_inbox" entsprechend gesetzt ist. Einige Mailing-Listen sind jedoch so umfangreich, dass sie dennoch getrennt gelesen werden sollen. Die Namen dieser Listen sind in der Variablen "skip_lists" angegeben, natürlich als regulärer Ausdruck.
RCDIR=$HOME/.procmail
skip_lists=(debian-(user|changes)|linux-(kernel|gcc))
:0
* use_inbox ?? y
{
:0
* $^X-Loop: $skiplists@
{
INCLUDERC=$RCDIR/rc.split
}
:0
inbox
}
:0 E
* $^X-Loop: $inboxlists@
inbox
INCLUDERC=$RCDIR/rc.split
| |
| Komfortables Management von Mailing-Listen | |
In diesem Beispiel wird bereits vorgegriffen auf die Variable
INCLUDERC. Dabei handelt es sich weniger um eine Variable, denn um
einen Befehl. Er bewirkt nämlich, daß die nach dem Gleichheitszeichen
angegebene Datei an dieser Stelle abgearbeitet wird. Auf diese Weise
lassen sich quasi Prozeduren oder Teilprogramme definieren, die an
verschiedenen Stellen eingebunden werden können. Durch
Variablenzuweisungen können ihnen zudem Daten übermittelt werden. Die
so aufgerufene Routine rc.split wird später erläutert.
Header-Manipulation
Neben den Programm procmail ist formail ein weiterer Bestandteil im
procmail-Paket. Bei formail handelt es sich ebenfalls um ein Filter
für Mails. Im Gegensatz zu procmail werden eingehende Mails jedoch
nicht sortiert, sondern modifiziert. Das Programm formail ist dazu
gedacht, Header-Zeilen zu ergänzen oder zu löschen sowie Mailboxen
aufzuteilen. Dem geneigten Leser sei an dieser Stelle die Manpage
formail(1) ans Herz gelegt.
Formail wird daher oft in Zusammenhang mit fhw-Regeln (filter-header-wait, siehe Tabelle 1) in einem procmailrc verwendet. Procmail schickt dabei den Header der Mail durch das angegebene Programm und ersetzt ihn durch die Ausgabe des Programms. Auf diese Weise werden Zeilen im Header verändert, hinzugefügt oder gelöscht. Eine übliche Anwendung ist es, eine Mail zu markieren, etwa mit folgender Regel:
:0 fhw | formail -A"Delivered-To: joey@buero.firma.de"
Der Header der Mail wird damit um die Delivered-To-Zeile ergänzt.
Wenn man Mails von mehreren Accounts an andere weiterleitet, um neue
Mails immer auch am aktuellen Rechner zu erhalten, besteht die Gefahr,
Mail-Loops zu erzeugen. Durch diese Technik muß procmail vor einem
Forward lediglich überprüfen, ob diese Zeile bereits existiert und sie
ggf. hinzufügen und die Mail weiterleiten.
Mit "formail -a" würde die Zeile nur dann hinzugefügt werden, wenn bisher keine Delivered-To-Zeile im Mailkopf enthalten war. Mit "-i" würden bisher existierende Zeilen in "Old-" umbenannt werden, "-I" würde bisher vorhandene Felder einfach löschen.
Natürlich ist formail nicht das einzige mögliche Filter, weitere sind ebenfalls möglich. Einige Mailing-Listen sind beispielsweise so konfiguriert, daß sie die Betreffzeile verändern und überflüssigerweise den Namen der Liste hineinschreiben.
Diese Ergänzungen sind hilfreich, wenn alle Mails in einer einzigen Mailbox gespeichert und nicht pro Liste aufgeteilt würden. Wer sie dann lieber nicht sehen möchte, der kann diese Zusätze mit einer einfachen Regel löschen lassen:
:0 fhw * ^X-Loop: gtk-.*list@ | sed 's/\[gtk.*-list\] //g'
Wenn es nicht explizit angegeben wird (nur fw), schickt procmail die
Mail samt Header und Inhalt durch das Filterprogramm. Durch die
zusätzliche Angabe von "b" (body) oder "h" (header) wird procmail
angewiesen, nur den Header oder nur den Inhalt an das Filter zu
schicken.
Im folgenden Beispiel werden Pressemitteilungen verarbeitet. Sie sind
breiter als 80 Zeichen und daher auf einem regulären Terminal nicht
vernünftig zu lesen. Daher wird procmail angewiesen, die Zeilen im
Mailinhalt entsprechend umzubrechen und anschließend eine passende
X-Loop-Zeile hinzuzufügen.
:0 fbw
* ^From: info@pressezentrum\.de
* ^To: Abonnement@pressezentrum\.de
| fold -s
:0 fhwa
| formail -A "X-Diagnostic: Processed by fold" \
-I "X-Loop: presse-info@pressezentrum.de"
| |
| Automatische Manipulation von Mails | |
Eine weitere Möglichkeit, die Anzahl eingehender Mails zu reduzieren besteht in der Benutzung von Digests. Die Mailing-Liste wird dann nicht mehr in Form einzelner Mails verteilt. Stattdessen wird ein Dutzend Mails zu einer großen Mail zusammengesetzt und erst dann verschickt. Insbesondere bei umfangreichen Listen (wie z.B. linux-kernel oder debian-user) wird dieses Verfahren zusätzlich angewendet.
Ein weiterer Grund für die Verwendung von digests besteht darin, hitzige und zu schnelle Diskussionen zu vermeiden. Entwickler eines Software-Pakets sind dann zum Beispiel auf der regulären Liste eingetragen während interessierte Leute sich nur auf der Digest-Liste einschreiben können. So wird die Auslieferung der Mails leicht verzögert, die Inhalte der Liste sind jedoch öffentlich und jedem zugänglich.
In diesem Fall möchte man die zusammengesetzten Mails vielleicht lieber einzeln lesen. Je nach verwendetem Programm zum Lesen der Mails wird ein Digest als eine große Mail angezeigt oder als eine Mail mit mehrern Abschnitten. Einzeln lassen sich die Mails jedoch besser anhand ihrer Verweise oder Themen sortieren.
Die Zurückverwandlung in einzelne Mails gehört klar zum Aufgabenfeld von formail. Das Argument "-s" teilt den Eingabestrom in einzelne Mails auf und nimmt sie als Eingabe für das Programm, welches anschließend in der Kommandozeile angegeben wurde. Dieser Parameter muß daher der letzte sein. So läßt sich eine bestehende Mailbox in ihre Komponenten aufteilen oder neu sortieren.
Für einen Digest reicht das jedoch noch nicht, denn eine Digest-Mail besteht nur aus einer einzigen Mail. Daher muß formail zusätzlich mitgeteilt werden, daß der Eingabestrom ein Digest ist, der aufgeteilt werden soll. Mit dem Parameter "-d" wird bestimmt, daß die Eingabe nicht im strengen Mailbox-Format vorliegt, sondern z.B. als Digest.
Mit dem bisherigen Wissen läßt sich ein Digest in einzelne Mails aufteilen, man erhält oftmals jedoch eine "überflüssige" Mail. Das Inhaltsverzeichnis ist oft die erste Komponente eines Digests. Wenn man die Mails einzeln lesen kann, wird es nicht mehr benötigt und darf ausgelassen werden. Auch darauf ist formail vorbereitet, denn mit "+1" wird die erste Mail übersprungen.
Die fertige Regel, um ein Digest aufzuteilen sieht dann wie folgt aus. Wenn die originale Digest-Mail behalten werden soll, muß das Flag "c" hinzugefügt werden.
:0 * ^X-Mailing-List:.*spliff-digest@lists.foo.org | formail +1 -A"X-Loop: spliff@lists.foo.org" -ds procmail
Autoresponder
Eine weitere Fähigkeit von formail ist es, zu einer Mail eine passende Antwortmail zu erzeugen. Auf diese Weise lassen sich kleine Mailserver aufsetzen, z.B. um bei Anfragen Textdateien zurückzuschicken oder einfache Info-Accounts. Aus einer eingehenden Mail generiert "formail -r" den Kopf einer Antwortmail. Dabei werden alle Zeilen außer X-Loop gelöscht bzw. entsprechend umgewandelt.
An einen derart erzeugten Mail-Header muß lediglich der Mailinhalt angehängt werden, bevor die Mail rausgeschickt werden kann. Dazu werden normale Techniken einer Shell benutzt.
Ein Info-Account kann mit folgender Regel zum Leben erweckt werden. Mails von anderen Mailsystemen sollen natürlich nicht beantwortet werden, genauso wie Mails, die bereits von diesem Programm erzeugt wurden. Daher werden zu Beginn der Regel einige Fälle ausgeschlossen.
:0
* !^FROM_DAEMON
* !^Delivered-To: info@foobar.org
| (formail -r -t -A"Precedence: junk" \
-A"Delivered-To: info@foobar.org"; \
cat $HOME/info.txt) | $SENDMAIL $SENDMAILFLAGS -t
| |
| Ein einfacher Auto-Responder | |
Ein Bonus von procmail besteht darin, mit einem regulären Ausdrücke
übereinstimmenden Text in einer Variablen zu speichern, die
anschließend weiterverarbeitet werden kann. Wenn "\/" in einem
regulären Ausdruck vorkommt, steht anschließend der übereinstimmende
Text, der auf das Symbol folgt, in der Variablen MATCH.
In einigen Beispielen wurde bewußt die zusätzliche Header-Zeile X-Loop verwendet. Dieser Header wird teilweise bei automatisch generierten oder weitergeleiten Mails verwendet. Diese Zeile läßt sich dadurch zur Bestimmung der Mailbox verwenden. Um daraus den Namen der Liste bzw. Mailbox zu ermitteln, muß die Zeile aufgeteilt werden.
Dabei wird ein Teil des übereinstimmenden Textes in die Variable MATCH übernommen und anschließend gekürzt. Die bisher als rc.split bezeichnete Routine sieht dann wie folgt aus:
:0
* ^X-Loop: .*\/[a-z0-9][^ ]*@
{
MBOX=`echo $MATCH|sed 's/@.*//'`
:0
$MBOX
}
| |
| Speichern des Ergebnisses vom Pattern-Matching | |
Wer viele Mailing-Listen abonniert hat, wird feststellen, daß damit jedoch längst nicht alle Listen gefiltert werden. SmartList als Listserver fügt z.B. folgenden Header an eine Mail:
X-Mailing-List:archive/latest/5597
Wird Majordomo als Listserver eingesetzt, dann würde folgende Zeile generiert werden:
Sender: owner-spliff-users@lists.spliff.org
Der auf Qmail aufbauende Listserver ezmlm erzeugt sogar eine völlig andere Zeile:
Delivered-To: mailing list spliff-users@lists.spliff.org
Damit rc.split wie gewünscht funktioniert, muß aus diesen Zeilen eine entsprechende X-Loop-Zeile generiert werden. Hier macht man sich wieder die regulären Ausdrucke und If-Then-Elsif-Else zunutze wie der folgende Block zeigt.
:0
* !^X-Loop:
{
:0 fhw
* ^X-Mailing-List: .*\/[a-z][a-z0-9\.\-]*@[a-z0-9\.\-]*
| formail -A "X-Loop: $MATCH"
:0 fhwE
* Delivered-To: mailing list \/[a-z][a-z0-9\.\-]*@[a-z0-9\.\-]*
| formail -A "X-Loop: $MATCH"
:0 fhwE
* ^Sender: owner-\/[a-z][a-z0-9\.\-]*@[a-z0-9\.\-]*
| formail -A "X-Loop: $MATCH"
}
| |
| Automatisches Sortieren von Mailing-Listen | |
Durch das Flag "E" werden die beiden letzten Teil-Regeln nur dann
ausgeführt, wenn die vorherigen nicht zum Zuge kamen.
Eigene Mails kennzeichnen
In einer großen Menge an Mails ist es oftmals schwer, die Mails zu erkennen, die an einen persönlich gerichtet sind. Wenn einem Bekannte schreiben, oder ein "interessanter" Betreff gewählt wurde, entdeckt man sie noch. Was ist jedoch, wenn unbekannte Leute eine Mail schreiben und keinen "interessanten" Betreff wählen?
Das Mailprogramm Mutt kann angewiesen werden, bestimmte Mails mit einem Ausrufezeichen im Index (flagged) darzustellen. So lassen sie sich beim Durchblättern schneller finden. Zusätzlich kann die Anzeige auf diese Mails beschränkt werden (mit "l" (für limit) und "~F"). Wenn man dafür sorgt, daß nur Mails, die explizit an einen selbst adressiert sind, derart hervorgehoben werden, dann lassen sie sich schneller als bisher entdecken und bearbeiten.
Die procmail-Regel, die dieses erledigt, sollten Sie inzwischen selbst
entwickeln können. Als abschließendes Beispiel sei daher auf den
etwas komplexeren regulären Ausdruck hingewiesen.
:0 fhw * ! ^FROM_DAEMON * ^TO.*((martin\.)?schulze|joey)@((.*\.)?infodrom\.(north\.de|org)) | formail -i "X-Status: F" | |
| Markieren von persönlichen Mails | |
Ausführliche Dokumentation befindet sich in den dem Programm
beiliegenden Manpages procmailrc(5), procmailex(5) und procmailsc(5).
Die umfangreichste Anwendung von procmail ist der Listserver
SmartList. Er ist komplett in procmail geschrieben. Sie finden ihn
im gleichen Verzeichnis wie das procmail-Paket.
Procmail-Regeln für viele Mailing-Listen.