[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Phpgroupware-developers] welcome to Sieve, summary attached
From: |
Tony (Angles) Puglisi |
Subject: |
[Phpgroupware-developers] welcome to Sieve, summary attached |
Date: |
Sun, 25 Nov 2001 10:59:30 +0000 |
Seems my carefully placed tabs and spaces disappeared (damn email app, oh sh**,
I
wrote some of it) in my summary I pasted in my last email :(
So I attached an html doc which just has pre tags to retain the spacing.
--
that's "angle" as in geometry
BEGIN SUMMARY: (you may wish to use the "view unformatted" option for this)
===== String Comparison =====
Three kinds
:is exact match
:contains substring match
:comparator "i;ascii-casemap" case-insensitive comparison
(which treats uppercase and lowercase characters in
the ASCII subset of UTF-8 as the same)
:comparator "i;octet" case-sensitive comparison
(simply compares octets)
NOTES:
- default comparator if unspecified is "i;ascii-casemap"
- when specifying a name of a header line (ex. "From"),
the comparator is always "i;ascii-casemap" case insensitive
- Comparators other than i;octet and i;ascii-casemap must
be declared with require, as they are extensions.
:matches wildcard glob-style match
using the characters "*" and "?". "*" matches zero or more
characters, and "?" matches a single character.
ANGLES PLANNED EXTNSIONS:
:ereg php POSIX regex
:preg php Perl regex
===== Addresses Comparisons =====
:localpart acts on the local-part (left-side of the @ sign)
:domain acts on the domain part (right-side of the @ sign)
:all acts on the whole address
===== Blocks =====
Blocks are sets of commands enclosed within curly braces. Blocks are
supplied to commands so that the commands can implement control
commands.
A control structure is a command that happens to take a test and a
block as one of its arguments; depending on the result of the test
supplied as another argument, it runs the code in the block some
number of times.
With the commands supplied in this memo, there are no loops. The
control structures supplied--if, elsif, and else--run a block either
once or not at all. So there are two arguments, the test and the
block.
===== Control Structures: If, Require, Stop =====
Syntax: if
Syntax: elsif
Syntax: else
There is no sub if-then blocks, just linear if--else(if)*--(end)
Syntax: stop
The "stop" action ends all processing. If no actions have been
executed, then the keep action is taken.
Syntax: require
The require command, if present, MUST be used before anything other
than a require can be used. An error occurs if a require appears
after a command other than require.
Example: require ["fileinto", "reject"];
Example: require "fileinto";
require "vacation";
===== Action Commands =====
Five available: keep, fileinto, redirect, reject, discard
Syntax: keep =========================================
The "keep" action is whatever action is taken in lieu of all other
actions, if no filtering happens at all; generally, this simply means
to file the message into the user's main mailbox. This command
provides a way to execute this action without needing to know the
name of the user's main mailbox, providing a way to call it without
needing to understand the user's setup, or the underlying mail
system.
Syntax: fileinto =========================================
The "fileinto" action delivers the message into the specified folder.
Implementations SHOULD support fileinto, but in some environments
this may be impossible.
The capability string for use with the require command is "fileinto".
In the following script, message A is filed into folder
"INBOX.harassment".
Example: require "fileinto";
if header :contains ["from"] "coyote" {
fileinto "INBOX.harassment";
}
Syntax: redirect =========================================
The "redirect" action is used to send the message to another user at
a supplied address, as a mail forwarding feature does. The
"redirect" action makes no changes to the message body or existing
headers, but it may add new headers. The "redirect" modifies the
envelope recipient.
The redirect command performs an MTA-style "forward"--that is, what
you get from a .forward file using sendmail under UNIX. The address
on the SMTP envelope is replaced with the one on the redirect command
and the message is sent back out. (This is not an MUA-style forward,
which creates a new message with a different sender and message ID,
wrapping the old message in a new one.)
A simple script can be used for redirecting all mail:
Example: redirect "address@hidden";
Implementations SHOULD take measures to implement loop control,
possibly including adding headers to the message or counting received
headers. If an implementation detects a loop, it causes an error.
Syntax: reject =========================================
The optional "reject" action refuses delivery of a message by sending
back an [MDN] to the sender. It resends the message to the sender,
wrapping it in a "reject" form, noting that it was rejected by the
recipient. In the following script, message A is rejected and
returned to the sender.
Example: if header :contains "from" "address@hidden" {
reject "I am not taking mail from you, and I don't want
your birdseed, either!";
}
A reject message MUST take the form of a failure MDN as specified by
[MDN]. The human-readable portion of the message, the first
component of the MDN, contains the human readable message describing
the error, and it SHOULD contain additional text alerting the
original sender that mail was refused by a filter. This part of the
MDN might appear as follows:
------------------------------------------------------------
Message was refused by recipient's mail filtering program. Reason
given was as follows:
I am not taking mail from you, and I don't want your birdseed,
either!
------------------------------------------------------------
The MDN action-value field as defined in the MDN specification MUST
be "deleted" and MUST have the MDN-sent-automatically and automatic-
action modes set.
Because some implementations can not or will not implement the reject
command, it is optional. The capability string to be used with the
require command is "reject".
Syntax: discard =========================================
Discard is used to silently throw away the message. It does so by
simply canceling the implicit keep. If discard is used with other
actions, the other actions still happen. Discard is compatible with
all other actions. (For instance fileinto+discard is equivalent to
fileinto.)
Discard MUST be silent; that is, it MUST NOT return a non-delivery
notification of any kind ([DSN], [MDN], or otherwise).
In the following script, any mail from "address@hidden" is thrown
out.
Example: if header :contains ["from"] ["address@hidden"] {
discard;
}
While an important part of this language, "discard" has the potential
to create serious problems for users: Students who leave themselves
logged in to an unattended machine in a public computer lab may find
their script changed to just "discard". In order to protect users in
this situation (along with similar situations), implementations MAY
keep messages destroyed by a script for an indefinite period, and MAY
disallow scripts that throw out all mail.
===== Test Commands =====
Tests are used in conditionals to decide which part(s) of the
conditional to execute.
Available tests:
address
allof
anyof
envelope
exists
false
header
not
size
true
Syntax: address [ADDRESS-PART] [COMPARATOR] [MATCH-TYPE]
The address test matches Internet addresses in structured headers
that contain addresses. It returns true if any header contains any
key in the specified part of the address, as modified by the
comparator and the match keyword.
Syntax: allof =========================================
The allof test performs a logical AND on the tests supplied to it.
Example: allof (false, false) => false
allof (false, true) => false
allof (true, true) => true
The allof test takes as its argument a test-list.
Syntax: anyof =========================================
The anyof test performs a logical OR on the tests supplied to it.
Example: anyof (false, false) => false
anyof (false, true) => true
anyof (true, true) => true
Syntax: envelope [COMPARATOR] [ADDRESS-PART] [MATCH-TYPE]
The "envelope" test is true if the specified part of the SMTP (or
equivalent) envelope matches the specified key.
If one of the envelope-part strings is (case insensitive) "from",
then matching occurs against the FROM address used in the SMTP MAIL
command.
NOTE (ANGLES):
I THINK THIS IS ONLY AVAILABLE IN CERTAIN SITUATIONS,
SUCH AS DURING AN SMTP TRANSACTION, THIS IS TH ONLY
TIME WHEN THIS SPECIFIC "RCPT TO" DATUM IS EXPOSED,
I.E. A CLIENT FEEDING AN OUTGOING MESSAGE TO A SMTP SERVER,
PERHAPS OTHER OCCASIONS SUCH AS DURING SMTP DESTINATION
FINAL DELIVERY. I MAY BE WORNG, THOUGH.
Syntax: exists =========================================
The "exists" test is true if the headers listed in the header-names
argument exist within the message. All of the headers must exist or
the test is false.
The following example throws out mail that doesn't have a From header
and a Date header.
Example: if not exists ["From","Date"] {
discard;
}
Syntax: false =========================================
The "false" test always evaluates to false.
Syntax: header [COMPARATOR] [MATCH-TYPE] =============
The "header" test evaluates to true if any header name matches any
key. The type of match is specified by the optional match argument,
which defaults to ":is" if not specified, as specified in section
2.6.
Like address and envelope, this test returns true if any combination
of the string-list and key-list arguments match.
If a header listed in the header-names argument exists, it contains
the null key (""). However, if the named header is not present, it
does not contain the null key. So if a message contained the header
X-Caffeine: C8H10N4O2
these tests on that header evaluate as follows:
header :is ["X-Caffeine"] [""] => false
header :contains ["X-Caffeine"] [""] => true
Syntax: not =========================================
The "not" test takes some other test as an argument, and yields the
opposite result. "not false" evaluates to "true" and "not true"
evaluates to "false".
Syntax: size <":over" / ":under"> =============================
The "size" test deals with the size of a message. It takes either a
tagged argument of ":over" or ":under", followed by a number
representing the size of the message.
If the argument is ":over", and the size of the message is greater
than the number provided, the test is true; otherwise, it is false.
If the argument is ":under", and the size of the message is less than
the number provided, the test is true; otherwise, it is false.
Exactly one of ":over" or ":under" must be specified, and anything
else is an error.
The size of a message is defined to be the number of octets from the
initial header until the last character in the message body.
Note that for a message that is exactly 4,000 octets, the message is
neither ":over" 4000 octets or ":under" 4000 octets.
Syntax: true =========================================
The "true" test always evaluates to true.
====== Extended Example ======
The following is an extended example of a Sieve script. Note that it
does not make use of the implicit keep.
#
# Example Sieve Filter
# Declare any optional features or extension used by the script
#
require ["fileinto", "reject"];
#
# Reject any large messages (note that the four leading dots get
# "stuffed" to three)
#
if size :over 1M
{
reject text:
Please do not send me large attachments.
Put your file on a server and send me the URL.
Thank you.
.... Fred
.
;
stop;
}
#
# Handle messages from known mailing lists
# Move messages from IETF filter discussion list to filter folder
#
if header :is "Sender" "address@hidden"
{
fileinto "filter"; # move to "filter" folder
}
#
# Keep all messages to or from people in my company
#
elsif address :domain :is ["From", "To"] "example.com"
{
keep; # keep in "In" folder
}
#
# Try and catch unsolicited email. If a message is not to me,
# or it contains a subject known to be spam, file it away.
#
elsif anyof (not address :all :contains
["To", "Cc", "Bcc"] "address@hidden",
header :matches "subject"
["*make*money*fast*", "*university*dipl*mas*"])
{
# If message header does not contain my address,
# it's from a list.
fileinto "spam"; # move to "spam" folder
}
else
{
# Move all other (non-company) mail to "personal"
# folder.
fileinto "personal";
}
====== Example: hillen-sieve-script-001.txt ======
require "fileinto";
if header :is "X-Mailinglist" "suse-linux" {
fileinto "INBOX.Listen.suse-linux";}
elsif header :contains "Mailing-List" "reiserfs" {
fileinto "INBOX.Listen.reiserfs";}
elsif address :contains :all ["to", "cc", "bcc"] "free-clim" {
fileinto "INBOX.Listen.free-clim";}
elsif header :contains "List-Id" "gnupg-users.gnupg.org" {
fileinto "INBOX.Listen.gnupg";}
elsif header :is "X-loop" "isdn4linux" {
fileinto "INBOX.Listen.isdn4linux";}
elsif header :contains "Mailing-list" "address@hidden"{
fileinto "INBOX.Listen.qmail";}
elsif allof (header :contains "Sender" "address@hidden",
address :contains :localpart ["to", "cc", "bcc"] "info-cyrus"){
fileinto "INBOX.Listen.info-cyrus";}
elsif header :contains "Sender" "address@hidden"{
fileinto "INBOX.Listen.ntbugtraq";}
elsif header :is "list-id" ""{
fileinto "INBOX.Listen.sieve";}
elsif header :contains "From" "address@hidden"{
fileinto "INBOX.Newsletter.securityportal";}
elsif address :contains :all ["from"] "address@hidden"{
fileinto "INBOX.Newsletter.ebay";}
elsif address :contains :all ["to", "cc", "bcc"] "address@hidden"{
fileinto "INBOX.Listen.allegro-cl";}
elsif address :contains :all ["to", "cc", "bcc"] "address@hidden"{
fileinto "INBOX.Listen.plob";}
else {
fileinto "INBOX";
====== Example: maro-sieve-script-001.txt ======
##############################################
# Submitted by Tony Maro
# http://www.maro.net/tony
# Use and abuse this script as you will
# I'm not responsible for what it does...
#
# Save this script in your home directory.
# Install this script with the following command,
# replacing "thisfile" and "yourname" with the appropriate
# information:
#
# installsieve -i thisfile -m PLAIN -u yourname localhost
#
#
require "fileinto";
require "reject";
#
# Circle MUD mailing list list
# All mail from the list has "[CIRCLE]" in the subject
# Place all these in the "Circle List" folder
# I could filter on the mail list senders e-mail as it's always
# the same, but this way I even catch personal replies that come
# directly from a user to me
if header :contains "Subject" "[CIRCLE]" {
fileinto "INBOX.Circle List";
}
#
# "shockwave" e-mail virus - just reject it
#
if header :contains "Subject" "A great Shockwave flash movie" {
reject "Possible virus? Check your system!";
}
#
# Get a lot of junk from dial-up uu.net accounts
# Make sure you create a Junk folder under your INBOX
# I like this one because it catches them even if they
# relay their crap through some international open
# mail relay
#
if header :contains "Received" ".da.uu.net" {
fileinto "INBOX.Junk";
}
#
# If the mail is listed as TO someone at bigfoot.com
# Then just reject it because it's spam (my experience anyway)
#
if header :contains "To:" "@bigfoot.com" {
reject "Yeah, right. Bugoff, hosier!";
}
#
# If the mail is not directed to me put in the junk folder
# be sure to replace address@hidden with the
# appropriate information
# Took me a while to figure out how to do NOT statements... :-}
#
if anyof ( not address :all :contains ["To", "Cc", "Bcc"] "address@hidden" ) {
fileinto "INBOX.Junk";
}
#
# Everything that makes it to here ends up in the INBOX
########################################################
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Phpgroupware-developers] welcome to Sieve, summary attached,
Tony (Angles) Puglisi <=