Sieve

Fra TermvaktWiki
Gå til: navigasjon, søk

Sieve ("sil" på engelsk) er språket e-postfilteret som brukes på UiOs e-postsystem skrives i. Det blir kjørt hver gang det kommer en ny melding.

For å sette opp et Sieve-filter ved UiO gjør man slik:

  • Start USIT sin emacs /local/bin/emacs og pass på at du jobber i UTF-8
  • Pass på at Emacs er satt opp til å bruke port 4190. Dette gjøres ved å taste M-x customize-group RET sieve-manage RET og oppdater «Sieve Manage Default Port». C-x C-s skal lagre dette for framtiden
  • Start med å laste inn Sieve-bibliotekene. Det gjøres ved å taste M-x load-library og så sieve. Du får da melding om Loading sieve...done
  • Kjør så M-x sieve-manage. Du blir da spurt om server, og denne finner du ved å besøke brukerinfo på verdensveven eller email info brukernavn i bofh. For meg så er dette
jbofh> email info martiso
Account:          martiso
Mail server:      cyrus03 (cyrus_IMAP)

Altså er det cyrus03 jeg skal skrive inn som server. Etter dette blir du spurt etter brukernavn og passord, og dette er det vanlige brukernavnet og passordet ved UiO. Velg så yStore password for this session

  • Du har nå fått opp en ny meny i emacs. Den ser ca. ut som dette:
Server  : cyrus03:4190
3 scripts on server, press RET on a script name edits it, or
press RET on <new script> to create a new script.
        <new script>
        sievefilter2.txt<3>
 ACTIVE sievefilter2.txt
        phpscript

Hvis du har laget filter i webmail allerede, vil dette hete phpscript. Du kan åpne det ved å trykke på enter når phpscript er markert. Hvis du har lyst til å endre filteret ditt bare litt, kan det enkleste være å redigere denne fila. Det som er viktig å legge merke til er at webmail-editoren kun leser de egenproduserte kommentarene i denne fila og presenterer disse som filteret hvis det både er kommentarer og kommandoer. Det er derfor lurt å slette disse merkelige kommentarene, ellers vil webmail presentere et filter, mens du faktisk har et annet filter.

Hvis du ikke har et filter fra før av, vil du kun se <new script>. Du kan da enten velge å redigere direkte ved å trykke enter på <new script> eller du kan åpne en ny fil (C-x C-f filnavn.siv). Jeg synes det er tryggest å lagre på hjemmeområdet en gang i blant. Jeg tar derfor utgangspunkt i at det blir laget en fil på hjemmeområdet som heter sievefilter.siv.

Hvis du har et filter du ønsker å laste opp (f.eks. sievefilter.siv) og gjøre aktivt, gjør du på følgende måte: Du starter sieve-manage, og logger deg på tjeneren. Åpne fila du ønsker å laste opp på vanlig måte (C-x C-f). Trykk M-x og skriv inn sieve-upload. Filteret vil da bli testet, og hvis det er syntaktisk OK, blir det lasta opp. Hvis det er feil i skriptet, får du beskjed om det. Rett opp og last opp på ny.

Du har nå lasta opp filteret, men det er enda ikke gjort aktivt. For å gjøre det aktivt gå tilbake til vinduet *sieve*. Her vil det nye skriptet kanskje ikke ha dukket opp enda, men du får det fram med M-x sieve-refresh-scriptlist. Når du ser det nye skriptet ditt, marker det, og kjør M-x sieve-activate. Du har nå lasta opp og aktivert det nye skriptet, og det vil brukes hver gang det kommer nye meldinger til deg.

  • Hvordan ser så et Sieve-filter ut?

Les dokumentasjonen eller se mitt eksempel på http://termvakt.uio.no/filer/sievefilter.txt

Siden få gidder å lese standarden så kan jeg komme med litt info. Se først på eksempelfila, og du vil se at starten av fila ser slik ut:

 require ["fileinto","reject","vacation","imapflags","relational","comparator-i;ascii-numeric","regex","notify"]; 

Denne linja brukes for å få med kommandoer man trenger, og webmail tar med alt som den kan bruke. Egentlig klarer du deg med langt færre. Ordet require er en såkalt control structure. Andre kontrollstrukturer er if og stop.

Videre ser fila slik ut:

