Subject: Language for conflicting actions

From: Lawrence Greenfield <[email-masked]>
Date: 25 Jan 1999 20:29:34 -0500

I'm opposed to adding more commands to the language that have nearly
identical semantics to fileinto.  Regardless, we're going to have to
deal with multiple fileinto's being executed.

Tied into this discussion is error messages.  One suggestion here at
CMU was to have the Sieve agent modify a header in a default-delivery
message to indicate a problem in a Sieve script...  Another
possibility is to send a DSN to the person.

---
Command Interactions

It is possible for two or more actions to be executed by a script.  A
script MUST NOT perform any action before finishing execution, and
MUST check that the actions are consistent (according the the
following chart).

An implementation MAY choose to support multiple compatible actions.
If so, it should either execute all actions or none (barring error
conditions outside the control of the Sieve interpreter).  If the
implementation cannot execute all actions, it should treat it as a
run-time error.

For instance, an implementation may choose to support "redirect" and
"fileinto" together, but not multiple "fileinto" actions.  In that
case, any script that attempts multiple "fileinto" actions causes a
run-time error.

	   keep      fileinto    redirect   discard    reject

keep       compat.   compat.     compat.    no         no

fileinto   compat.   compat.     compat.    no         no

redirect   compat.   compat.     compat.    no         no

discard    no        no          no         yes        no

reject     no        no          no         no         no

Two "keep"'s cause a message to be delivered multiple times to the
default location.  Two "fileinto"'s cause a message to be filed into
the specified folders.  Two "redirect"'s cause a message to be
forwarded to multiple addresses.

The implicit keep is only performed when no actions were executed by
the script.

---
Run-time Errors

It is impossible to prevent run-time errors from occuring.
Implementations are encouraged to statically check Sieve scripts
upon submission to minimize the chances of errors during run-time.

Errors may include:
- quota or ACL problems
- incompatible actions
- too many actions (too many redirects by site policy)

If a run-time error occurs, the implementation should attempt to
perform a "keep" (disregarding any other actions) and should send a
message to the user, either via electronic mail or another
communication channel.

---

From: Randall Gellens <[email-masked]>
Date: Mon, 25 Jan 1999 18:20:00 -0800

I'm getting a sinking feeling that we are heading towards a train 
wreck.  Sieve is getting more complicated the longer these 
discussions go on, and that means more problems.

I really thought our prime goal was to specify something simple 
enough to solve a good chunk of the problem and get it standardized 
NOW.

Every argument for adding this tweak or allowing that extra behavior 
hurts the prime goal.  Is this what we want?

> deal with multiple fileinto's being executed.

Please, let's go with something simple to understand and implement. 
To me, that is one FileInto per message. 

If Sieve gets fancy, your script won't run on my servers.  If that's 
OK, why do we need Sieve at all?  Just let each server implement 
whatever script rules it likes.

> possibility is to send a DSN to the person.

I'd rather not discuss error messages at this stage.  Every time this 
has come up before, we have punted.  I still think we can defer this 
until we have base RFC.

