phpgroupware-developers
[Top][All Lists]
Advanced

[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
########################################################


reply via email to

[Prev in Thread] Current Thread [Next in Thread]