if header :contains "X-UiO-Spam-score" "sssss" 
{
  fileinto "INBOX.spam";
  stop;
}

Den første linja er en if-test. Første argument (header) til kontrollstrukturen if er en test som sier hvor i meldingen vi skal sjekke. En liten oversikt over mulige tester:

address: "address" vil tolke headerfeltene From, To, Cc, Bcc, Sender, Resent-From og Resent-To slik at vi kun står igjen med selve e-postadressene (altså hvis det i To-feltet står "termvakt <termvakt@matnat.uio.no>" vil address plukke ut "termvakt@matnat.uio.no" for å gjøre sammenligningen).
allof: Logisk AND, forklart nedenfor
anyof: Logisk OR, forklart nedenfor
envelope: Sjekker adressen som står utenpå konvolutten, denne kan være helt forskjellig fra det som står i To og From-feltet i selve meldingen. Dessverre blir f.eks. "martin.sollien" skrevet om til brukernavnet "martiso" på vegen gjennom e-postsystemet, men bortsett fra dette er konvoluttadressen uforandret. Adressen i To blir alltid skrevet om til din offisielle adresse, så hvis du ønsker å sortere ut e-post sendt til dine gamle adresser, må du bruke envelope. Krever require "envelope".
exists: Sjekker om headeren er finnes i meldingen. Et lite eksempel som vil kaste meldinger som ikke har definert avsender: if not exists "From" { discard; }
header: Angir at vi skal teste en header for innhold.
not: Logisk NOT, tar en av de andre testene som argument og inverterer resultatet.
size: Tester på størrelsen til mailen. De to argumentene den kan ha er :over og :under. Kan bruke bokstavene K (=2^10), M (=2^20) og G (=2^30) for å angi størrelse, f.eks. 4M. For eksempel se i RFC3028.


Det andre argumentet, ":contains" er et tagged argument. I dette tilfellet sier det hvordan if-testen skal teste. De fem sammenligningsmåtene man kan bruke er:

:contains: Returnerer sant hvis teststrengen finnes i den angitte headeren (altså om teststrengen er en delstreng av headeren).
:is: Returnerer sant hvis teststrengen og headeren er like.
:matches: Kan lage søkestrenger som inneholder vilkårlig tegn (wildcards). Et lite eksempel er if header :matches ["*viagra*", "*make*money*fast*"]. Det to jokertegnene er '?' og '*'. '?' tilsvarer ett tilfeldig tegn, mens '*' angir null eller flere tilfeldige tegn. Hvis du skriver "Re:*", så må strengen starte med "Re:", mens "*Re:*" vil være sann uansett hvor "Re:" står i strengen.
:value: Tester på numeriske verdier, f.eks. tall i subject. Krever require "relational".
:regex: Hvis du ønsker å bruke regulære uttrykk, er dette tingen å bruke. Siden jeg ikke kan dette, kan jeg ikke utdype dette nærmere. Krever require "regex".

Hvis man bruker :contains, :is, :matches eller :regex, er det neste argumentet hvilken header man skal søke i, mens det etter det igjen angir teststrengen.

Det siste argumentet (det som er innafor {} ) er hva som skal skje hvis testen returnerer sant. Her kan man gjøre følgende:

reject "tekst": Meldingen tas ikke i mot, og sendes tilbake til avsender. "Tekst" er det du vil at avsender skal få av feilmelding. Vær forsiktig med denne, da avsenderadressen kan være forfalsket, og da vil du plage en uskyldig tredjepart.
fileinto "mappe": Flytter meldingen til den angitte mappa. Om du gjør flere fileinto til samme mappe, vil du likevel bare få ett eksemplar. Krever require "fileinto".
redirect "adresse": Videresender meldingen til "adresse".
keep: Den legger meldingen i INBOX. Dette er standard på alle meldingene som kommer hvis ingen annen hendelse blir gjort.
discard: Kaster meldingen.
notify: Varsler om at det har kommet ny e-post via f.eks. SMS. Har for tiden ingen effekt ved UiO. Krever require "notify".
vacation: Sender en melding til avsender om at du er utilgjengelig el.l. For de fleste er det bedre å bruke Automatisk svar i UiO-innstillinger i webmail, men hvis du vil ha mer finkornet kontroll, kan du gjøre det her. Se advarsel om reject. Krever require "vacation".