> MUST check that the actions are consistent (according the the

When we discussed parsing before executing (to trap syntax errors), 
it was decided that this was a quality of implementation issue, not a 
Sieve requirement.  Why should this be any different?

(My implementation does a full parse before executing anything, but I 
don't hold actions.  I could do so, and it would be really easy for 
things like FileInto where I only honor the last one anyway, but that 
gets complicated when multiple Forwards and such are done.)

> forwarded to multiple addresses.

Now we're getting fancy, and in addition I'm not sure these semantics 
are desirable.  I can see Sieve scripts which execute multiple 
"keep"s, for different tests, with the intent that the message be 
kept, not duplicated.  Of what use is duplicating the message, 
especially into the same mailbox?

We're adding complexity and reducing interoperability and/or 
deployability.  For what gain?

> The implicit keep is only performed when no actions were executed by

So a script that does only a "Reply" causes the message to be 
discarded?  Does a DSN get generated?  Very odd to get a reply and a 
failure DSN for the same message.

> message to the user, either via electronic mail or another

Let's not specify how the user is to be notified.

---

From: Tim Showalter <[email-masked]>
Date: 25 Jan 1999 22:40:45 -0500

> Date: Mon, 25 Jan 1999 18:20:00 -0800
> From: Randall Gellens <[email-masked]>

> hurts the prime goal.  Is this what we want?

I have assumed since the beginning that multiple fileintos were no
problem whatsoever.  I was rather surprised that you don't believe this
is the case.

> To me, that is one FileInto per message. 

It is *not* simple to understand.  We *will* get users asking "Why
doesn't this work?"  If I tell the MTA to do two things and it does one,
how is it easier to understand?

I don't consider the implementation complexity to be that great.

> especially into the same mailbox?

I'm not particularly sure that two "keeps" should deposit the message
into the main mailbox; I don't believe that writing one message to a
mailbox twice should ever actually do that.  But I do believe that
multiple redirects are not much of a problem.

> failure DSN for the same message.

No, a DSN should not be generated.  That's what reject is for.  Is that
not clear in the spec?  (Should I fix it?)

If we're going to have an implicit keep, the only way it's going to make 
sense is if it happens when zero other actions are done.  If you don't
want an implicit keep, do a discard.

-- 
Tim Showalter <[email-masked]>

---

From: Tim Showalter <[email-masked]>
Date: 27 Jan 1999 23:20:17 -0500

> Sieve requirement.  Why should this be any different?

Well, here's the problem.  Reject and forward are mutually exclusive
(or, IMHO, should be, because I have a very hard time with the idea that 
a standards-track document should provide for bogus DSNs.)

If you reject a message, you have to throw it away; the DSN says you
did so.

It was decided some time ago that reject+keep was an absurd thing to do
and should not be allowed, right?

---

From: Tim Showalter <[email-masked]>
Date: 27 Jan 1999 23:22:57 -0500

> Date: 27 Jan 1999 23:20:17 -0500
> From: Tim Showalter <[email-masked]>
> 

Note that I'm not saying you can't run the script before parsing it.
I'm saying you have to queue up actions before doing any.  That's pretty
easy to implement, even if you sprinkle in the evaluation code in with
the parser -- you just save up a list of all the stuff you're gonna do
and sanity check it before running it.

---

From: Randall Gellens <[email-masked]>
Date: Thu, 28 Jan 1999 14:43:20 -0800

> and sanity check it before running it.

You can prevent mutually exclusive actions by keeping a flag as to 
which ones you've done; you don't need to queue them all.  So you 
could parse the script first, for example, then while executing it 
hit a "forward" statement and do it (and set the "forwarded" flag), 
then later on hit a "reject" and issue a run-time error/warning that 
it was ignored.

Saving up a list of everything you're going to do could force an 
implementation to use more memory or have scaling problems, 
potentially.  If a script executes multiple forwards, or replies 
(assuming that is accepted as an extension), the execution agent 
could be forced to dynamically allocate a potentially unbounded 
amount of memory to keep all the actions (including text).  Yes, you 
could get around this by instead keeping pointers to the statements, 
but that's still no business of the spec, I say.

Why should the standard force an implementation?  It seems wrong.

If we want to state that certain actions are mutually exclusive, OK. 
But let's not dictate implementation methods.

---

From: Tim Showalter <[email-masked]>
Date: 28 Jan 1999 18:00:40 -0500

> Date: Thu, 28 Jan 1999 14:43:20 -0800
> From: Randall Gellens <[email-masked]>

> then later on hit a "reject" and issue a run-time error/warning that 

This isn't very good.  The best that you can do is do whatever happens
first, and I don't consider that to be desirable.

> potentially.

I don't buy that at all.  I cannot imagine how a list of actions (which
will typically be one per message and seldom more than five per message)
could cause massive scaling problems even on the largest of central
servers.

The cost of running Sieve in the first place will be orders of magnitude
higher than queueing up actions.

> If a script executes multiple forwards, or replies 
> amount of memory to keep all the actions (including text).

This is not very important, really.  After all, if the number of headers 
is large, an implementation could be forced to allocate a potentially
unbounded amount of space for that, too.  Same goes for length of
the script.

As a server programmer, I don't see an implementation problem here at
all.