diff options
author | Ori Bernstein <ori@eigenstate.org> | 2021-02-28 16:36:42 -0800 |
---|---|---|
committer | Ori Bernstein <ori@eigenstate.org> | 2021-02-28 16:36:42 -0800 |
commit | 35558431105e4c793673310bd5bfa7f8a99d89e3 (patch) | |
tree | 994bc10cc2746dc9e38acafde7b862ca5fe5c1e6 | |
parent | be782ef4357465e608db4123d21c3eeb14a2a110 (diff) | |
download | plan9front-35558431105e4c793673310bd5bfa7f8a99d89e3.tar.xz |
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.
-rw-r--r-- | sys/src/cmd/upas/Mail/mbox.c | 46 |
1 files changed, 28 insertions, 18 deletions
diff --git a/sys/src/cmd/upas/Mail/mbox.c b/sys/src/cmd/upas/Mail/mbox.c index 5b05dc529..b32c9b6a4 100644 --- a/sys/src/cmd/upas/Mail/mbox.c +++ b/sys/src/cmd/upas/Mail/mbox.c @@ -260,13 +260,15 @@ addmesg(Mesg *m, int ins) mbox.mesgsz *= 2; mbox.mesg = erealloc(mbox.mesg, mbox.mesgsz*sizeof(Mesg*)); } - if(ins) - idx = slotfor(m); - else - idx = mbox.nmesg; - memmove(&mbox.mesg[idx + 1], &mbox.mesg[idx], (mbox.nmesg - idx)*sizeof(Mesg*)); - mbox.mesg[idx] = m; - mbox.nmesg++; + if(ins >= 0){ + if(ins == 0) + idx = slotfor(m); + else + idx = mbox.nmesg; + memmove(&mbox.mesg[idx + 1], &mbox.mesg[idx], (mbox.nmesg - idx)*sizeof(Mesg*)); + mbox.mesg[idx] = m; + mbox.nmesg++; + } if(m->messageid == nil) return; @@ -296,7 +298,7 @@ addmesg(Mesg *m, int ins) } static Mesg * -placeholder(char *msgid, vlong time, int ins) +placeholder(char *msgid, vlong time) { Mesg *m; @@ -305,7 +307,6 @@ placeholder(char *msgid, vlong time, int ins) m->messageid = estrdup(msgid); m->hash = strhash(msgid); m->time = time; - addmesg(m, ins); return m; } @@ -381,8 +382,10 @@ load(char *name, char *digest, int ins) return m; } p = lookupid(m->inreplyto); - if(p == nil) - p = placeholder(m->inreplyto, m->time, ins); + if(p == nil){ + p = placeholder(m->inreplyto, m->time); + addmesg(m, ins); + } if(!addchild(p, m, d)) m->state |= Stoplev; return m; @@ -656,6 +659,8 @@ relinkmsg(Mesg *p, Mesg *m) /* remove child, preserving order */ j = 0; + if(p == nil || m == nil) + return; for(i = 0; p && i < p->nchild; i++){ if(p->child[i] != m) p->child[j++] = p->child[i]; @@ -675,7 +680,7 @@ relinkmsg(Mesg *p, Mesg *m) static void mbflush(char **, int) { - int i, j, ln, fd; + int i, j, ln, fd, dummy; char *path; Mesg *m, *p; @@ -687,7 +692,7 @@ mbflush(char **, int) sysfatal("open mbox: %r"); while(i < mbox.nmesg){ m = mbox.mesg[i]; - if((m->state & Sopen) || !(m->flags & (Fdel|Ftodel))){ + if((m->state & (Sopen|Sdummy)) || !(m->flags & (Fdel|Ftodel))){ i++; continue; } @@ -698,18 +703,23 @@ mbflush(char **, int) fprint(fd, "delete %s %d", mailbox, atoi(m->name)); p = m->parent; + dummy = 0; removeid(m); if(p == nil && m->nsub != 0){ - p = placeholder(m->messageid, m->time, 1); + p = placeholder(m->messageid, m->time); p->nsub = m->nsub + 1; + addmesg(p, -1); mbox.mesg[i] = p; + dummy = 1; } - if(p != nil) - relinkmsg(p, m); + relinkmsg(p, m); for(j = 0; j < m->nchild; j++) mbredraw(m->child[j], 1, 1); - memmove(&mbox.mesg[i], &mbox.mesg[i+1], (mbox.nmesg - i)*sizeof(Mesg*)); - mbox.nmesg--; + if(!dummy){ + memmove(&mbox.mesg[i], &mbox.mesg[i+1], (mbox.nmesg - i)*sizeof(Mesg*)); + mbox.nmesg--; + } + mesgfree(m); } close(fd); fprint(mbox.ctl, "clean\n"); |