#include "imap4d.h"
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;
st = binalloc(&parsebin, sizeof *st, 1);
if(st == nil)
parseerr("out of memory");
st->sign = sign;
st->op = op;
st->flags = flags;
return st;
}
Fetch *
mkfetch(int op, Fetch *next)
{
Fetch *f;
f = binalloc(&parsebin, sizeof *f, 1);
if(f == nil)
parseerr("out of memory");
f->op = op;
f->next = next;
return f;
}
Fetch*
revfetch(Fetch *f)
{
Fetch *last, *next;
last = nil;
for(; f != nil; f = next){
next = f->next;
f->next = last;
last = f;
}
return last;
}
Slist*
mkslist(char *s, Slist *next)
{
Slist *sl;
sl = binalloc(&parsebin, sizeof *sl, 0);
if(sl == nil)
parseerr("out of memory");
sl->s = s;
sl->next = next;
return sl;
}
Slist*
revslist(Slist *sl)
{
Slist *last, *next;
last = nil;
for(; sl != nil; sl = next){
next = sl->next;
sl->next = last;
last = sl;
}
return last;
}
int
Bnlist(Biobuf *b, Nlist *nl, char *sep)
{
char *s;
int n;
s = "";
n = 0;
for(; nl != nil; nl = nl->next){
n += Bprint(b, "%s%ud", s, nl->n);
s = sep;
}
return n;
}
int
Bslist(Biobuf *b, Slist *sl, char *sep)
{
char *s;
int n;
s = "";
n = 0;
for(; sl != nil; sl = sl->next){
n += Bprint(b, "%s%Z", s, sl->s);
s = sep;
}
return n;
}
|