Mail: fix infinite deletion loop
When deleting messages that came in just the right order, we would end up stuck in a loop deleting and reinserting a dummy parent, rather than the messages we wanted to remove.
This commit is contained in:
parent
be782ef435
commit
3555843110
1 changed files with 28 additions and 18 deletions
|
@ -260,13 +260,15 @@ addmesg(Mesg *m, int ins)
|
||||||
mbox.mesgsz *= 2;
|
mbox.mesgsz *= 2;
|
||||||
mbox.mesg = erealloc(mbox.mesg, mbox.mesgsz*sizeof(Mesg*));
|
mbox.mesg = erealloc(mbox.mesg, mbox.mesgsz*sizeof(Mesg*));
|
||||||
}
|
}
|
||||||
if(ins)
|
if(ins >= 0){
|
||||||
idx = slotfor(m);
|
if(ins == 0)
|
||||||
else
|
idx = slotfor(m);
|
||||||
idx = mbox.nmesg;
|
else
|
||||||
memmove(&mbox.mesg[idx + 1], &mbox.mesg[idx], (mbox.nmesg - idx)*sizeof(Mesg*));
|
idx = mbox.nmesg;
|
||||||
mbox.mesg[idx] = m;
|
memmove(&mbox.mesg[idx + 1], &mbox.mesg[idx], (mbox.nmesg - idx)*sizeof(Mesg*));
|
||||||
mbox.nmesg++;
|
mbox.mesg[idx] = m;
|
||||||
|
mbox.nmesg++;
|
||||||
|
}
|
||||||
if(m->messageid == nil)
|
if(m->messageid == nil)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -296,7 +298,7 @@ addmesg(Mesg *m, int ins)
|
||||||
}
|
}
|
||||||
|
|
||||||
static Mesg *
|
static Mesg *
|
||||||
placeholder(char *msgid, vlong time, int ins)
|
placeholder(char *msgid, vlong time)
|
||||||
{
|
{
|
||||||
Mesg *m;
|
Mesg *m;
|
||||||
|
|
||||||
|
@ -305,7 +307,6 @@ placeholder(char *msgid, vlong time, int ins)
|
||||||
m->messageid = estrdup(msgid);
|
m->messageid = estrdup(msgid);
|
||||||
m->hash = strhash(msgid);
|
m->hash = strhash(msgid);
|
||||||
m->time = time;
|
m->time = time;
|
||||||
addmesg(m, ins);
|
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -381,8 +382,10 @@ load(char *name, char *digest, int ins)
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
p = lookupid(m->inreplyto);
|
p = lookupid(m->inreplyto);
|
||||||
if(p == nil)
|
if(p == nil){
|
||||||
p = placeholder(m->inreplyto, m->time, ins);
|
p = placeholder(m->inreplyto, m->time);
|
||||||
|
addmesg(m, ins);
|
||||||
|
}
|
||||||
if(!addchild(p, m, d))
|
if(!addchild(p, m, d))
|
||||||
m->state |= Stoplev;
|
m->state |= Stoplev;
|
||||||
return m;
|
return m;
|
||||||
|
@ -656,6 +659,8 @@ relinkmsg(Mesg *p, Mesg *m)
|
||||||
|
|
||||||
/* remove child, preserving order */
|
/* remove child, preserving order */
|
||||||
j = 0;
|
j = 0;
|
||||||
|
if(p == nil || m == nil)
|
||||||
|
return;
|
||||||
for(i = 0; p && i < p->nchild; i++){
|
for(i = 0; p && i < p->nchild; i++){
|
||||||
if(p->child[i] != m)
|
if(p->child[i] != m)
|
||||||
p->child[j++] = p->child[i];
|
p->child[j++] = p->child[i];
|
||||||
|
@ -675,7 +680,7 @@ relinkmsg(Mesg *p, Mesg *m)
|
||||||
static void
|
static void
|
||||||
mbflush(char **, int)
|
mbflush(char **, int)
|
||||||
{
|
{
|
||||||
int i, j, ln, fd;
|
int i, j, ln, fd, dummy;
|
||||||
char *path;
|
char *path;
|
||||||
Mesg *m, *p;
|
Mesg *m, *p;
|
||||||
|
|
||||||
|
@ -687,7 +692,7 @@ mbflush(char **, int)
|
||||||
sysfatal("open mbox: %r");
|
sysfatal("open mbox: %r");
|
||||||
while(i < mbox.nmesg){
|
while(i < mbox.nmesg){
|
||||||
m = mbox.mesg[i];
|
m = mbox.mesg[i];
|
||||||
if((m->state & Sopen) || !(m->flags & (Fdel|Ftodel))){
|
if((m->state & (Sopen|Sdummy)) || !(m->flags & (Fdel|Ftodel))){
|
||||||
i++;
|
i++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -698,18 +703,23 @@ mbflush(char **, int)
|
||||||
fprint(fd, "delete %s %d", mailbox, atoi(m->name));
|
fprint(fd, "delete %s %d", mailbox, atoi(m->name));
|
||||||
|
|
||||||
p = m->parent;
|
p = m->parent;
|
||||||
|
dummy = 0;
|
||||||
removeid(m);
|
removeid(m);
|
||||||
if(p == nil && m->nsub != 0){
|
if(p == nil && m->nsub != 0){
|
||||||
p = placeholder(m->messageid, m->time, 1);
|
p = placeholder(m->messageid, m->time);
|
||||||
p->nsub = m->nsub + 1;
|
p->nsub = m->nsub + 1;
|
||||||
|
addmesg(p, -1);
|
||||||
mbox.mesg[i] = p;
|
mbox.mesg[i] = p;
|
||||||
|
dummy = 1;
|
||||||
}
|
}
|
||||||
if(p != nil)
|
relinkmsg(p, m);
|
||||||
relinkmsg(p, m);
|
|
||||||
for(j = 0; j < m->nchild; j++)
|
for(j = 0; j < m->nchild; j++)
|
||||||
mbredraw(m->child[j], 1, 1);
|
mbredraw(m->child[j], 1, 1);
|
||||||
memmove(&mbox.mesg[i], &mbox.mesg[i+1], (mbox.nmesg - i)*sizeof(Mesg*));
|
if(!dummy){
|
||||||
mbox.nmesg--;
|
memmove(&mbox.mesg[i], &mbox.mesg[i+1], (mbox.nmesg - i)*sizeof(Mesg*));
|
||||||
|
mbox.nmesg--;
|
||||||
|
}
|
||||||
|
mesgfree(m);
|
||||||
}
|
}
|
||||||
close(fd);
|
close(fd);
|
||||||
fprint(mbox.ctl, "clean\n");
|
fprint(mbox.ctl, "clean\n");
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue