Der Syntax wird grundlegend im RFC5228 erklärt. Sieve kann mit Extentions erweitert werden. Die Seite mit den von Dovecot unterstützten Extentions und die Übersicht von IANA verlinken zu den entsprechenden RFCs.
Grob vereinfacht ist der Code folgender Maßen strukturiert:
require ["extension1", "extension2"]; if <test> <:match_type> <:optional_argument> <element_to_test> <string_to_match> { action1; action2; ... }
# comment line /* comment block over several lines like in C */
Der Editor unseres Webmails nutzt Kommentare um den einzelnen Regeln Namen zu geben
# rule:[rule name] if <test> { action; }
Wie in anderen Sprachen kann man mit if Fallunterscheidungen durchführen. Sieve geht bis zum Ende jede If-Regel durch und wendet jede zutreffende Regel an. Um ungewollte Dopperlverarbeitungen zu verhindern kann man elseif oder das stop Kommando verwenden. Letzteres beendet die weitere Verarbeitung der Sieve-Regeln.
if <test> { action; action; } elsif <test> { action; action; } else { action; } # stops the script at this very position if <test> { action; stop; }
Mit Hilfe der String-Liste können alternative Werte, also mit OR verbunden, angegeben werden.
["string1", "string2"]
AND, OR und Negation werden von Sieve als Tests betrachtet, die man mit den anderen Tests kombinieren kann. allof (AND), anyof (OR) und not (Negation) lauten diese Tests. Bei anyof und allof müssen die Tests von runden Klammern umschlossen und durch Kommas getrennt werden. Dies wird Testliste genannt.
if anyof ( test1, test2, test3 ) { action1; action2; }
Dies ist nur ein Ausschnitt mit den gebräuchlichsten Tests. Die Sieve-Extentions bieten weitere Tests.
testet einen beliebig definierbaren header
require ["fileinto", "other_extension"]; # Move mails with a Spamassassin score of 6.0 or more into the "Junk" folder. if header :contains "x-spam-level" "******" { fileinto "Junk"; }
testet nur headers mit Adressfeldern (From: To: Sender:) Im Gegensatz zum Test “header” kann man mit Hilfe von optionalen Argumenten auch nach dem lokalen Teil oder der Domäne gesucht werden. Die optionalen Argumente lauten :domain, :localpart und :all .
if address :is :domain "to" "example.com" { action; }
testet die Envelope header (MAIL FROM: und RCPT TO:) und nutzt genau wie der Test “address” die optionalen Argumente :domain, :localpart oder :all. “envelope” ist bereits ein Test, welcher mit der gleichnamigen Extension “envelope” geladen werden muss. Dazu muss in der ersten Zeile des Scripts mit require diese Erweiterung geladen werden.
require ["envelope", "other_extension"];
testet ob ein spezieller header vorkommt.
ermöglicht Filter anhand der Mailgröße zu setzen. Die zugehörigen Argumente sind :over und :under
if size :over 500K{ action; }
:is führt einen exakten Vergleich durch, Das heisst, die Zeichenkette muss mit dem String exakt übereinstimmen
:contains prüft, ob eine bestimmte Zeichenkette in einem String enthalten ist.
:matches kann beim Vergleich Teile einer Zeichenkette ungeprüft belassen. Mit dem Symbol “*” können mehrere, mit dem Symbol “?” genau ein Zeichen freigestellt werden.
:raw <string_to_find> ist ein spezieller Match-Type des Tests “body” und liefert den body der Email als unveränderten Text.
:text <string_to_find> ist ein spezieller Match-Type des Tests “body” und säubert den body z.B. von HTML-Kommentaren.
Der Command Block wird mit geschweiften Klammern umrahmt und jedes Kommando wird mit einem Strichpunkt abgeschlossen. Folgende Standardaktionen sind möglich, weitere Aktionen kann man per Extensions laden.
bedeutet, dass die Nachricht im Hauptmailboxordner, also der Inbox abgespeichert werden soll. Sieve hat immer ein “implizites keep” damit Emails, die auf keinen Filter ansprechen auf alle Fälle in der Inbox landen.
führt ein Forward zu einer anderen Adresse durch. Ein entsprechendes redirect ohne if-Abfrage kann zur generellen Weiterleitung aller Emails genutzt werden.
redirect "user@sbg.ac.at";
verwirft die Email still und leise.
verschiebt die Email in den gewünschten Mailbox-Ordner. Bei uns ist der Separator für (Sub)Folder ein “/”, wie er auch unter Linux in Pfadangaben genutzt wird. Die Aktion “fileinto” ist im RFC nur empfohlen und wird daher als Extention in der ersten Zeile des Scripts geladen.
require "fileinto"; if address :is :all ["from"] "user@sbg.ac.at" { fileinto "INBOX/mySpecialFriends"; }
Sollte der Ordner noch nicht existieren, wird bei unserem Dovecot Pigeonhole einfach der Ordner erstellt.