Hi Brendan and all,
Nearly a month passed since my last message. Here comes the patch
that I announced some time ago.
The patch introduces imap_partial_fetch into mutt. To try it out, add the line
set imap_partial_fetch=yes
to your .muttrc file.
The code introduced here will at least partly resolve the issue related
to imap partial fetch. I often get emails which a 3.6k text part and
with 22 M of images. The proposed change will as a minimum allow users
to check the text of a message before downloading 22M of images.
I hope this patch will make mutt suck yet a little less.
Cheers,
Tilman
On Sun, Jan 05, 2014 at 02:30:53PM -0800, Brendan Cully wrote:
> On Sunday, 05 January 2014 at 22:55, Tilman WEIERS wrote:
> > Hi all,
> >
> > I would like to announce I am working on imap partial fetch. There is a
> > ticket for this issue under
> > http://dev.mutt.org/trac/ticket/3465
> >
> > I want to avoid doing someone else's work again. Is there anyone else
> > working on imap partial fetch?
>
> Hi!
>
> This is exciting news! As far as I'm aware no one has taken on any of
> this yet. I'd recommend you outline your plan for it before coding it
> up, in case we can offer any feedback that might reduce the work
> involved in implementing it and getting it integrated.
>
> Thanks,
> Brendan
diff -r muttsrc/commands.c mycleanmutt/commands.c
72c72
< mutt_parse_mime_message (Context, cur);
---
> mutt_parse_mime_message (Context, cur, option (OPTIMAPPARTIALFETCH) ? 1 :
> 0);
373c373
< mutt_parse_mime_message (Context, h);
---
> mutt_parse_mime_message (Context, h, option (OPTIMAPPARTIALFETCH) ? 1 :
> 0);
405c405
< mutt_parse_mime_message (Context, h);
---
> mutt_parse_mime_message (Context, h, option (OPTIMAPPARTIALFETCH) ? 1 :
> 0);
430c430
< mutt_parse_mime_message(Context, Context->hdrs[Context->v2r[i]]);
---
> mutt_parse_mime_message(Context, Context->hdrs[Context->v2r[i]],
> option (OPTIMAPPARTIALFETCH) ? 1 : 0);
712c712
< mutt_parse_mime_message (Context, h);
---
> mutt_parse_mime_message (Context, h, option (OPTIMAPPARTIALFETCH) ? 1 :
> 0);
982c982
<
---
>
985,986c985,986
< mutt_parse_mime_message (Context, h);
< if ((msg = mx_open_message (Context, h->msgno)) == NULL)
---
> mutt_parse_mime_message (Context, h, option (OPTIMAPPARTIALFETCH) ? 1 : 0);
> if ((msg = mx_open_message (Context, h->msgno, 0)) == NULL)
Only in mycleanmutt/contrib: Makefile
Only in mycleanmutt/contrib: Makefile.in
diff -r muttsrc/copy.c mycleanmutt/copy.c
685c685
< if ((msg = mx_open_message (src, hdr->msgno)) == NULL)
---
> if ((msg = mx_open_message (src, hdr->msgno, 1)) == NULL)
740c740
< if ((msg = mx_open_message (src, hdr->msgno)) == NULL)
---
> if ((msg = mx_open_message (src, hdr->msgno, 0)) == NULL)
diff -r muttsrc/crypt.c mycleanmutt/crypt.c
612c612
< mutt_parse_mime_message (Context, Context->hdrs[Context->v2r[i]]);
---
> mutt_parse_mime_message (Context, Context->hdrs[Context->v2r[i]],
> option (OPTIMAPPARTIALFETCH) ? 1 : 0);
663c663
< mutt_parse_mime_message (Context, h);
---
> mutt_parse_mime_message (Context, h, option (OPTIMAPPARTIALFETCH) ? 1 :
> 0);
diff -r muttsrc/imap/imap.h mycleanmutt/imap/imap.h
60c60
< int imap_fetch_message (MESSAGE* msg, CONTEXT* ctx, int msgno);
---
> int imap_fetch_message (MESSAGE* msg, CONTEXT* ctx, int msgno, int
> partial_fetch);
diff -r muttsrc/imap/message.c mycleanmutt/imap/message.c
44a45,46
> #include "mime.h"
>
392c394
< int imap_fetch_message (MESSAGE *msg, CONTEXT *ctx, int msgno)
---
> int imap_fetch_message (MESSAGE *msg, CONTEXT *ctx, int msgno, int
> partial_fetch)
410a413,420
> /* TW change 2013-12-31 f** NYE */
> LOFF_T first_part_size = 0;
> LOFF_T first_part_offset = 0;
>
> /* TW change on 2014-01-01 */
> char bs[LONG_STRING];
> char bps[LONG_STRING];
>
413a424,432
> if(h->content->type==TYPEMULTIPART)
> {
> if(h->content->parts)
> {
> first_part_size = h->content->parts->length;
> first_part_offset = h->content->parts->offset;
> }
> }
>
416,419c435,443
< if (HEADER_DATA(h)->parsed)
< return 0;
< else
< goto parsemsg;
---
> /* either the message has been fetched already or it should be fetched
> only partially */
> if(HEADER_DATA(h)->partial==0 ||
> (HEADER_DATA(h)->partial==1&&partial_fetch==1&&first_part_size<16384))
> {
> if (HEADER_DATA(h)->parsed) {
> return 0;
> } else {
> goto parsemsg;
> }
> }
460c484,499
< snprintf (buf, sizeof (buf), "UID FETCH %u %s", HEADER_DATA(h)->uid,
---
> if(partial_fetch==1)
> {
> /* Added by TW on 2014-01-01 to ensure the first part of a message is all
> fetched */
> if(first_part_size<16384)
> {
> first_part_size=16384;
> }
> snprintf (bps, sizeof(bps),"BODY.PEEK[]<0.%i>",(int) first_part_size);
> snprintf (bs, sizeof(bs), "BODY[]<0.%i>",(int) first_part_size);
> snprintf (buf, sizeof (buf), "UID FETCH %u %s", HEADER_DATA(h)->uid,
> (mutt_bit_isset (idata->capabilities, IMAP4REV1) ?
> (option (OPTIMAPPEEK) ? bps : bs) :
> "RFC822"));
> HEADER_DATA(h)->partial = 1;
> } else {
> snprintf (buf, sizeof (buf), "UID FETCH %u %s", HEADER_DATA(h)->uid,
463a503,504
> HEADER_DATA(h)->partial = 0;
> }
571c612,615
< h->content->length = ftell (msg->fp) - h->content->offset;
---
> /* Changed by TW on 2013-12-31 to resolve the issue with wrong message sizes
> */
> if(partial_fetch==0) {
> h->content->length = ftell (msg->fp) - h->content->offset;
> }
diff -r muttsrc/imap/message.h mycleanmutt/imap/message.h
37a38
> unsigned int partial : 1;
diff -r muttsrc/init.h mycleanmutt/init.h
1151a1152,1157
> { "imap_partial_fetch", DT_BOOL, R_NONE, OPTIMAPPARTIALFETCH, 0 },
> /*
> ** .pp
> ** If enabled, mutt will download only the selected part of an IMAP message.
> ** Useful in case of IMAP messages with large attachments.
> */
diff -r muttsrc/mailbox.h mycleanmutt/mailbox.h
59c59
< MESSAGE *mx_open_message (CONTEXT *, int);
---
> MESSAGE *mx_open_message (CONTEXT *, int, int);
diff -r muttsrc/mutt.h mycleanmutt/mutt.h
366a367
> OPTIMAPPARTIALFETCH,
diff -r muttsrc/mx.c mycleanmutt/mx.c
1352c1352
< MESSAGE *mx_open_message (CONTEXT *ctx, int msgno)
---
> MESSAGE *mx_open_message (CONTEXT *ctx, int msgno, int partial_fetch)
1389c1389
< if (imap_fetch_message (msg, ctx, msgno) != 0)
---
> if (imap_fetch_message (msg, ctx, msgno, partial_fetch) != 0)
diff -r muttsrc/parse.c mycleanmutt/parse.c
652c652,653
< if (last && last->length == 0 && !final)
---
> if (last && last->length == 0 && !final)
> {
653a655,658
> #ifdef USE_IMAP
>
> #endif /* USE_IMAP */
> }
948c953
< void mutt_parse_mime_message (CONTEXT *ctx, HEADER *cur)
---
> void mutt_parse_mime_message (CONTEXT *ctx, HEADER *cur, int partial_fetch)
957c962,963
< if (cur->content->parts)
---
> /* changed by TW on 2014-01-02: When partial_fetch==0, the presence of the
> first part of a message is no good indicator of whether the message has been
> parsed earlier */
> if (partial_fetch==0 && cur->content->parts)
960c966
< if ((msg = mx_open_message (ctx, cur->msgno)))
---
> if ((msg = mx_open_message (ctx, cur->msgno, partial_fetch)))
961a968
>
1629c1636
< mutt_parse_mime_message (ctx, hdr);
---
> mutt_parse_mime_message (ctx, hdr, option (OPTIMAPPARTIALFETCH) ? 1 : 0);
diff -r muttsrc/pattern.c mycleanmutt/pattern.c
158c158
< if ((msg = mx_open_message (ctx, msgno)) != NULL)
---
> if ((msg = mx_open_message (ctx, msgno, 0)) != NULL)
178c178
< mutt_parse_mime_message (ctx, h);
---
> mutt_parse_mime_message (ctx, h, option (OPTIMAPPARTIALFETCH) ? 1 : 0);
diff -r muttsrc/pgp.c mycleanmutt/pgp.c
678c678
< mutt_parse_mime_message (Context, h);
---
> mutt_parse_mime_message (Context, h, option (OPTIMAPPARTIALFETCH) ? 1 :
> 0);
698c698
< mutt_parse_mime_message (Context, Context->hdrs[Context->v2r[i]]);
---
> mutt_parse_mime_message (Context, Context->hdrs[Context->v2r[i]],
> option (OPTIMAPPARTIALFETCH) ? 1 : 0);
712c712
< mutt_parse_mime_message (Context, h);
---
> mutt_parse_mime_message (Context, h, option (OPTIMAPPARTIALFETCH) ? 1 :
> 0);
Only in mycleanmutt/po: bg.gmo
Only in mycleanmutt/po: ca.gmo
Only in mycleanmutt/po: cs.gmo
Only in mycleanmutt/po: da.gmo
Only in mycleanmutt/po: de.gmo
Only in mycleanmutt/po: el.gmo
Only in mycleanmutt/po: eo.gmo
Only in mycleanmutt/po: es.gmo
Only in mycleanmutt/po: et.gmo
Only in mycleanmutt/po: eu.gmo
Only in mycleanmutt/po: fr.gmo
Only in mycleanmutt/po: ga.gmo
Only in mycleanmutt/po: gl.gmo
Only in mycleanmutt/po: hu.gmo
Only in mycleanmutt/po: id.gmo
Only in mycleanmutt/po: it.gmo
Only in mycleanmutt/po: ja.gmo
Only in mycleanmutt/po: ko.gmo
Only in mycleanmutt/po: lt.gmo
Only in mycleanmutt/po: nl.gmo
Only in mycleanmutt/po: pl.gmo
Only in mycleanmutt/po: POTFILES
Only in mycleanmutt/po: pt_BR.gmo
Only in mycleanmutt/po: ru.gmo
Only in mycleanmutt/po: sk.gmo
Only in mycleanmutt/po: sv.gmo
Only in mycleanmutt/po: tr.gmo
Only in mycleanmutt/po: uk.gmo
Only in mycleanmutt/po: zh_CN.gmo
Only in mycleanmutt/po: zh_TW.gmo
diff -r muttsrc/postpone.c mycleanmutt/postpone.c
539c539
< if (!fp && (msg = mx_open_message (ctx, hdr->msgno)) == NULL)
---
> if (!fp && (msg = mx_open_message (ctx, hdr->msgno, 0)) == NULL)
diff -r muttsrc/protos.h mycleanmutt/protos.h
225c225
< void mutt_parse_mime_message (CONTEXT *ctx, HEADER *);
---
> void mutt_parse_mime_message (CONTEXT *ctx, HEADER *, int);
diff -r muttsrc/recvattach.c mycleanmutt/recvattach.c
953c953,955
< mutt_parse_mime_message (Context, hdr);
---
> /* Adapted by TW on 2014-01-02: parse the full message */
> hdr->content->parts=NULL;
> mutt_parse_mime_message (Context, hdr, 0);
957c959
< if ((msg = mx_open_message (Context, hdr->msgno)) == NULL)
---
> if ((msg = mx_open_message (Context, hdr->msgno, 0)) == NULL)
diff -r muttsrc/send.c mycleanmutt/send.c
367c367
< mutt_parse_mime_message (ctx, cur);
---
> mutt_parse_mime_message (ctx, cur, option (OPTIMAPPARTIALFETCH) ? 1 : 0);
432c432
< mutt_parse_mime_message (ctx, cur);
---
> mutt_parse_mime_message (ctx, cur, option (OPTIMAPPARTIALFETCH) ? 1 : 0);
diff -r muttsrc/sendlib.c mycleanmutt/sendlib.c
1291c1291
< mutt_parse_mime_message (ctx, hdr);
---
> mutt_parse_mime_message (ctx, hdr, option (OPTIMAPPARTIALFETCH) ? 1 : 0);
2531c2531
< if (!fp && (msg = mx_open_message (Context, h->msgno)) == NULL)
---
> if (!fp && (msg = mx_open_message (Context, h->msgno, 0)) == NULL)
diff -r muttsrc/VERSION mycleanmutt/VERSION
1c1
< 1.5.22
---
> 1.5.23