-$Cambridge: exim/doc/doc-txt/README.SIEVE,v 1.3 2005/03/29 15:21:57 ph10 Exp $
+$Cambridge: exim/doc/doc-txt/README.SIEVE,v 1.4 2005/05/03 10:02:27 ph10 Exp $
Notes on the Sieve implementation for Exim
The Exim Sieve implementation offers the core as defined by RFC 3028, the
"envelope" (RFC 3028), the "fileinto" (RFC 3028), the "copy" (RFC 3894)
-and the "vacation" (draft-showalter-sieve-vacation-05.txt) extension,
+and the "vacation" (draft-ietf-sieve-vacation-01.txt) extension,
the "i;ascii-numeric" comparator, but not the "reject" extension.
Exim does not support MDMs, so adding it just to the sieve filter makes
little sense.
vacation-command = "vacation" { vacation-options } <reason: string>
vacation-options = [":days" number]
- [":addresses" string-list]
[":subject" string]
+ [":from" string]
+ [":addresses" string-list]
[":mime"]
+ [":handle" string]
command =/ vacation-command
Semantics Of ":mime"
-RFC 3028 does not specify how strings using MIME parts are used to compose
-messages. The vacation draft refers to RFC 3028 and does not specify it
-either. As a result, different implementations generate different mails.
-The Exim Sieve implementation splits the reason into header and body.
-It adds the header to the mail header and uses the body as mail body.
-Be aware, that other imlementations compose a multipart structure with
-the reason as only part. Both conform to the specification (or lack
-thereof).
+The draft does not specify how strings using MIME entities are used
+to compose messages. As a result, different implementations generate
+different mails. The Exim Sieve implementation splits the reason into
+header and body. It adds the header to the mail header and uses the body
+as mail body. Be aware, that other imlementations compose a multipart
+structure with the reason as only part. Both conform to the specification
+(or lack thereof).
Semantics Of Not Using ":mime"
the user or to declare spam as legitimate mail by proving to
use opt-in. The draft specifies to use "Re: " in front of the
subject, but this implementation uses "Auto: ", as suggested in
-the current draft concerning automatic mail responses.
+RFC 3834, section 3.1.5.
Rate Limiting Responses
-This implementation hashes the reason, specified subject, ":mime"
-option and ":addresses" option and uses the hex string representation
-as filename within the "sieve_vacation_directory" to store the recipient
-addresses for this vacation parameter set.
+In absence of a handle, this implementation hashes the reason,
+":subject" option, ":mime" option and ":from" option and uses the hex
+string representation as filename within the "sieve_vacation_directory"
+to store the recipient addresses for this vacation parameter set.
The draft specifies that sites may define a minimum ":days" value than 1.
This implementation uses 1. The maximum value MUST greater than 7,
-/* $Cambridge: exim/src/src/sieve.c,v 1.10 2005/04/07 10:02:02 ph10 Exp $ */
+/* $Cambridge: exim/src/src/sieve.c,v 1.11 2005/05/03 10:02:27 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
/*
vacation-command = "vacation" { vacation-options } <reason: string> ";"
vacation-options = [":days" number]
- [":addresses" string-list]
[":subject" string]
+ [":from" string]
+ [":addresses" string-list]
[":mime"]
+ [":handle" string]
*/
int m;
unsigned long days;
- struct String *addresses;
struct String subject;
+ struct String from;
+ struct String *addresses;
int reason_is_mime;
string_item *aliases;
+ struct String handle;
struct String reason;
if (!filter->require_vacation)
filter->vacation_ran=1;
}
days=VACATION_MIN_DAYS>7 ? VACATION_MIN_DAYS : 7;
- addresses=(struct String*)0;
subject.character=(uschar*)0;
subject.length=-1;
+ from.character=(uschar*)0;
+ from.length=-1;
+ addresses=(struct String*)0;
aliases=NULL;
reason_is_mime=0;
+ handle.character=(uschar*)0;
+ handle.length=-1;
for (;;)
{
if (parse_white(filter)==-1) return -1;
if (days<VACATION_MIN_DAYS) days=VACATION_MIN_DAYS;
else if (days>VACATION_MAX_DAYS) days=VACATION_MAX_DAYS;
}
+ else if (parse_identifier(filter,CUS ":subject")==1)
+ {
+ if (parse_white(filter)==-1) return -1;
+ if ((m=parse_string(filter,&subject))!=1)
+ {
+ if (m==0) filter->errmsg=CUS "subject string expected";
+ return -1;
+ }
+ }
+ else if (parse_identifier(filter,CUS ":from")==1)
+ {
+ int start, end, domain;
+ uschar *error,*ss;
+
+ if (parse_white(filter)==-1) return -1;
+ if ((m=parse_string(filter,&from))!=1)
+ {
+ if (m==0) filter->errmsg=CUS "from string expected";
+ return -1;
+ }
+ if (from.length>0)
+ {
+ ss = parse_extract_address(from.character, &error, &start, &end, &domain,
+ FALSE);
+ if (ss == NULL)
+ {
+ filter->errmsg=string_sprintf("malformed address \"%s\" in "
+ "Sieve filter: %s", from.character, error);
+ return -1;
+ }
+ }
+ else
+ {
+ filter->errmsg=CUS "empty :from address in Sieve filter";
+ return -1;
+ }
+ }
else if (parse_identifier(filter,CUS ":addresses")==1)
{
struct String *a;
aliases=new;
}
}
- else if (parse_identifier(filter,CUS ":subject")==1)
+ else if (parse_identifier(filter,CUS ":mime")==1)
+ reason_is_mime=1;
+ else if (parse_identifier(filter,CUS ":handle")==1)
{
if (parse_white(filter)==-1) return -1;
- if ((m=parse_string(filter,&subject))!=1)
+ if ((m=parse_string(filter,&from))!=1)
{
- if (m==0) filter->errmsg=CUS "subject string expected";
+ if (m==0) filter->errmsg=CUS "handle string expected";
return -1;
}
}
- else if (parse_identifier(filter,CUS ":mime")==1)
- reason_is_mime=1;
else break;
}
if (parse_white(filter)==-1) return -1;
uschar *buffer;
int buffer_capacity;
struct String key;
- struct String *a;
md5 base;
uschar digest[16];
uschar hexdigest[33];
key.character=(uschar*)0;
key.length=0;
capacity=0;
- if (subject.length!=-1) key.character=string_cat(key.character,&capacity,&key.length,subject.character,subject.length);
- key.character=string_cat(key.character,&capacity,&key.length,reason_is_mime?US"1":US"0",1);
- key.character=string_cat(key.character,&capacity,&key.length,reason.character,reason.length);
- if (addresses!=(struct String*)0) for (a=addresses; a->length!=-1; ++a)
+ if (handle.length==-1)
{
- key.character=string_cat(key.character,&capacity,&key.length,US":",1);
- key.character=string_cat(key.character,&capacity,&key.length,a->character,a->length);
+ if (subject.length!=-1) key.character=string_cat(key.character,&capacity,&key.length,subject.character,subject.length);
+ if (from.length!=-1) key.character=string_cat(key.character,&capacity,&key.length,from.character,from.length);
+ key.character=string_cat(key.character,&capacity,&key.length,reason_is_mime?US"1":US"0",1);
+ key.character=string_cat(key.character,&capacity,&key.length,reason.character,reason.length);
}
+ else
+ key=handle;
md5_start(&base);
md5_end(&base, key.character, key.length, digest);
for (i = 0; i < 16; i++) sprintf(CS (hexdigest+2*i), "%02X", digest[i]);
addr->reply = store_get(sizeof(reply_item));
memset(addr->reply,0,sizeof(reply_item)); /* XXX */
addr->reply->to = string_copy(sender_address);
- addr->reply->from = expand_string(US"$local_part@$domain");
+ if (from.length==-1)
+ addr->reply->from = expand_string(US"$local_part@$domain");
+ else
+ addr->reply->from = from.character;
/* Allocation is larger than neccessary, but enough even for split MIME words */
buffer_capacity=16+4*subject.length;
buffer=store_get(buffer_capacity);