6 addlru(Mcache *c, Message *m)
12 while((l = *ll) != nil){
25 notecache(Mailbox *mb, Message *m, long sz)
27 assert(Topmsg(mb, m));
28 assert(sz >= 0 && sz <= Maxmsg);
35 cachefree0(Mailbox *mb, Message *m, int force)
40 if(!force && mb->fetch == nil)
42 for(s = m->part; s; s = s->next)
43 cachefree(mb, s, force);
44 dprint("cachefree: %D %p, %p\n", m->fileid, m, m->start);
57 for(i = 0; i < nelem(m->references); i++){
58 free(m->references[i]);
77 m->cstate &= ~(Cheader|Cbody);
83 cachefree(Mailbox *mb, Message *m, int force)
87 for(ll = &mb->lru; *ll != nil; ll = &((*ll)->lru)){
95 cachefree0(mb, m, force);
99 putcache(Mailbox *mb, Message *m)
104 while(mb->lru != nil && (mb->cached > cachetarg || mb->nlru > 10)){
106 while(mb->lru->refs > 0){
111 cachefree(mb, mb->lru, 0);
116 squeeze(Message *m, uvlong o, long l, int c)
121 q = memchr(m->start + o, c, l);
125 e = m->start + o + l;
126 for(p = q; q < e; q++){
137 msgrealloc(Message *m, ulong l)
139 long l0, h0, m0, me, b0;
141 l0 = m->end - m->start;
143 h0 = m->hend - m->start;
144 m0 = m->mheader - m->start;
145 me = m->mhend - m->start;
146 b0 = m->body - m->start;
147 assert(h0 >= 0 && m0 >= 0 && me >= 0 && b0 >= 0);
148 m->start = erealloc(m->start, l + 1);
149 m->rbody = m->start + b0;
150 m->rbend = m->end = m->start + l0;
152 m->header = m->start;
153 m->hend = m->start + h0;
156 m->body = m->start + b0;
157 m->bend = m->start + l0;
159 m->mheader = m->start + m0;
160 m->mhend = m->start + me;
164 * the way we squeeze out bad characters is exceptionally sneaky.
167 fetch(Mailbox *mb, Message *m, uvlong o, ulong l)
173 l0 = m->end - m->start;
175 dprint("fetch %lud sz %lud o %llud l %lud badchars %d\n", l0, m->size, o, l, m->badchars);
176 if(l0 == m->size || o > m->size)
182 l += m->ibadchars - m->badchars;
185 msgrealloc(m, o + m->badchars + l);
189 if(mb->fetch(mb, m, o + m->badchars, l) == -1){
190 logmsg(m, "can't fetch %D %llud %lud", m->fileid, o, l);
195 l += m->size - sz0; /* awful botch for gmail */
197 /* grumble. poor planning. */
199 memmove(m->start + o, m->start + o + m->badchars, l);
200 n = squeeze(m, o, l, 0);
201 n += squeeze(m, o, l - n, '\r');
203 if(m->ibadchars == 0)
204 dprint(" %ld more badchars\n", n);
207 msgrealloc(m, o + l);
210 m->bend = m->rbend = m->end = m->start + o + l;
212 if(o + l + n == m->size && m->cstate&Cidx){
213 dprint(" redux %llud %ld\n", o + l, n);
219 eprint("unhandled case in fetch\n");
225 cachehash(Mailbox *mb, Message *m)
227 if(m->whole == m->whole->whole)
228 henter(PATH(mb->id, Qmbox), m->name,
229 (Qid){PATH(m->id, Qdir), 0, QTDIR}, m, mb);
231 henter(PATH(m->whole->id, Qdir), m->name,
232 (Qid){PATH(m->id, Qdir), 0, QTDIR}, m, mb);
233 henter(PATH(m->id, Qdir), "xxx",
234 (Qid){PATH(m->id, Qmax), 0, QTFILE}, m, mb); /* sleezy speedup */
237 static char *itab[] = {
255 for(i = 0; i < 8; i++)
258 p = seprint(p, e, "%s ", itab[i]);
267 middlecache(Mailbox *mb, Message *m)
272 while(!Topmsg(mb, m)){
274 if((m->cstate & Cbody) == 0)
279 dprint("middlecache %d [%D] %lud %lud\n", m->id, m->fileid, (ulong)(m->end - m->start), m->size);
280 return cachebody(mb, m);
284 cacheheaders(Mailbox *mb, Message *m)
290 if(!mb->fetch || m->cstate&Cheader)
293 return middlecache(mb, m);
294 dprint("cacheheaders %d %D\n", m->id, m->fileid);
296 r = fetch(mb, m, 0, m->size);
297 else for(r = 0; (o = m->end - m->start) < m->size; ){
298 if((r = fetch(mb, m, o, 4096)) < 0)
303 for(e = m->end - 2; p < e; p++){
304 p = memchr(p, '\n', e - p);
307 if(p[1] == '\n' || (p[1] == '\r' && p[2] == '\n'))
314 parseheaders(mb, m, mb->addfrom, 0);
319 digestmessage(Mailbox *mb, Message *m)
321 assert(m->digest == 0);
322 m->digest = emalloc(SHA1dlen);
323 sha1((uchar*)m->start, m->end - m->start, m->digest, nil);
324 if(mtreeisdup(mb, m)){
325 logmsg(m, "dup detected");
326 m->deleted = Dup; /* no dups allowed */
329 dprint("%d %#A\n", m->id, m->digest);
333 cachebody(Mailbox *mb, Message *m)
337 while(!Topmsg(mb, m))
339 if(!mb->fetch || m->cstate&Cbody)
341 o = m->end - m->start;
342 dprint("cachebody %d [%D] %lud %lud %s", m->id, m->fileid, o, m->size, cstate(m));
344 if(fetch(mb, m, o, m->size - o) < 0)
346 if((m->cstate&Cidx) == 0){
347 assert(m->ibadchars == 0);
349 dprint("reducing size %ld %ld\n", m->size, m->size - m->badchars);
350 m->size -= m->badchars; /* sneaky */
351 m->ibadchars = m->badchars;
354 digestmessage(mb, m);
356 m->lines = countlines(m);
357 parse(mb, m, mb->addfrom, 0);
358 dprint(" →%s\n", cstate(m));
363 cacheidx(Mailbox *mb, Message *m)
367 if(cachebody(mb, m) == -1)
369 m->cstate |= Cidxstale|Cidx;
374 countparts(Message *m)
379 for(p = m->part; p; p = p->next){
387 insurecache(Mailbox *mb, Message *m)
389 if(m->deleted || !m->inmbox)
393 if((m->cstate & Cidx) == 0){
394 logmsg(m, "%s: can't cache: %s: %r", mb->path, m->name);