int
inmsgset(Msgset *ms, uint id)
{
for(; ms; ms = ms->next)
if(ms->from <= id && ms->to >= id)
return 1;
return 0;
}
/*
* we can't rely on uids being in order, but short-circuting saves us
* very little. we have a few tens of thousands of messages at most.
* also use the msg list as the outer loop to avoid 1:5,3:7 returning
* duplicates. this is allowed, but silly. and could be a problem for
* internal uses that aren't idempotent, like (re)moving messages.
*/
static int
formsgsu(Box *box, Msgset *s, uint max, int (*f)(Box*, Msg*, int, void*), void *rock)
{
int ok;
Msg *m;
Msgset *ms;
ok = 1;
for(m = box->msgs; m != nil && m->seq <= max; m = m->next)
for(ms = s; ms != nil; ms = ms->next)
if(m->uid >= ms->from && m->uid <= ms->to){
if(!f(box, m, 1, rock))
ok = 0;
break;
}
return ok;
}
int
formsgsi(Box *box, Msgset *ms, uint max, int (*f)(Box*, Msg*, int, void*), void *rock)
{
int ok, rok;
uint id;
Msg *m;
ok = 1;
for(; ms != nil; ms = ms->next){
id = ms->from;
rok = 0;
for(m = box->msgs; m != nil && m->seq <= max; m = m->next){
if(m->seq > id)
break; /* optimization */
if(m->seq == id){
if(!f(box, m, 0, rock))
ok = 0;
if(id >= ms->to){
rok = 1;
break; /* optimization */
}
if(ms->to == ~0UL)
rok = 1;
id++;
}
}
if(!rok)
ok = 0;
}
return ok;
}
/*
* iterated over all of the items in the message set.
* errors are accumulated, but processing continues.
* if uids, then ignore non-existent messages.
* otherwise, that's an error. additional note from the
* rfc:
*
* “Servers MAY coalesce overlaps and/or execute the
* sequence in any order.”
*/
int
formsgs(Box *box, Msgset *ms, uint max, int uids, int (*f)(Box*, Msg*, int, void*), void *rock)
{
if(uids)
return formsgsu(box, ms, max, f, rock);
else
return formsgsi(box, ms, max, f, rock);
}
Store*
mkstore(int sign, int op, int flags)
{
Store *st;