diff -rU5 mutt-1.3.8-nntp/doc/manual.sgml.head mutt-1.3.8/doc/manual.sgml.head --- mutt-1.3.8-nntp/doc/manual.sgml.head Sun Sep 10 06:41:58 2000 +++ mutt-1.3.8/doc/manual.sgml.head Sun Sep 10 06:42:21 2000 @@ -1685,10 +1685,11 @@ ~s SUBJECT messages having SUBJECT in the ``Subject'' field. ~T tagged messages ~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 ~y EXPR messages which contain EXPR in the `X-Label' field ~z [MIN]-[MAX] messages with a size in the range MIN to MAX *) Only in mutt-1.3.8/doc: manual.sgml.head.orig diff -rU5 mutt-1.3.8-nntp/doc/manual.txt mutt-1.3.8/doc/manual.txt --- mutt-1.3.8-nntp/doc/manual.txt Sun Sep 10 06:41:58 2000 +++ mutt-1.3.8/doc/manual.txt Sun Sep 10 06:53:04 2000 @@ -1982,10 +1982,11 @@ ~s SUBJECT messages having SUBJECT in the ``Subject'' field. ~T tagged messages ~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 ~y EXPR messages which contain EXPR in the `X-Label' field ~z [MIN]-[MAX] messages with a size in the range MIN to MAX *) Where EXPR, USER, ID, and SUBJECT are ``regular expressions''. @@ -3943,10 +3944,12 @@ %%uu user (login) name of the author %%vv first name of the author, or the recipient if the message is from you + + %%VV number of attachments (%%--VV: number of top-level attachments) %%WW name of organization of author (`organization:' field) %%yy `x-label:' field, if present Only in mutt-1.3.8/doc: manual.txt.orig Only in mutt-1.3.8/doc: manual.txt.rej diff -rU5 mutt-1.3.8-nntp/doc/muttrc.man.head mutt-1.3.8/doc/muttrc.man.head --- mutt-1.3.8-nntp/doc/muttrc.man.head Tue Jun 20 07:39:38 2000 +++ mutt-1.3.8/doc/muttrc.man.head Sun Sep 10 06:42:21 2000 @@ -346,17 +346,18 @@ ~s \fIEXPR\fP messages having \fIEXPR\fP in the \(lqSubject\(rq field. ~T tagged messages ~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 .PP The \fB~d\fP and \fB~r\fP operators are used to match date ranges, diff -rU5 mutt-1.3.8-nntp/hdrline.c mutt-1.3.8/hdrline.c --- mutt-1.3.8-nntp/hdrline.c Sun Sep 10 06:41:59 2000 +++ mutt-1.3.8/hdrline.c Sun Sep 10 06:53:44 2000 @@ -218,10 +218,11 @@ * %S = short message status (e.g., N/O/D/!/r/-) * %t = `to:' field (recipients) * %T = $to_chars * %u = user (login) name of author * %v = first name of author, unless from self + * %V = number of MIME attachments * %W = where user is (organization) * %y = `x-label:' field (if present) * %Y = `x-label:' field (if present, tree unfolded, and != parent's x-label) * %Z = status flags */ @@ -645,10 +646,36 @@ hdr->deleted ? 'D' : (hdr->attach_del ? 'd' : ch), hdr->tagged ? '*' : (hdr->flagged ? '!' : (Tochars && ((i = mutt_user_is_recipient (hdr)) < mutt_strlen (Tochars)) ? Tochars[i] : ' '))); mutt_format_s (dest, destlen, prefix, 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 'y': if (optional) optional = hdr->env->x_label ? 1 : 0; Only in mutt-1.3.8: hdrline.c.orig diff -rU5 mutt-1.3.8-nntp/init.h mutt-1.3.8/init.h --- mutt-1.3.8-nntp/init.h Sun Sep 10 06:41:59 2000 +++ mutt-1.3.8/init.h Sun Sep 10 06:54:39 2000 @@ -229,10 +229,29 @@ ** etc) on a list of tagged attachments, Mutt will concatenate the ** attachments and will operate on them as a single attachment. The ** ``$$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 ** This is the string that will precede a message which has been included ** in a reply. For a full listing of defined escape sequences see the @@ -830,10 +849,11 @@ ** .dt %S .dd status of the message (N/D/d/!/r/\(as) ** .dt %t .dd `to:' field (recipients) ** .dt %T .dd the appropriate character from the $$to_chars string ** .dt %u .dd user (login) name of the author ** .dt %v .dd first name of the author, or the recipient if the message is from you + ** .dt %V .dd number of attachments ** .dt %W .dd name of organization of author (`organization:' field) ** .dt %y .dd `x-label:' field, if present ** .dt %Y .dd `x-label' field, if present, and (1) not at part of a thread tree, ** (2) at the top of a thread, or (3) `x-label' is different from ** preceding message's `x-label'. Only in mutt-1.3.8: init.h.orig diff -rU5 mutt-1.3.8-nntp/mutt.h mutt-1.3.8/mutt.h --- mutt-1.3.8-nntp/mutt.h Sun Sep 10 06:41:59 2000 +++ mutt-1.3.8/mutt.h Sun Sep 10 06:55:42 2000 @@ -211,10 +211,11 @@ #ifdef HAVE_PGP M_PGP_SIGN, M_PGP_ENCRYPT, M_PGP_KEY, #endif + M_MIMEATTACH, M_XLABEL, #ifdef USE_NNTP M_NEWSGROUPS, #endif @@ -383,10 +384,14 @@ OPTWRAP, OPTWRAPSEARCH, OPTWRITEBCC, /* write out a bcc header? */ OPTXMAILER, + OPTATINLINEOK, /* Count inline attachments? */ + OPTATCONTAINERSOK, /* Count containing messages? */ + OPTATRECURSE, /* Recurse message/\* types? */ + /* PGP options */ #ifdef HAVE_PGP OPTPGPAUTOSIGN, OPTPGPAUTOENCRYPT, @@ -774,9 +779,15 @@ #define state_puts(x,y) fputs(x,(y)->fpout) #define state_putc(x,y) fputc(x,(y)->fpout) 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" #include "globals.h" Only in mutt-1.3.8: mutt.h.orig diff -rU5 mutt-1.3.8-nntp/parse.c mutt-1.3.8/parse.c --- mutt-1.3.8-nntp/parse.c Sun Sep 10 06:41:59 2000 +++ mutt-1.3.8/parse.c Sun Sep 10 06:42:21 2000 @@ -1411,5 +1411,100 @@ else p = rfc822_parse_adrlist (p, s); 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; +} Only in mutt-1.3.8: parse.c.orig diff -rU5 mutt-1.3.8-nntp/pattern.c mutt-1.3.8/pattern.c --- mutt-1.3.8-nntp/pattern.c Sun Sep 10 06:41:59 2000 +++ mutt-1.3.8/pattern.c Sun Sep 10 07:04:11 2000 @@ -85,10 +85,11 @@ { 'S', M_SUPERSEDED, 0, NULL }, { 'T', M_TAG, 0, NULL }, { 't', M_TO, 0, eat_regexp }, { 'U', M_UNREAD, 0, NULL }, { 'v', M_COLLAPSED, 0, NULL }, + { 'V', M_MIMEATTACH, 0, eat_range }, #ifdef USE_NNTP { 'w', M_NEWSGROUPS, 0, eat_regexp }, #endif { 'x', M_REFERENCE, 0, eat_regexp }, { 'y', M_XLABEL, 0, eat_regexp }, @@ -892,10 +893,27 @@ case M_PGP_ENCRYPT: return (pat->not ^ (h->pgp & PGPENCRYPT)); 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))); + } case M_XLABEL: return (pat->not ^ (h->env->x_label && regexec (pat->rx, h->env->x_label, 0, NULL, 0) == 0)); #ifdef USE_NNTP case M_NEWSGROUPS: return (pat->not ^ (h->env->newsgroups && regexec (pat->rx, h->env->newsgroups, 0, NULL, 0) == 0)); Only in mutt-1.3.8: pattern.c.orig diff -rU5 mutt-1.3.8-nntp/protos.h mutt-1.3.8/protos.h --- mutt-1.3.8-nntp/protos.h Sun Sep 10 06:41:59 2000 +++ mutt-1.3.8/protos.h Sun Sep 10 06:42:21 2000 @@ -138,10 +138,11 @@ void mutt_block_signals_system (void); void mutt_body_handler (BODY *, STATE *); void mutt_bounce_message (FILE *fp, HEADER *, ADDRESS *); void mutt_buffy (char *); void mutt_canonical_charset (char *, size_t, const 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 *); void mutt_decode_attachment (BODY *, STATE *); void mutt_default_save (char *, size_t, HEADER *); Only in mutt-1.3.8: protos.h.orig