I tillegg så kan man legge inn kontrollstrukturordet stop her. Filteret vil da stoppe, og ikke gjøre de resterende testene.


Så kan vi gjøre det litt mer avansert. Vi har to ord som implementerer logisk AND og OR. Disse er allof og anyof. To eksempler ser du nedenfor:

# Denne testen flytter alle termvaktmail til termvakt-folderen. STOPPER IKKE
if anyof (
  header :contains ["to", "cc"] "termvakt@matnat.uio.no",
  header :contains ["to", "cc"] "lk-alle@usit.uio.no",
  header :contains ["to", "cc"] "stueansvarlige@matnat.uio.no",
  header :contains ["to", "cc"] "termvakt@ifi.uio.no",
  header :contains ["to", "cc"] "termvakter@ifi.uio.no")
{
  fileinto "INBOX.termvakt";
}
# Denne testen flytter meldinger som ser ut som spam til bofh.no til spam-folderen
if allof (
  header :contains ["to", "cc"] "@bofh.no",
  header :contains ["subject"] "viagra")
{
  fileinto "INBOX.spam";
  stop;
}

I tillegg så finnes operatoren not. Den virker som en logisk NOT og inverterer sannhetsverdien av et uttrykk. Et lite eksempel på det:

if not header :contains ["to", "cc"] "viagra" 
{ 
  keep;
}

Når det gjelder kommentarer, så skrives de enten med # og da blir resten av linja kommentert ut, eller så kan man bruke /* */ og alt som står mellom de to sekvensene blir kommentert vekk.

En ting som er viktig å merke seg er det som kalles "String Lists". "String Lists" oppgis inne i '[' og ']' og elementene skilles med ','. Evalueringen er slik at dersom testen er sann med ett eller flere av elementene i listen, så er hele uttrykket sant. Det er brukt flere ganger i eksemplene over, men et lite forklarende eksempel til:

if header :contains ["to", "cc"] ["termvakt@matnat.uio.no", "termvakt@ifi.uio.no"]

er det samme som

if anyof (
  header : contains "to" "termvakt@matnat.uio.no"
  header : contains "cc" "termvakt@matnat.uio.no"
  header : contains "to" "termvakt@ifi.uio.no"
  header : contains "cc" "termvakt@ifi.uio.no")

Det er også viktig å merke seg at ingenting i Sieve skiller mellom store og små bokstaver, heller ikke strengene. Man kan gjøre slik at strengene blir case-sensitive, og det gjøres med å skrive :comparator "i;octet" etter f.eks :contains. Et lite eksempel:

if header :contains :comparator "i;octet" "Subject" "MAKE MONEY FAST" 
{
  discard;
}

Denne testen vil kaste alle meldinger som har emnefelt som "this is a great way to MAKE MONEY FAST", mens den vil ikke slå til på "this is a great way to make money fast".

Så kan vi gjøre ting enda mer avansert. Vi har allerede sett at vi har if som test, men vi har også elsif og else. Et lite eksempel:

if header :is "Sender" "no@rart.no"
{
  fileinto "INBOX.rart";  
}
elsif address :domain :is ["From", "To"] "uio.no"
{
  fileinto "INBOX.uio";
}
else
{
  keep;
}

I denne testen har er det en annen ny ting også, nemlig :domain. Siden vi jobber med e-post, har vi ofte behov for å få tak i det som er til venstre for @ og det som er til høyre for @. Det som er til venstre kan kan få tak i ved å legge til :localpart, mens hvis man skal ha tak i det til høyre (domenet) skriver man bare @@:domain@. Hvis man trenger hele e-postadressen, kan man skrive :all. Dette fungerer for address og envelope. Hvis du er plaget med at du får mye spam til adresser du ikke bruker, kan du f.eks. skrive:

if envelope :domain "To" ["hfstud.uio.no", "ernst.uio.no", "www.ifi.uio.no"]
{
 discard;
}

Siden konvoluttmottaker alltid vil være en av dine gyldige adresser, er det tilstrekkelig å sjekke domenedelen.


Eksterne linker

  • For oppklarende info, sjekk [1]
Personlige verktøy
Navnerom
Varianter
Handlinger
Navigasjon
Kategorier
Programvare
Andre
Translate
Verktøy