From 43e56e26ded432658cdc5b9b3fce16919b3c64f7 Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Sun, 5 Jul 2020 17:44:32 +0200 Subject: [PATCH] upas/fs: put date822 into the index, fix from and replyto handling the date, from and replyto fields where unstable, in that the value read depended on the state of the cache. fixing the from and replyto fields is easy, we just handle the substitution in parsebody(). the date field however requires us to put the date822 into the index so it can be recovered without requiering to reparse the header (and body, as we might have a message/rfc822 message with promoted fields). with these changes, the fields will be consistent and independnet of the cache state. a small optimization also has been added: after parsing the body, attachments and substitution of from/replyto, the boundary and unixfrom strings are not needed anymore and can be freed early. --- sys/src/cmd/upas/fs/cache.c | 27 ++++++++++++++++++--------- sys/src/cmd/upas/fs/dat.h | 2 +- sys/src/cmd/upas/fs/fs.c | 31 +++++++++---------------------- sys/src/cmd/upas/fs/idx.c | 27 ++++++++++++++------------- sys/src/cmd/upas/fs/mbox.c | 37 ++++++++++++++++++++++++------------- 5 files changed, 66 insertions(+), 58 deletions(-) diff --git a/sys/src/cmd/upas/fs/cache.c b/sys/src/cmd/upas/fs/cache.c index 96ea6f4bc..2b82e7967 100644 --- a/sys/src/cmd/upas/fs/cache.c +++ b/sys/src/cmd/upas/fs/cache.c @@ -57,6 +57,7 @@ cachefree(Mailbox *mb, Message *m) } for(s = m->part; s; s = s->next) cachefree(mb, s); + if(m->mallocd){ free(m->start); m->mallocd = 0; @@ -69,20 +70,28 @@ cachefree(Mailbox *mb, Message *m) free(m->header); m->hallocd = 0; } + for(i = 0; i < nelem(m->references); i++){ free(m->references[i]); - m->references[i] = 0; + m->references[i] = nil; } + free(m->unixfrom); + m->unixfrom = nil; + free(m->unixheader); + m->unixheader = nil; + free(m->boundary); + m->boundary = nil; + m->csize = 0; - m->start = 0; - m->end = 0; - m->header = 0; - m->hend = 0; + m->start = nil; + m->end = nil; + m->header = nil; + m->hend = nil; m->hlen = -1; - m->body = 0; - m->bend = 0; - m->mheader = 0; - m->mhend = 0; + m->body = nil; + m->bend = nil; + m->mheader = nil; + m->mhend = nil; m->decoded = 0; m->converted = 0; m->badchars = 0; diff --git a/sys/src/cmd/upas/fs/dat.h b/sys/src/cmd/upas/fs/dat.h index 415415edb..27e84baf8 100644 --- a/sys/src/cmd/upas/fs/dat.h +++ b/sys/src/cmd/upas/fs/dat.h @@ -67,6 +67,7 @@ struct Idx { char *subject; char *sender; char *inreplyto; + char *date822; char *idxaux; /* mailbox specific */ char *type; /* mime info */ @@ -117,7 +118,6 @@ struct Message { /* mail info */ char *unixheader; char *unixfrom; - char *date822; char *references[Nref]; /* nil terminated unless full */ /* mime info */ diff --git a/sys/src/cmd/upas/fs/fs.c b/sys/src/cmd/upas/fs/fs.c index c77d25462..89e390e8d 100644 --- a/sys/src/cmd/upas/fs/fs.c +++ b/sys/src/cmd/upas/fs/fs.c @@ -423,11 +423,12 @@ fileinfo(Mailbox *mb, Message *m, int t, char **pp) } break; case Qdate: - p = m->date822; - if(p == nil){ - p = buf; - len = snprint(buf, sizeof buf, "%#Δ", m->fileid); - } + if((p = m->date822) != nil) + break; + /* wet floor */ + case Qunixdate: + p = buf; + len = snprint(buf, sizeof buf, "%#Δ", m->fileid); break; case Qfilename: p = m->filename; @@ -442,10 +443,7 @@ fileinfo(Mailbox *mb, Message *m, int t, char **pp) p = m->messageid; break; case Qfrom: - if(m->from != nil) - p = m->from; - else - p = m->unixfrom; + p = m->from; break; case Qffrom: p = m->ffrom; @@ -494,7 +492,7 @@ fileinfo(Mailbox *mb, Message *m, int t, char **pp) e = buf + sizeof buf; s = buf; for(i = 0; i < nelem(m->references); i++){ - if(m->references[i] == 0) + if(m->references[i] == nil) break; s = seprint(s, e, "%s\n", m->references[i]); } @@ -503,14 +501,7 @@ fileinfo(Mailbox *mb, Message *m, int t, char **pp) len = s - buf; break; case Qreplyto: - if(m->replyto != nil) - p = m->replyto; - else if(m->from != nil) - p = m->from; - else if(m->sender != nil) - p = m->sender; - else if(m->unixfrom != nil) - p = m->unixfrom; + p = m->replyto; break; case Qsender: p = m->sender; @@ -528,10 +519,6 @@ fileinfo(Mailbox *mb, Message *m, int t, char **pp) case Qtype: p = m->type; break; - case Qunixdate: - p = buf; - len = snprint(buf, sizeof buf, "%#Δ", m->fileid); - break; case Qfileid: p = buf; len = snprint(buf, sizeof buf, "%D", m->fileid); diff --git a/sys/src/cmd/upas/fs/idx.c b/sys/src/cmd/upas/fs/idx.c index ab487b026..c715552a8 100644 --- a/sys/src/cmd/upas/fs/idx.c +++ b/sys/src/cmd/upas/fs/idx.c @@ -5,10 +5,10 @@ #define idprint(...) if(iflag > 1) fprint(2, __VA_ARGS__); else {} #define iprint(...) if(iflag) fprint(2, __VA_ARGS__); else {} -static char *magic = "idx magic v8\n"; +static char *magic = "idx magic v9\n"; static char *mbmagic = "genericv1"; enum { - Idxfields = 22, + Idxfields = 23, Idxto = 30000, /* index timeout in ms */ Idxstep = 300, /* sleep between tries */ @@ -58,8 +58,9 @@ idxfree(Idx *i) free(i->subject); free(i->sender); free(i->inreplyto); - free(i->idxaux); + free(i->date822); free(i->filename); + free(i->idxaux); } memset(i, 0, sizeof *i); } @@ -77,7 +78,7 @@ pridxmsg(Biobuf *b, Idx *x) { Bprint(b, "%#A %ux %D %lud ", x->digest, x->flags&~Frecent, x->fileid, x->lines); Bprint(b, "%q %q %q %q %q ", ∂(x->ffrom), ∂(x->from), ∂(x->to), ∂(x->cc), ∂(x->bcc)); - Bprint(b, "%q %q %q %q %q ", ∂(x->replyto), ∂(x->messageid), ∂(x->subject), ∂(x->sender), ∂(x->inreplyto)); + Bprint(b, "%q %q %q %q %q %q ", ∂(x->replyto), ∂(x->messageid), ∂(x->subject), ∂(x->sender), ∂(x->inreplyto), ∂(x->date822)); Bprint(b, "%s %d %q %lud %lud ", x->type, x->disposition, ∂(x->filename), x->size, x->rawbsize); Bprint(b, "%lud %q %d\n", x->ibadchars, ∂(x->idxaux), x->nparts); return 0; @@ -402,15 +403,15 @@ dead: m->subject = ∫(f[11]); m->sender = ∫(f[12]); m->inreplyto = ∫(f[13]); - m->type = intern(f[14]); - m->disposition = atoi(f[15]); - m->filename = ∫(f[16]); - m->size = strtoul(f[17], 0, 0); - m->rawbsize = strtoul(f[18], 0, 0); - m->ibadchars = strtoul(f[19], 0, 0); - m->idxaux = ∫(f[20]); - m->nparts = strtoul(f[21], 0, 0); - + m->date822 = ∫(f[14]); + m->type = intern(f[15]); + m->disposition = atoi(f[16]); + m->filename = ∫(f[17]); + m->size = strtoul(f[18], 0, 0); + m->rawbsize = strtoul(f[19], 0, 0); + m->ibadchars = strtoul(f[20], 0, 0); + m->idxaux = ∫(f[21]); + m->nparts = strtoul(f[22], 0, 0); m->cstate &= ~Cidxstale; m->cstate |= Cidx|Cnew; m->str = s; diff --git a/sys/src/cmd/upas/fs/mbox.c b/sys/src/cmd/upas/fs/mbox.c index d9b245bf6..1ae11300f 100644 --- a/sys/src/cmd/upas/fs/mbox.c +++ b/sys/src/cmd/upas/fs/mbox.c @@ -486,6 +486,7 @@ parseunix(Message *m) if((p = strchr(s, ' ')) == nil) return; *p = 0; + free(m->unixfrom); m->unixfrom = strdup(s); *p = ' '; } @@ -563,9 +564,9 @@ parseheaders(Mailbox *mb, Message *m, int addfrom, int justmime) free(m->unixheader); m->unixheader = nil; } else if(m->unixheader == nil){ - if(m->unixfrom && strcmp(m->unixfrom, "???") != 0) + if(m->unixfrom != nil && strcmp(m->unixfrom, "???") != 0) p = m->unixfrom; - else if(m->from) + else if(m->from != nil) p = m->from; else p = "???"; @@ -605,6 +606,24 @@ parsebody(Message *m, Mailbox *mb) } }else if(strncmp(m->type, "text/", 5) == 0) sanemsg(m); + + free(m->boundary); + m->boundary = nil; + + if(m->replyto == nil){ + if(m->from != nil) + m->replyto = strdup(m->from); + else if(m->sender != nil) + m->replyto = strdup(m->sender); + else if(m->unixfrom != nil) + m->replyto = strdup(m->unixfrom); + } + if(m->from == nil && m->unixfrom != nil) + m->from = strdup(m->unixfrom); + + free(m->unixfrom); + m->unixfrom = nil; + m->rawbsize = m->rbend - m->rbody; m->cstate |= Cbody; } @@ -888,7 +907,7 @@ ref822(Message *m, Header *h, char*, char *p) free(a[0]); memmove(&a[0], &a[1], (Nref - 1) * sizeof(a[0])); j--; - } if(a[j] != nil) + } else if(a[j] != nil) continue; a[j] = strdup(f[i]); } @@ -1030,11 +1049,6 @@ delmessage(Mailbox *mb, Message *m) cachefree(mb, m); idxfree(m); } - free(m->unixfrom); - free(m->unixheader); - free(m->date822); - free(m->boundary); - free(m); } @@ -1527,11 +1541,8 @@ mailplumb(Mailbox *mb, Message *m) if(subject == nil) subject = ""; - if(m->from != nil) - from = m->from; - else if(m->unixfrom != nil) - from = m->unixfrom; - else + from = m->from; + if(from == nil) from = ""; sprint(len, "%lud", m->size);