diff -Pur mutt-1.2.5/doc/manual.sgml.head mutt-1.2.5-attach/doc/manual.sgml.head --- mutt-1.2.5/doc/manual.sgml.head Sat Apr 22 04:33:46 2000 +++ mutt-1.2.5-attach/doc/manual.sgml.head Wed Jan 31 00:42:23 2001 @@ -1609,6 +1609,7 @@ ~t USER messages addressed to USER ~U unread messages ~v message is part of a collapsed thread. +~V [MIN]-[MAX] messages with MIN to MAX attachments *) ~x EXPR messages which contain EXPR in the `References' field ~z [MIN]-[MAX] messages with a size in the range MIN to MAX *) diff -Pur mutt-1.2.5/doc/manual.txt mutt-1.2.5-attach/doc/manual.txt --- mutt-1.2.5/doc/manual.txt Fri Jul 28 13:50:52 2000 +++ mutt-1.2.5-attach/doc/manual.txt Wed Jan 31 00:43:44 2001 @@ -1866,6 +1866,7 @@ ~t USER messages addressed to USER ~U unread messages ~v message is part of a collapsed thread. + ~V [MIN]-[MAX] messages with MIN - MAX attachments *) ~x EXPR messages which contain EXPR in the `References' field ~z [MIN]-[MAX] messages with a size in the range MIN to MAX *) @@ -3732,6 +3733,8 @@ %u user (login) name of the author %v first name of the author, or the recipient if the message is from you + %V number of attachments (%-V: number of + top-level attachments) %Z message status flags %{fmt} the date and time of the message is converted to sender's time zone, and diff -Pur mutt-1.2.5/doc/muttrc.man.head mutt-1.2.5-attach/doc/muttrc.man.head --- mutt-1.2.5/doc/muttrc.man.head Fri Mar 3 04:10:19 2000 +++ mutt-1.2.5-attach/doc/muttrc.man.head Wed Jan 31 00:33:56 2001 @@ -340,13 +340,14 @@ ~t \fIEXPR\fP messages addressed to \fIEXPR\fP ~U unread messages ~v message is part of a collapsed thread. +~V \fIMIN\fP-\fIMAX\fP messages with MIN - MAX attachments ~x \fIEXPR\fP messages which contain \fIEXPR\fP in the \(lqReferences\(rq field ~z \fIMIN\fP-\fIMAX\fP messages with a size in the range \fIMIN\fP to \fIMAX\fP .TE .PP In the above, \fIEXPR\fP is a regular expression. .PP -With the \fB~m\fP, \fB~n\fP, and \fB~z\fP operators, you can also +With the \fB~m\fP, \fB~n\fP, \fB~V\fP, and \fB~z\fP operators, you can also specify ranges in the forms \fB<\fP\fIMAX\fP, \fB>\fP\fIMIN\fP, \fIMIN\fP\fB-\fP, and \fB-\fP\fIMAX\fP. .SS Matching dates diff -Pur mutt-1.2.5/hdrline.c mutt-1.2.5-attach/hdrline.c --- mutt-1.2.5/hdrline.c Fri Mar 3 04:10:08 2000 +++ mutt-1.2.5-attach/hdrline.c Wed Jan 31 00:36:26 2001 @@ -215,6 +215,7 @@ * %t = `to:' field (recipients) * %T = $to_chars * %u = user (login) name of author + * %V = number of MIME attachments * %v = first name of author, unless from self * %Z = status flags */ @@ -607,6 +608,32 @@ if ((p = strpbrk (buf2, " %@"))) *p = 0; snprintf (dest, destlen, fmt, buf2); + break; + + case 'V': + { + int i, flags; + + flags = 0; + + if (option(OPTATRECURSE)) + flags |= M_PARTS_MSGTRANS; + if (option(OPTATINLINEOK)) + flags |= M_PARTS_INLINEOK; + if (option(OPTATCONTAINERSOK)) + flags |= M_PARTS_CONTAINS; + + mutt_parse_mime_message(ctx, hdr); + i = mutt_count_body_parts(hdr->content, flags); + mutt_free_body(&hdr->content->parts); + + /* The recursion allows messages without depth to return 0. */ + if (optional) + optional = i ? 1 : 0; + + snprintf (fmt, sizeof (fmt), "%%%sd", prefix); + snprintf (dest, destlen, fmt, i); + } break; case 'Z': diff -Pur mutt-1.2.5/init.h mutt-1.2.5-attach/init.h --- mutt-1.2.5/init.h Tue Jul 18 02:47:08 2000 +++ mutt-1.2.5-attach/init.h Wed Jan 31 00:37:52 2001 @@ -217,6 +217,25 @@ ** ``$$attach_sep'' separator is added after each attachment. When set, ** Mutt will operate on the attachments one by one. */ + { "attach_count_containers_ok", DT_BOOL, R_INDEX, OPTATCONTAINERSOK, 0 }, + /* + ** .pp + ** If set, Mutt's attachment counter (%V/~V) will consider MIME components + ** which contain other components (e.g., multipart/* and message/*) as + ** attachments. + */ + { "attach_count_inline_ok", DT_BOOL, R_INDEX, OPTATINLINEOK, 0 }, + /* + ** .pp + ** If set, Mutt's attachment counter (%V/~V) will consider MIME components + ** with a disposition of "inline" as attachments. + */ + { "attach_count_recurse", DT_BOOL, R_INDEX, OPTATRECURSE, 1 }, + /* + ** .pp + ** If set, Mutt's attachment counter (%V/~V) will examine message/* + ** components for attachments. + */ { "attribution", DT_STR, R_NONE, UL &Attribution, UL "On %d, %n wrote:" }, /* ** .pp @@ -806,6 +825,7 @@ ** %u user (login) name of the author ** %v first name of the author, or the ** . recipient if the message is from you + ** %V number of attachments ** %Z message status flags ** %{fmt} the date and time of the message is ** . converted to sender's time zone, and diff -Pur mutt-1.2.5/mutt.h mutt-1.2.5-attach/mutt.h --- mutt-1.2.5/mutt.h Thu Jun 8 05:00:14 2000 +++ mutt-1.2.5-attach/mutt.h Wed Jan 31 00:38:35 2001 @@ -199,6 +199,8 @@ M_PGP_ENCRYPT, M_PGP_KEY, #endif + + M_MIMEATTACH, /* Options for Mailcap lookup */ M_EDIT, @@ -356,6 +358,10 @@ OPTWRITEBCC, /* write out a bcc header? */ OPTXMAILER, + OPTATINLINEOK, /* Count inline attachments? */ + OPTATCONTAINERSOK, /* Count containing messages? */ + OPTATRECURSE, /* Recurse message/\* types? */ + /* PGP options */ #ifdef HAVE_PGP @@ -712,6 +718,12 @@ void state_prefix_putc(char, STATE *); int state_printf(STATE *, const char *, ...); + +/* Flags for mutt_count_body_parts() */ +#define M_PARTS_MSGTRANS (1<<0) /* message/rfc822 is transparent */ +#define M_PARTS_CONTAINS (1<<1) /* Count containers */ +#define M_PARTS_INLINEOK (1<<2) /* Inline dispositions (except PGP) */ +#define M_PARTS_PGPOK (1<<3) /* Count PGP */ #include "protos.h" #include "lib.h" diff -Pur mutt-1.2.5/parse.c mutt-1.2.5-attach/parse.c --- mutt-1.2.5/parse.c Sat Apr 22 03:49:29 2000 +++ mutt-1.2.5-attach/parse.c Wed Jan 31 00:33:56 2001 @@ -1288,3 +1288,98 @@ return p; } + +int count_body_parts (BODY *body, int flags) +{ + int count = 0; + int shallcount, shallrecurse; + BODY *bp; + + if (body == NULL) + return 0; + + for (bp = body; bp != NULL; bp = bp->next) + { + /* Initial disposition is to count and not to recurse this part. */ + shallcount = 1; + shallrecurse = 0; + + dprint(30, (debugfile, "bp: desc=\"%s\"; fn=\"%s\", type=\"%d/%s\"\n", + bp->description ? bp->description : ("none"), + bp->filename ? bp->filename : + bp->d_filename ? bp->d_filename : "(none)", + bp->type, bp->subtype ? bp->subtype : "*")); + if (bp->type == TYPEMESSAGE) + { + /* If messages are "transparent", recursively examine their parts. */ + if (flags & M_PARTS_MSGTRANS) + shallrecurse = 1; + /* Do not count messages if they are transparent + and we are not told to count containers. */ + if (shallrecurse && !(flags & M_PARTS_CONTAINS)) + shallcount = 0; + } + else if (bp->type == TYPEMULTIPART) + { + /* Always recurse multiparts. */ + shallrecurse = 1; + /* If told to count containers, then consider this one. */ + if (!(flags & M_PARTS_CONTAINS)) + shallcount = 0; + } + + /* These are just different reasons to turn off shallcount, so ignore + * them if it's already off. + */ + if (shallcount && bp->disposition != DISPATTACH) + { + /* Are we allowed to count inline disposition? */ + if (flags & M_PARTS_INLINEOK) + { + /* Inline is OK */ +#ifdef HAVE_PGP + /* no good lib routines for this on a per-component basis */ + if (!(flags & M_PARTS_PGPOK) && + bp->type == TYPEAPPLICATION && + !mutt_strncmp(bp->subtype, "pgp", 3)) + shallcount = 0; +#endif + dprint(30, (debugfile, "cbp: inlineok shallcount = %d\n", shallcount)); + } + else + { + /* Inline not OK */ + shallcount = 0; + dprint(30, (debugfile, "cbp: inlinebad shallcount = %d\n", shallcount)); + } + } + + if (shallcount) + count++; + + if (shallrecurse) + { + dprint(30, (debugfile, "cbp: %08x pre count = %d\n", bp, shallcount)); + count += count_body_parts(bp->parts, flags); + dprint(30, (debugfile, "cbp: %08x post count = %d\n", bp, shallcount)); + } + } + + dprint(30, (debugfile, "bp: return %d\n", count < 0 ? 0 : count)); + return count < 0 ? 0 : count; +} + +int mutt_count_body_parts (BODY *body, int flags) +{ + int count; + + count = count_body_parts(body, flags); + + /* Never count the fundamental document. If inlineok, we will have + * counted it, so count will be inflated. Discount this before returning. + */ + if (count > 0 && (flags & M_PARTS_INLINEOK)) + --count; + + return count; +} diff -Pur mutt-1.2.5/pattern.c mutt-1.2.5-attach/pattern.c --- mutt-1.2.5/pattern.c Sun Apr 9 07:27:37 2000 +++ mutt-1.2.5-attach/pattern.c Wed Jan 31 00:40:26 2001 @@ -87,6 +87,7 @@ { 't', M_TO, 0, eat_regexp }, { 'U', M_UNREAD, 0, NULL }, { 'v', M_COLLAPSED, 0, NULL }, + { 'V', M_MIMEATTACH, 0, eat_range }, { 'x', M_REFERENCE, 0, eat_regexp }, { 'z', M_SIZE, 0, eat_range }, { 0 } @@ -890,6 +891,24 @@ case M_PGP_KEY: return (pat->not ^ (h->pgp & PGPKEY)); #endif + case M_MIMEATTACH: + { + int i, flags = 0; + + if (option(OPTATRECURSE)) + flags |= M_PARTS_MSGTRANS; + if (option(OPTATINLINEOK)) + flags |= M_PARTS_INLINEOK; + if (option(OPTATCONTAINERSOK)) + flags |= M_PARTS_CONTAINS; + + mutt_parse_mime_message(ctx, h); + i = mutt_count_body_parts(h->content->parts, flags); + mutt_free_body(&h->content->parts); + return (pat->not ^ (i >= pat->min && (pat->max == M_MAXRANGE || + i <= pat->max))); + } + } mutt_error (_("error: unknown op %d (report this error)."), pat->op); return (-1); diff -Pur mutt-1.2.5/protos.h mutt-1.2.5-attach/protos.h --- mutt-1.2.5/protos.h Tue May 16 10:23:12 2000 +++ mutt-1.2.5-attach/protos.h Wed Jan 31 00:40:59 2001 @@ -133,6 +133,7 @@ void mutt_body_handler (BODY *, STATE *); void mutt_bounce_message (FILE *fp, HEADER *, ADDRESS *); void mutt_buffy (char *); +int mutt_count_body_parts (BODY *body, int flags); void mutt_check_rescore (CONTEXT *); void mutt_clear_error (void); void mutt_create_alias (ENVELOPE *, ADDRESS *);