diff -Pur mutt-1.5.8-base/Makefile.am mutt-1.5.8-mega/Makefile.am --- mutt-1.5.8-base/Makefile.am Sat Feb 12 14:54:39 2005 +++ mutt-1.5.8-mega/Makefile.am Thu Mar 10 17:50:14 2005 @@ -18,7 +18,7 @@ bin_PROGRAMS = mutt @DOTLOCK_TARGET@ @PGPAUX_TARGET@ mutt_SOURCES = $(BUILT_SOURCES) \ addrbook.c alias.c attach.c base64.c browser.c buffy.c color.c \ - crypt.c cryptglue.c \ + compress.c crypt.c cryptglue.c \ commands.c complete.c compose.c copy.c curs_lib.c curs_main.c date.c \ edit.c enter.c flags.c init.c filter.c from.c getdomain.c \ handler.c hash.c hdrline.c headers.c help.c hook.c keymap.c \ @@ -68,6 +68,7 @@ EXTRA_DIST = COPYRIGHT GPL OPS OPS.PGP OPS.CRYPT OPS.SMIME TODO \ configure account.h \ + compress.h \ attach.h buffy.h charset.h copy.h crypthash.h dotlock.h functions.h gen_defs \ globals.h hash.h history.h init.h keymap.h mutt_crypt.h \ mailbox.h mapping.h md5.h mime.h mutt.h mutt_curses.h mutt_menu.h \ diff -Pur mutt-1.5.8-base/Makefile.in mutt-1.5.8-mega/Makefile.in --- mutt-1.5.8-base/Makefile.in Sat Feb 12 14:58:25 2005 +++ mutt-1.5.8-mega/Makefile.in Thu Mar 10 18:01:24 2005 @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.9.2 from Makefile.am. +# Makefile.in generated by automake 1.9 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, @@ -37,7 +37,6 @@ NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : -build_triplet = @build@ host_triplet = @host@ EXTRA_PROGRAMS = mutt_dotlock$(EXEEXT) pgpring$(EXEEXT) \ makedoc$(EXEEXT) @@ -75,11 +74,11 @@ am__objects_1 = patchlist.$(OBJEXT) am_mutt_OBJECTS = $(am__objects_1) addrbook.$(OBJEXT) alias.$(OBJEXT) \ attach.$(OBJEXT) base64.$(OBJEXT) browser.$(OBJEXT) \ - buffy.$(OBJEXT) color.$(OBJEXT) crypt.$(OBJEXT) \ - cryptglue.$(OBJEXT) commands.$(OBJEXT) complete.$(OBJEXT) \ - compose.$(OBJEXT) copy.$(OBJEXT) curs_lib.$(OBJEXT) \ - curs_main.$(OBJEXT) date.$(OBJEXT) edit.$(OBJEXT) \ - enter.$(OBJEXT) flags.$(OBJEXT) init.$(OBJEXT) \ + buffy.$(OBJEXT) color.$(OBJEXT) compress.$(OBJEXT) \ + crypt.$(OBJEXT) cryptglue.$(OBJEXT) commands.$(OBJEXT) \ + complete.$(OBJEXT) compose.$(OBJEXT) copy.$(OBJEXT) \ + curs_lib.$(OBJEXT) curs_main.$(OBJEXT) date.$(OBJEXT) \ + edit.$(OBJEXT) enter.$(OBJEXT) flags.$(OBJEXT) init.$(OBJEXT) \ filter.$(OBJEXT) from.$(OBJEXT) getdomain.$(OBJEXT) \ handler.$(OBJEXT) hash.$(OBJEXT) hdrline.$(OBJEXT) \ headers.$(OBJEXT) help.$(OBJEXT) hook.$(OBJEXT) \ @@ -294,7 +293,7 @@ BUILT_SOURCES = keymap_defs.h patchlist.c mutt_SOURCES = $(BUILT_SOURCES) \ addrbook.c alias.c attach.c base64.c browser.c buffy.c color.c \ - crypt.c cryptglue.c \ + compress.c crypt.c cryptglue.c \ commands.c complete.c compose.c copy.c curs_lib.c curs_main.c date.c \ edit.c enter.c flags.c init.c filter.c from.c getdomain.c \ handler.c hash.c hdrline.c headers.c help.c hook.c keymap.c \ @@ -326,6 +325,7 @@ EXTRA_DIST = COPYRIGHT GPL OPS OPS.PGP OPS.CRYPT OPS.SMIME TODO \ configure account.h \ + compress.h \ attach.h buffy.h charset.h copy.h crypthash.h dotlock.h functions.h gen_defs \ globals.h hash.h history.h init.h keymap.h mutt_crypt.h \ mailbox.h mapping.h md5.h mime.h mutt.h mutt_curses.h mutt_menu.h \ @@ -487,6 +487,7 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/commands.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/complete.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compose.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compress.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/copy.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crypt-gpgme.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crypt-mod-pgp-classic.Po@am__quote@ diff -Pur mutt-1.5.8-base/Muttrc mutt-1.5.8-mega/Muttrc --- mutt-1.5.8-base/Muttrc Sat Feb 12 14:57:47 2005 +++ mutt-1.5.8-mega/Muttrc Thu Mar 10 18:34:08 2005 @@ -15,9 +15,9 @@ macro pager \cb |urlview\n 'call urlview to extract URLs out of a message' # Show documentation when pressing F1 -macro generic "!less /usr/local/doc/mutt/manual.txt\n" "Show Mutt documentation" -macro index "!less /usr/local/doc/mutt/manual.txt\n" "Show Mutt documentation" -macro pager "!less /usr/local/doc/mutt/manual.txt\n" "Show Mutt documentation" +macro generic "!less /opt/pkgs/mutt_dev-1.5.8/doc/mutt/manual.txt\n" "Show Mutt documentation" +macro index "!less /opt/pkgs/mutt_dev-1.5.8/doc/mutt/manual.txt\n" "Show Mutt documentation" +macro pager "!less /opt/pkgs/mutt_dev-1.5.8/doc/mutt/manual.txt\n" "Show Mutt documentation" # If Mutt is unable to determine your site's domain name correctly, you can # set the default here. @@ -29,6 +29,87 @@ # set use_8bitmime ## +## *** DEFAULT SETTINGS FOR THE ATTACHMENTS PATCH *** +## + +## +## COMPATIBILITY ISSUES: +## + dgc.attach.2's $attach_count_inline_ok is supplanted by the inline-allow +## and inline-exclude parameters. +## +## + The old dgc.attach.2 $attach_count_recurse is now named $attach_recurse. +## It has the same function as before: it makes the counter recurse into +## message/rfc822 containers. +## +## + $attach_count_containers_ok no longer exists. Instead, you should +## allow/exclude message/.* and/or multipart/.* types. See the example +## below. +## +## + dgc.attach.2 always discounted the first MIME part of any message. +## Since we're more flexible now about MIME types, that's not necessarily +## the right behavior. Setting $attach_ignore_fundamental provides loose +## compatibility to the old behavior; it's on by default. + +## Recurse through MIME parts that contain other MIME parts. +set attach_recurse + +## Discount fundamental parts that are inlined and are not containers. +## (E.g., don't count the basic text/plain part that a JPEG of your +## summer vacation is attached to.) +set attach_ignore_fundamental + + +## Config parameters for the attachment counter (%X and ~X). Eight +## parameters are defined: +## attach-allow: Allow attachments of these types to be counted... +## attach-exclude: ... unless they're of these types. +## inline-allow: Allow inline parts of these types to be counted... +## inline-exclude: ... unless they're of these types. +## unattach-allow: Remove these types from the attach-allow list. +## unattach-exclude: Remove these types from the attach-exclude list. +## uninline-allow: Remove these types from the inline-allow list. +## uninline-exclude: Remove these types from the inline-exclude list. +## +## The "*" wildcard is supported for the major (left) side of the MIME +## type. The minor (right) side is a regular expression. "*/.*" matches +## anything. +## +## Removing a pattern from a list removes that pattern literally. It +## does not remove any type matching the pattern. So, for example, +## attach-allow */.* +## attach-allow image/jpeg +## unattach-allow */.* +## Leaves image/jpeg on the attach-allow list. It does not remove all +## items. + +## +## Count any MIME part with an "attachment" disposition, EXCEPT for +## text/x-vcard and application/pgp parts. (PGP parts are already known +## to mutt, and can be searched for with ~g, ~G, and ~k.) +## +## I've added x-pkcs7 to this, since it functions (for S/MIME) +## analogously to PGP signature attachments. S/MIME isn't supported +## in a stock mutt build, but we can still treat it specially here. +attach-allow */.* +attach-exclude text/x-vcard application/pgp.* +attach-exclude application/x-pkcs7-.* + +## Discount all MIME parts with an "inline" disposition, unless they're +## text/plain. (Why inline a text/plain part unless it's external to the +## message flow?) +inline-allow text/plain + +## These two lines emulate the old (dgc.attach.2) +## $attach_count_containers_ok variable. The first line is unnecessary +## if you already have "attach-allow */.*", of course. +#attach-allow message/.* multipart/.* +#inline-allow message/.* multipart/.* + +## You probably don't really care to know about deleted attachments. +attach-exclude message/external-body +inline-exclude message/external-body + +## ## More settings ## @@ -190,6 +271,8 @@ # %u unlink (=to delete) flag # %>X right justify the rest of the string and pad with character "X" # %|X pad to the end of the line with character "X" +# %*X soft-fill with character "X" as pad +# For an explanation of `soft-fill', see the ``$index_format'' documentation. # # # set attach_sep="\n" @@ -217,6 +300,28 @@ # Mutt will operate on the attachments one by one. # # +# set attach_ignore_fundamental=yes +# +# Name: attach_ignore_fundamental +# Type: boolean +# Default: yes +# +# +# If set, Mutt's attachment counter discounts the fundamental MIME +# part if its disposition is inline. +# +# +# set attach_recurse=yes +# +# Name: attach_recurse +# Type: boolean +# Default: yes +# +# +# If set, Mutt's attachment counter (%X/~X) will examine message/* +# components for attachments. +# +# # set attribution="On %d, %n wrote:" # # Name: attribution @@ -353,6 +458,19 @@ # when the current thread is uncollapsed. # # +# set uncollapse_new=yes +# +# Name: uncollapse_new +# Type: boolean +# Default: yes +# +# +# When set, Mutt will automatically uncollapse any collapsed thread +# that receives a new message. When unset, collapsed threads will +# remain collapsed. the presence of the new message will still affect +# index sorting, though. +# +# # set compose_format="-- Mutt: Compose [Approx. msg size: %l Atts: %a]%>-" # # Name: compose_format @@ -568,17 +686,6 @@ # filtered message is read from the standard output. # # -# set dotlock_program="/usr/local/bin/mutt_dotlock" -# -# Name: dotlock_program -# Type: path -# Default: "/usr/local/bin/mutt_dotlock" -# -# -# Contains the path of the mutt_dotlock (8) binary to be used by -# mutt. -# -# # set dsn_notify="" # # Name: dsn_notify @@ -729,6 +836,16 @@ # (PGP only) # # +# set flag_safe=no +# +# Name: flag_safe +# Type: boolean +# Default: no +# +# +# If set, flagged messages cannot be deleted. +# +# # set folder="~/Mail" # # Name: folder @@ -767,6 +884,8 @@ # %u owner name (or numeric uid, if missing) # %>X right justify the rest of the string and pad with character "X" # %|X pad to the end of the line with character "X" +# %*X soft-fill with character "X" as pad +# For an explanation of `soft-fill', see the ``$index_format'' documentation. # # # set followup_to=yes @@ -1316,6 +1435,7 @@ # %T the appropriate character from the $to_chars string # %u user (login) name of the author # %v first name of the author, or the recipient if the message is from you +# %X number of attachments # %y `x-label:' field, if present # %Y `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 @@ -1334,16 +1454,23 @@ # function ``strftime''; a leading bang disables locales. # %>X right justify the rest of the string and pad with character "X" # %|X pad to the end of the line with character "X" -# +# %*X soft-fill with character "X" as pad +# `Soft-fill' deserves some explanation. Normal right-justification +# will print everything to the left of the %>, displaying padding and +# the whatever lies to the right only if there's room. By contrast, +# soft-fill gives priority to the right-hand side, guaranteeing space +# to display it and showing padding only if there's still room. If +# necessary, soft-fill will eat text leftwards to make room for +# rightward text. # # See also: ``$to_chars''. # # -# set ispell="/usr/bin/ispell" +# set ispell="/opt/bin/ispell" # # Name: ispell # Type: path -# Default: "/usr/bin/ispell" +# Default: "/opt/bin/ispell" # # # How to invoke ispell (GNU's spell-checking software). @@ -1372,6 +1499,18 @@ # the strings your system accepts for the locale variable LC_TIME. # # +# set mark_macro_prefix="'" +# +# Name: mark_macro_prefix +# Type: string +# Default: "'" +# +# +# Prefix for macros created using mark-message. A new macro +# automatically generated with a will be composed +# from this prefix and the letter a. +# +# # set mail_check=5 # # Name: mail_check @@ -1409,6 +1548,33 @@ # DOING! # # +# set header_cache="" +# +# Name: header_cache +# Type: path +# Default: "" +# +# +# The header_cache variable points to the header cache database. If +# header_cache points to a directory there will be created one header cache +# database per folder within this directory. If it doesn't point to a directory a +# global header cache for all folders is used. Per default it is unset and so +# no header caching will be used. +# +# +# set header_cache_pagesize="16384" +# +# Name: header_cache_pagesize +# Type: string +# Default: "16384" +# +# +# Change the header cache database page size. Too large or to small values +# can waste space, memory, or CPU time. The default should be more or +# less the best you can get. For details google after mutt header +# cache (first hit). +# +# # set maildir_trash=no # # Name: maildir_trash @@ -1435,6 +1601,12 @@ # will show up with an "O" next to them in the index menu, # indicating that they are old. # +# If unset, messages remain new until they are read or the +# new flag is explicitly removed. See also the ``$see_old'' +# variable. +# +# N.B. This variable does not affect IMAP folders. +# # # set markers=yes # @@ -1504,6 +1676,18 @@ # when scrolling through menus. (Similar to ``$pager_context''.) # # +# set menu_move_off=no +# +# Name: menu_move_off +# Type: boolean +# Default: no +# +# +# When unset, the bottom entry of menus will never scroll up past +# the bottom of the screen, unless there are less entries than lines. +# When set, the bottom entry may move off the bottom. +# +# # set menu_scroll=no # # Name: menu_scroll @@ -1533,6 +1717,31 @@ # ``x''. # # +# set mdn_enable=no +# +# Name: mdn_enable +# Type: boolean +# Default: no +# +# +# When set, the message disposition notification support (RFC-2298) +# is enabled. This shows an extra menu entry in the composer menu and +# enables all the other MDN features. Keep it disabled to prevent any +# disposition notifications to be send. +# +# +# set mdn_confirm=no +# +# Name: mdn_confirm +# Type: boolean +# Default: no +# +# +# When set, a confirmation to send a message disposition +# notification is always requested. When unset, a confirmation is +# only requested for suspect messages as demanded by RFC-2298. +# +# # set mh_purge=no # # Name: mh_purge @@ -1566,6 +1775,17 @@ # The name of the MH sequence used to tag replied messages. # # +# set mh_seq_mdnsent="mdnsent" +# +# Name: mh_seq_mdnsent +# Type: string +# Default: "mdnsent" +# +# +# The name of the MH sequence used to mark messages for whom a +# message disposition notice has already been sent. +# +# # set mh_seq_unseen="unseen" # # Name: mh_seq_unseen @@ -3248,6 +3468,18 @@ # Also see the ``$force_name'' variable. # # +# set see_old=yes +# +# Name: see_old +# Type: boolean +# Default: yes +# +# +# Controls whether or not Mutt makes the distinction between new +# messages and old unread messages. In order to make Mutt +# treat all unread messages as new only, you can unset this variable. +# +# # set score=yes # # Name: score @@ -3313,11 +3545,11 @@ # "iso-8859-1". # # -# set sendmail="/usr/sbin/sendmail -oem -oi" +# set sendmail="/usr/lib/sendmail -oem -oi" # # Name: sendmail # Type: path -# Default: "/usr/sbin/sendmail -oem -oi" +# Default: "/usr/lib/sendmail -oem -oi" # # # Specifies the program and arguments used to deliver mail sent by Mutt. @@ -3633,7 +3865,8 @@ # %V currently active limit pattern, if any * # %>X right justify the rest of the string and pad with "X" # %|X pad to the end of the line with "X" -# +# %*X soft-fill with character "X" as pad +# For an explanation of `soft-fill', see the ``$index_format'' documentation. # # * = can be optionally printed if nonzero # @@ -3859,18 +4092,6 @@ # sending messages. If unset, no `From:' header field will be # generated unless the user explicitly sets one using the ``my_hdr'' # command. -# -# -# set use_idn=yes -# -# Name: use_idn -# Type: boolean -# Default: yes -# -# -# When set, Mutt will show you international domain names decoded. -# Note: You can use IDNs for addresses even if this is unset. -# This variable only affects decoding. # # # set use_ipv6=yes Only in mutt-1.5.8-base: Muttrc.head diff -Pur mutt-1.5.8-base/Muttrc.head.in mutt-1.5.8-mega/Muttrc.head.in --- mutt-1.5.8-base/Muttrc.head.in Thu Jan 24 06:10:47 2002 +++ mutt-1.5.8-mega/Muttrc.head.in Thu Mar 10 17:50:13 2005 @@ -29,6 +29,87 @@ # set use_8bitmime ## +## *** DEFAULT SETTINGS FOR THE ATTACHMENTS PATCH *** +## + +## +## COMPATIBILITY ISSUES: +## + dgc.attach.2's $attach_count_inline_ok is supplanted by the inline-allow +## and inline-exclude parameters. +## +## + The old dgc.attach.2 $attach_count_recurse is now named $attach_recurse. +## It has the same function as before: it makes the counter recurse into +## message/rfc822 containers. +## +## + $attach_count_containers_ok no longer exists. Instead, you should +## allow/exclude message/.* and/or multipart/.* types. See the example +## below. +## +## + dgc.attach.2 always discounted the first MIME part of any message. +## Since we're more flexible now about MIME types, that's not necessarily +## the right behavior. Setting $attach_ignore_fundamental provides loose +## compatibility to the old behavior; it's on by default. + +## Recurse through MIME parts that contain other MIME parts. +set attach_recurse + +## Discount fundamental parts that are inlined and are not containers. +## (E.g., don't count the basic text/plain part that a JPEG of your +## summer vacation is attached to.) +set attach_ignore_fundamental + + +## Config parameters for the attachment counter (%X and ~X). Eight +## parameters are defined: +## attach-allow: Allow attachments of these types to be counted... +## attach-exclude: ... unless they're of these types. +## inline-allow: Allow inline parts of these types to be counted... +## inline-exclude: ... unless they're of these types. +## unattach-allow: Remove these types from the attach-allow list. +## unattach-exclude: Remove these types from the attach-exclude list. +## uninline-allow: Remove these types from the inline-allow list. +## uninline-exclude: Remove these types from the inline-exclude list. +## +## The "*" wildcard is supported for the major (left) side of the MIME +## type. The minor (right) side is a regular expression. "*/.*" matches +## anything. +## +## Removing a pattern from a list removes that pattern literally. It +## does not remove any type matching the pattern. So, for example, +## attach-allow */.* +## attach-allow image/jpeg +## unattach-allow */.* +## Leaves image/jpeg on the attach-allow list. It does not remove all +## items. + +## +## Count any MIME part with an "attachment" disposition, EXCEPT for +## text/x-vcard and application/pgp parts. (PGP parts are already known +## to mutt, and can be searched for with ~g, ~G, and ~k.) +## +## I've added x-pkcs7 to this, since it functions (for S/MIME) +## analogously to PGP signature attachments. S/MIME isn't supported +## in a stock mutt build, but we can still treat it specially here. +attach-allow */.* +attach-exclude text/x-vcard application/pgp.* +attach-exclude application/x-pkcs7-.* + +## Discount all MIME parts with an "inline" disposition, unless they're +## text/plain. (Why inline a text/plain part unless it's external to the +## message flow?) +inline-allow text/plain + +## These two lines emulate the old (dgc.attach.2) +## $attach_count_containers_ok variable. The first line is unnecessary +## if you already have "attach-allow */.*", of course. +#attach-allow message/.* multipart/.* +#inline-allow message/.* multipart/.* + +## You probably don't really care to know about deleted attachments. +attach-exclude message/external-body +inline-exclude message/external-body + +## ## More settings ## diff -Pur mutt-1.5.8-base/OPS mutt-1.5.8-mega/OPS --- mutt-1.5.8-base/OPS Fri Jul 4 12:07:11 2003 +++ mutt-1.5.8-mega/OPS Thu Mar 10 17:51:39 2005 @@ -27,12 +27,16 @@ OP_COMPOSE_EDIT_MESSAGE "edit the message" OP_COMPOSE_EDIT_MIME "edit attachment using mailcap entry" OP_COMPOSE_EDIT_REPLY_TO "edit the Reply-To field" +OP_COMPOSE_EDIT_DNT "edit the Disposition-Notification-To field" OP_COMPOSE_EDIT_SUBJECT "edit the subject of this message" OP_COMPOSE_EDIT_TO "edit the TO list" OP_CREATE_MAILBOX "create a new mailbox (IMAP only)" OP_EDIT_TYPE "edit attachment content type" OP_COMPOSE_GET_ATTACHMENT "get a temporary copy of an attachment" +OP_COMPOSE_GROUP_ALTS "group tagged attachments as multipart/alternative" OP_COMPOSE_ISPELL "run ispell on the message" +OP_COMPOSE_MOVE_UP "move an attachment up in the attachment list" +OP_COMPOSE_MOVE_DOWN "move an attachment down in the attachment list" OP_COMPOSE_NEW_MIME "compose new attachment using mailcap entry" OP_COMPOSE_TOGGLE_RECODE "toggle recoding of this attachment" OP_COMPOSE_POSTPONE_MESSAGE "save this message to send later" @@ -42,6 +46,7 @@ OP_COMPOSE_TOGGLE_UNLINK "toggle whether to delete file after sending it" OP_COMPOSE_UPDATE_ENCODING "update an attachment's encoding info" OP_COMPOSE_WRITE_MESSAGE "write the message to a folder" +OP_COMPOSE_SWITCH_DNT "switch between Disposition-Notification-To defaults" OP_COPY_MESSAGE "copy a message to a file/mailbox" OP_CREATE_ALIAS "create an alias from a message sender" OP_CURRENT_BOTTOM "move entry to bottom of screen" @@ -56,6 +61,7 @@ OP_DISPLAY_ADDRESS "display full address of sender" OP_DISPLAY_HEADERS "display message and toggle header weeding" OP_DISPLAY_MESSAGE "display a message" +OP_EDIT_LABEL "add, change, or delete a message's label" OP_EDIT_MESSAGE "edit the raw message" OP_EDITOR_BACKSPACE "delete the char in front of the cursor" OP_EDITOR_BACKWARD_CHAR "move the cursor one character to the left" @@ -96,6 +102,7 @@ OP_LIST_REPLY "reply to specified mailing list" OP_MACRO "execute a macro" OP_MAIL "compose a new mail message" +OP_MAIN_BREAK_THREAD "break the thread in two" OP_MAIN_CHANGE_FOLDER "open a different folder" OP_MAIN_CHANGE_FOLDER_READONLY "open a different folder in read only mode" OP_MAIN_CLEAR_FLAG "clear a status flag from a message" @@ -105,6 +112,7 @@ OP_MAIN_FIRST_MESSAGE "move to the first message" OP_MAIN_LAST_MESSAGE "move to the last message" OP_MAIN_LIMIT "show only messages matching a pattern" +OP_MAIN_LINK_THREADS "link tagged message to the current one" OP_MAIN_NEXT_NEW "jump to the next new message" OP_MAIN_NEXT_NEW_THEN_UNREAD "jump to the next new or unread message" OP_MAIN_NEXT_SUBTHREAD "jump to the next subthread" @@ -125,6 +133,7 @@ OP_MAIN_TAG_PATTERN "tag messages matching a pattern" OP_MAIN_UNDELETE_PATTERN "undelete messages matching a pattern" OP_MAIN_UNTAG_PATTERN "untag messages matching a pattern" +OP_MARK_MSG "create a hot-key macro for the current message" OP_MIDDLE_PAGE "move to the middle of the page" OP_NEXT_ENTRY "move to the next entry" OP_NEXT_LINE "scroll down one line" diff -Pur mutt-1.5.8-base/PATCHES mutt-1.5.8-mega/PATCHES --- mutt-1.5.8-base/PATCHES Wed Dec 31 18:00:00 1969 +++ mutt-1.5.8-mega/PATCHES Thu Mar 10 18:31:05 2005 @@ -0,0 +1,17 @@ +patch-1.5.8.ats.parent_match.1 +patch-1.5.8.cb.menu_context.8 +patch-1.5.8.dgc.xlabel_ext.7 +patch-1.5.8.g10.mdn.3 +patch-1.5.8.dgc.setenv.1 +patch-1.5.8.dgc.softfill.3 +patch-1.5.8.dgc.flagsafe.1 +patch-1.5.8.dgc.fmtpipe.1 +patch-1.5.8.dgc.markmsg.2 +patch-1.5.8.dgc.deepif.1 +patch-1.5.8.dgc.groupalts.2 +rr.compressed +patch-1.5.8.dgc.attach.5 +patch-1.5.8.cd.edit_threads.9.5 +patch-1.5.8.dgc.uncollapsenew.1 +patch-1.5.8.ats.mark_old.1.5 +patch-1.5.8.ats.date_conditional.1 diff -Pur mutt-1.5.8-base/aclocal.m4 mutt-1.5.8-mega/aclocal.m4 --- mutt-1.5.8-base/aclocal.m4 Sat Feb 12 14:57:23 2005 +++ mutt-1.5.8-mega/aclocal.m4 Thu Mar 10 17:53:24 2005 @@ -1,4 +1,4 @@ -# generated automatically by aclocal 1.9.2 -*- Autoconf -*- +# generated automatically by aclocal 1.9 -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 # Free Software Foundation, Inc. @@ -40,7 +40,7 @@ # Call AM_AUTOMAKE_VERSION so it can be traced. # This function is AC_REQUIREd by AC_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], - [AM_AUTOMAKE_VERSION([1.9.2])]) + [AM_AUTOMAKE_VERSION([1.9])]) # AM_AUX_DIR_EXPAND diff -Pur mutt-1.5.8-base/alias.c mutt-1.5.8-mega/alias.c --- mutt-1.5.8-base/alias.c Sat Feb 12 12:53:32 2005 +++ mutt-1.5.8-mega/alias.c Thu Mar 10 17:50:19 2005 @@ -140,6 +140,7 @@ env->cc = mutt_expand_aliases (env->cc); env->bcc = mutt_expand_aliases (env->bcc); env->reply_to = mutt_expand_aliases (env->reply_to); + env->dnt = mutt_expand_aliases (env->dnt); env->mail_followup_to = mutt_expand_aliases (env->mail_followup_to); } diff -Pur mutt-1.5.8-base/buffy.c mutt-1.5.8-mega/buffy.c --- mutt-1.5.8-base/buffy.c Thu Feb 3 12:47:52 2005 +++ mutt-1.5.8-mega/buffy.c Thu Mar 10 17:50:10 2005 @@ -107,7 +107,7 @@ hdr = mutt_new_header (); tmp_envelope = mutt_read_rfc822_header (f, hdr, 0, 0); - if (!(hdr->read || hdr->old)) + if (!(hdr->read || (option(OPTSEEOLD) && hdr->old))) result = 1; mutt_free_envelope(&tmp_envelope); diff -Pur mutt-1.5.8-base/commands.c mutt-1.5.8-mega/commands.c --- mutt-1.5.8-base/commands.c Sat Feb 12 13:22:15 2005 +++ mutt-1.5.8-mega/commands.c Thu Mar 10 17:50:19 2005 @@ -32,6 +32,7 @@ #include "pager.h" #include "mutt_crypt.h" #include "mutt_idna.h" +#include "rfc2047.h" #include #include #include @@ -58,6 +59,311 @@ /* The folder the user last saved to. Used by ci_save_message() */ static char LastSaveFolder[_POSIX_PATH_MAX] = ""; +static int is_in_mdn_list (ADDRESS *addr, LIST *p) +{ + if (addr->mailbox) + { + for (;p; p = p->next) + if (!mutt_strncasecmp (addr->mailbox, p->data, mutt_strlen (p->data))) + return 1; + } + return 0; +} + +/* Compare 2 addresses. Thisactually should do a case-insensitive + compare on the mailbox part (according to rfc-2298) but we ignore + that because case sensitive mailboxes are not common. + + FIXME: There is a similar but static function in send.c: mutt_addrcmp. + */ +static int address_compare (ADDRESS *a, ADDRESS *b) +{ + if (!a->mailbox || !b->mailbox) + return-1; + return ascii_strcasecmp (a->mailbox, b->mailbox); +} + +static void write_address (FILE *fp, const char *tag, const char *prefix, + ADDRESS *a, int qualify) +{ + const char *fqdn = mutt_fqdn (1); + char buffer[STRING]; + ADDRESS *aa; + + aa = rfc822_cpy_adr (a); + if (fqdn && qualify) + rfc822_qualify (aa, fqdn); + rfc2047_encode_adrlist (aa, tag); + *buffer = 0; + rfc822_write_address (buffer, sizeof (buffer), aa, 1); + rfc822_free_address (&aa); + + fprintf (fp, "%s: %s%s\n", tag, prefix, buffer); +} + + + + +/* Record that the MDN as already been sent. */ +static void mark_mdn_done (HEADER *cur) +{ + /* Hmmm: How should this be done. IMHO the New Message mark should + be sufficient but it is not exactly what we want: IF one select + "ignore for now" the message will be flaged as old but the MDN + was not sent and the next time it gets displayed, there won't be + an indication whether it should be sent or not. Also automatic + tools won't be able to detect that status. */ + mutt_set_flag (Context, cur, M_MDNSENT, 1); +} + +/* Construct a Message Disposition Notiifcation and send it out. */ +static void mutt_send_mdn (HEADER *cur, int confirmed, ADDRESS *dnt) +{ + char fnamebuf[LONG_STRING]; + FILE *fp; + HEADER *msg; + BODY *t; + char current_date_buf[SHORT_STRING], *current_date; + ADDRESS *addr; + + mutt_make_date (current_date_buf, sizeof (current_date_buf)); + current_date = current_date_buf; + current_date += strncmp (current_date_buf, "Date: ",6)? 0:6; + if (*current_date && current_date[strlen(current_date)-1] =='\n') + current_date[strlen(current_date)-1] = 0; + + msg = mutt_new_header (); + msg->env = mutt_new_envelope (); + msg->env->to = dnt; /* Note that this is not a copy! */ + msg->env->subject = safe_strdup ("Disposition notification"); + + t = mutt_new_body (); + msg->content = t; + t->type = TYPEMULTIPART; + t->subtype = safe_strdup ("report"); + t->encoding = ENC7BIT; + t->use_disp = 0; + t->disposition = DISPINLINE; + mutt_generate_boundary (&t->parameter); + mutt_set_parameter ("report-type", "disposition-notification", + &t->parameter); + + t->parts = mutt_new_body (); + t = t->parts; + t->type = TYPETEXT; + t->subtype = safe_strdup ("plain"); + t->use_disp = 0; + t->disposition = DISPINLINE; + t->encoding = ENC7BIT; + mutt_mktemp (fnamebuf); + t->filename = safe_strdup (fnamebuf); + t->unlink = 1; + if (!(fp = safe_fopen (t->filename, "w"))) + { + mutt_perror (t->filename); + /* fixme: cleanup */ + return; + } + fprintf (fp, "Original message info:\n\n"); + if (cur->env->date) + fprintf (fp, " Date: %s\n", cur->env->date); + if (cur->env->to) + write_address (fp, " To", "", cur->env->to, 0); + if (cur->env->subject) + fprintf (fp, " Subject: %s\n", cur->env->subject); + fprintf (fp, "\n" + "The message has been displayed at %s.\n" + "This is no guarantee that the message has been read or understood.\n\n", + current_date); + fclose (fp); + + + t->next = mutt_new_body (); + t = t->next; + t->type = TYPEMESSAGE; + t->subtype = safe_strdup ("disposition-notification"); + t->use_disp = 0; + t->disposition = DISPINLINE; + t->encoding = ENC7BIT; + mutt_mktemp (fnamebuf); + t->filename = safe_strdup (fnamebuf); + t->unlink = 1; + if (!(fp = safe_fopen (t->filename, "w"))) + { + mutt_perror (t->filename); + /* fixme: cleanup */ + return; + } + + fprintf (fp, "Reporting-UA: %s; Mutt/%s\n", Fqdn, MUTT_VERSION); + /*fprintf (fp, "Original-Recipient: rfc822;%s\n");*/ + + + addr = NULL; + { + LIST *uh = UserHeader; + + for (; uh; uh = uh->next) + { + if (!ascii_strncasecmp ("from:", uh->data, 5)) + { /* User has specified a default From: address. This has priority. */ + addr = rfc822_parse_adrlist (addr, uh->data + 5); + break; + } + } + } + if (!addr) + addr = mutt_default_from (); + + write_address (fp, "Final-Recipient", "rfc822;", addr, 1); + rfc822_free_address (&msg->env->from); + msg->env->from = addr; + + if (cur->env->message_id) + fprintf (fp, "Original-Message-ID: %s\n", cur->env->message_id); + + fprintf (fp, "Disposition: manual-action/MDN-sent-%s; displayed\n", + confirmed? "manually":"automatically"); + fclose (fp); + + if (!mutt_send_message_direct (msg, 1)) + mutt_message (_("Message Disposition Notification sent.")); + + msg->env->to = NULL; /* we didn't used a copy */ + mutt_free_envelope (&msg->env); msg->env = NULL; + + mark_mdn_done (cur); +} + + +/* Have a look at the current message and decide whether a MDN should + be sent. Return true if the user selected to ignore it for now. */ +int mutt_handle_mdn (HEADER *cur) +{ + int must_ask = 0; + int ask_this = 0; + int unknown_required = 0; + int confirmed = 0; + PARAMETER *parm; + ADDRESS *dnt_addr = NULL; + ADDRESS *a; + + if (!option (OPTMDNENABLE) ) + return 0; /* MDN support not enabled */ + + /* Do we have a notification header? */ + if (!cur->env || !cur->env->dnt) + return 0; /* Nothing to do. */ + if (cur->mdnsent) + return 0; /* Already sent. */ + + /* Check whether one of the notification addresses is in the deny + list. Add all non-denied addresses to a new list. */ + for (a = cur->env->dnt; a; a = a->next) + { + if (!is_in_mdn_list (a, MdnDeny)) + { + ADDRESS *aa = rfc822_cpy_adr_real (a); + rfc822_append (&dnt_addr, aa); + rfc822_free_address (&aa); + } + } + + if (!dnt_addr) + { + mark_mdn_done (cur); + return 0; /* All addresses are in the deny list. */ + } + + /* Check whether we can handle all required options. RFC2298 does + not define any yet, but we must be prepared for future extensions + and X-foo attributes. */ + for (parm=cur->env->dno; parm; parm = parm->next) + { + if (!ascii_strcasecmp (parm->value, "required")) + unknown_required = 1; + else if (ascii_strcasecmp (parm->value, "optional")) + must_ask = 1; /* invalid importance value */ + } + + if (unknown_required) + { + /* We don't sent a failed messages at all. */ + mark_mdn_done (cur); + mutt_message (_("Required Disposition Notification Option unknown " + "- DNT ignored")); + rfc822_free_address (&dnt_addr); + return 0; + } + + + /* Check that the Return-Path matches the DNT, a Return-Path exists + and that it does not comtain more than one address.*/ + if (dnt_addr->next) + must_ask = 1; /* More than one address. */ + else if (!cur->env->return_path) + must_ask = 1; + else if (cur->env->return_path->next) + must_ask = 1; + else if (address_compare (dnt_addr, cur->env->return_path)) + must_ask = 1; /* Addresses don't match. */ + else if ( option (OPTMDNCONFIRM) ) + ask_this = 1; + + /* Check the allow list, which overrides the above. */ + if (must_ask || ask_this) + { + for (a = dnt_addr; a; a = a->next) + if (!is_in_mdn_list (a, MdnAllow)) + break; + if (!a) /* All addresses are in the allow list. */ + must_ask = ask_this = 0; + } + + + /* Get confirmation if required. */ + if (must_ask) + { + switch (mutt_yesorno (_("Disposition-Notification request is questionable." + " Really send?"), M_NO)) + { + case M_YES: + break; + case M_NO: + mark_mdn_done (cur); + rfc822_free_address (&dnt_addr); + return 0; + default: + /* ^G */ + rfc822_free_address (&dnt_addr); + return 1; /* ignore/postponed */ + } + confirmed = 1; + } + else if (ask_this) + { + switch (mutt_yesorno (_("Disposition-Notification requested. " + "Send?"), M_YES)) + { + case M_YES: + break; + case M_NO: + mark_mdn_done (cur); + rfc822_free_address (&dnt_addr); + return 0; + default: + /* ^G */ + rfc822_free_address (&dnt_addr); + return 1; /* ignore/postponed */ + } + confirmed = 1; + } + + mutt_send_mdn (cur, confirmed, dnt_addr); + rfc822_free_address (&dnt_addr); + return 0; +} + int mutt_display_message (HEADER *cur) { char tempfile[_POSIX_PATH_MAX], buf[LONG_STRING]; @@ -157,6 +463,8 @@ return 0; } + mutt_handle_mdn (cur); + if (fpfilterout != NULL && mutt_wait_filter (filterpid) != 0) mutt_any_key_to_continue (NULL); @@ -284,7 +592,7 @@ if (mutt_strwidth (prompt) > COLS - extra_space) { mutt_format_string (prompt, sizeof (prompt), - 0, COLS-extra_space, 0, 0, + 0, COLS-extra_space, FMT_LEFT, 0, prompt, sizeof (prompt), 0); safe_strcat (prompt, sizeof (prompt), "...?"); } diff -Pur mutt-1.5.8-base/compose.c mutt-1.5.8-mega/compose.c --- mutt-1.5.8-base/compose.c Thu Feb 3 12:47:52 2005 +++ mutt-1.5.8-mega/compose.c Thu Mar 10 17:50:19 2005 @@ -59,6 +59,7 @@ HDR_SUBJECT, HDR_REPLYTO, HDR_FCC, + HDR_DNT, /* Disposition-Notification-To */ #ifdef MIXMASTER HDR_MIX, @@ -67,7 +68,7 @@ HDR_CRYPT, HDR_CRYPTINFO, - HDR_ATTACH = (HDR_FCC + 5) /* where to start printing the attachments */ + HDR_ATTACH = (HDR_DNT + 5) /* where to start printing the attachments */ }; #define HDR_XOFFSET 10 @@ -82,7 +83,8 @@ "Bcc: ", "Subject: ", "Reply-To: ", - "Fcc: " + "Fcc: ", + "Dnt: " }; static struct mapping_t ComposeHelp[] = { @@ -214,6 +216,8 @@ for (i = 0; i < idxlen; i++) { + if (idx[i]->content->type == TYPEMULTIPART) + continue; strfcpy(pretty, idx[i]->content->filename, sizeof(pretty)); if(stat(idx[i]->content->filename, &st) != 0) { @@ -260,6 +264,8 @@ draw_envelope_addr (HDR_REPLYTO, msg->env->reply_to); mvprintw (HDR_FCC, 0, TITLE_FMT, Prompts[HDR_FCC - 1]); mutt_paddstr (W, fcc); + if (option(OPTMDNENABLE)) + draw_envelope_addr (HDR_DNT, msg->env->dnt); if (WithCrypto) redraw_crypt_lines (msg); @@ -313,6 +319,47 @@ return 0; } +static int switch_to_next_dnt (int line, ADDRESS **addr, int *current_dnt) +{ + char buf[HUGE_STRING] = ""; /* needs to be large for alias expansion */ + LIST *p; + int i, idx = *current_dnt + 1; + + if (!MdnDntDefaults) + return 0; + + rfc822_free_address (addr); + p = MdnDntDefaults; + for (i = 0; i < idx; i++) + { + p = p->next; + if (!p) + break; + } + if (!p) + idx = -1; + *current_dnt = idx; + + if (!p || !p->data || !strcmp (p->data, "none") ) + *addr = mutt_parse_adrlist (*addr, ""); + else + *addr = mutt_parse_adrlist (*addr, p->data); + + if (option (OPTNEEDREDRAW)) + { + unset_option (OPTNEEDREDRAW); + return (REDRAW_FULL); + } + + /* redraw the expanded list so the user can see the result */ + buf[0] = 0; + rfc822_write_address (buf, sizeof (buf), *addr, 1); + move (line, HDR_XOFFSET); + mutt_paddstr (W, buf); + + return 0; +} + static int delete_attachment (MUTTMENU *menu, short *idxlen, int x) { ATTACHPTR **idx = (ATTACHPTR **) menu->data; @@ -361,6 +408,43 @@ } +/* + * compose_attach_swap: swap two adjacent entries in the attachment list. + */ +static void compose_attach_swap (BODY *msg, ATTACHPTR **idx, short first) +{ + int i; + void *saved; + BODY *part; + + /* Reorder BODY pointers. + * Must traverse msg from top since BODY * has no previous ptr. + */ + for (part = msg; part; part = part->next) + { + if (part->next == idx[first]->content) + { + idx[first]->content->next = idx[first+1]->content->next; + idx[first+1]->content->next = idx[first]->content; + part->next = idx[first+1]->content; + break; + } + } + + /* Reorder index */ + saved = idx[first]; + idx[first] = idx[first+1]; + idx[first+1] = saved; + + /* Swap ptr->num */ + i = idx[first]->num; + idx[first]->num = idx[first+1]->num; + idx[first+1]->num = i; + + return; +} + + /* * cum_attachs_size: Cumulative Attachments Size * @@ -507,6 +591,7 @@ /* Sort, SortAux could be changed in mutt_index_menu() */ int oldSort, oldSortAux; struct stat st; + int current_dnt = -1; mutt_attach_init (msg->content); idx = mutt_gen_attach_list (msg->content, -1, idx, &idxlen, &idxmax, 0, 1); @@ -520,6 +605,20 @@ menu->data = idx; menu->help = mutt_compile_help (helpstr, sizeof (helpstr), MENU_COMPOSE, ComposeHelp); + if ( option(OPTMDNENABLE) && MdnDntDefaults && MdnDntDefaults->data + && !(msg->env->dnt && msg->env->dnt->mailbox + && *msg->env->dnt->mailbox)) + { + rfc822_free_address (&msg->env->dnt); + if (!MdnDntDefaults || !MdnDntDefaults->data + || !strcmp (MdnDntDefaults->data, "none") ) + msg->env->dnt = mutt_parse_adrlist (msg->env->dnt, ""); + else + msg->env->dnt = mutt_parse_adrlist (msg->env->dnt, + MdnDntDefaults->data); + current_dnt++; + } + while (loop) { switch (op = mutt_menuLoop (menu)) @@ -577,6 +676,15 @@ MAYBE_REDRAW (menu->redraw); mutt_message_hook (NULL, msg, M_SEND2HOOK); break; + case OP_COMPOSE_EDIT_DNT: + if (option (OPTMDNENABLE)) + menu->redraw = edit_address_list (HDR_DNT, &msg->env->dnt); + break; + case OP_COMPOSE_SWITCH_DNT: + if (option (OPTMDNENABLE)) + menu->redraw = switch_to_next_dnt (HDR_DNT, &msg->env->dnt, + ¤t_dnt); + break; case OP_COMPOSE_EDIT_MESSAGE: if (Editor && (mutt_strcmp ("builtin", Editor) != 0) && !option (OPTEDITHDRS)) { @@ -658,6 +766,132 @@ mutt_message_hook (NULL, msg, M_SEND2HOOK); break; + + case OP_COMPOSE_MOVE_UP: + if (menu->current == 0) + { + mutt_error(_("Attachment is already at top.")); + break; + } + if (menu->current == 1) + { + mutt_error(_("The fundamental part cannot be moved.")); + break; + } + compose_attach_swap(msg->content, idx, menu->current - 1); + menu->redraw = 1; + menu->current--; + break; + + + case OP_COMPOSE_MOVE_DOWN: + if (menu->current == idxlen-1) + { + mutt_error(_("Attachment is already at bottom.")); + break; + } + if (menu->current == 0) + { + mutt_error(_("The fundamental part cannot be moved.")); + break; + } + compose_attach_swap(msg->content, idx, menu->current); + menu->redraw = 1; + menu->current++; + break; + + case OP_COMPOSE_GROUP_ALTS: + { + BODY *group, *bptr, *alts; + ATTACHPTR *gptr; + int i, j; + char *p; + + if (menu->tagged < 2) + { + mutt_error(_("Grouping alternatives requires at least 2 tagged messages.")); + break; + } + +/* need to redo using mutt_gen_attach_list() */ + + group = safe_calloc(1, sizeof(BODY)); + group->type = TYPEMULTIPART; + group->subtype = "alternative"; + + alts = NULL; + for (i = 0, bptr = msg->content; bptr && bptr->next;) + { + /* always look at bptr->next, not bptr itself */ + if (bptr->next->tagged) + { + /* untag */ + bptr->next->tagged = 0; + + /* for first match, set group desc according to match */ +# define ALTS_TAG "Alternatives for \"%s\"" + if (!group->description) + { + p = bptr->next->description; + if (!p) + p = bptr->next->filename; + if (p) + { + group->description = safe_calloc(1, + strlen(p) + strlen(ALTS_TAG) + 1); + sprintf(group->description, ALTS_TAG, p); + } + } + + /* append bptr->next to the alts list, + * and remove from the msg->content list */ + if (alts == NULL) + { + group->parts = alts = bptr->next; + bptr->next = bptr->next->next; + alts->next = NULL; + } + else + { + alts->next = bptr->next; + bptr->next = bptr->next->next; + alts = alts->next; + alts->next = NULL; + } + + /* now delink the idx entry */ + for (j = i+1; j < idxlen-1; ++j) + { + idx[j] = idx[j+1]; + } + --idxlen; + } + else + { + bptr = bptr->next; + ++i; + } + } + + /* add group to attachment list */ + for (bptr = msg->content; bptr->next; bptr = bptr->next); + bptr->next = group; + group->next = NULL; + + gptr = safe_calloc(1, sizeof(ATTACHPTR)); + gptr->content = group; + idx[idxlen] = gptr; + update_idx(menu, idx, idxlen++); + + /* add a boundary */ + mutt_generate_boundary(&group->parameter); + + /* if no group desc yet, make one up */ + if (!group->description) + group->description = strdup("unknown alternative group"); + } + menu->redraw = 1; + break; case OP_COMPOSE_ATTACH_FILE: { diff -Pur mutt-1.5.8-base/compress.c mutt-1.5.8-mega/compress.c --- mutt-1.5.8-base/compress.c Wed Dec 31 18:00:00 1969 +++ mutt-1.5.8-mega/compress.c Thu Mar 10 17:50:15 2005 @@ -0,0 +1,490 @@ +/* + * Copyright (C) 1997 Alain Penders + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "mutt.h" + +#ifdef USE_COMPRESSED + +#include "mx.h" +#include "mailbox.h" +#include "mutt_curses.h" + +#include +#include +#include +#include + +typedef struct +{ + const char *close; /* close-hook command */ + const char *open; /* open-hook command */ + const char *append; /* append-hook command */ + off_t size; /* size of real folder */ +} COMPRESS_INFO; + +char echo_cmd[HUGE_STRING]; + +/* parameters: + * ctx - context to lock + * excl - exclusive lock? + * retry - should retry if unable to lock? + */ +int mbox_lock_compressed (CONTEXT *ctx, FILE *fp, int excl, int retry) +{ + int r; + + if ((r = mx_lock_file (ctx->realpath, fileno (fp), excl, 1, retry)) == 0) + ctx->locked = 1; + else if (retry && !excl) + { + ctx->readonly = 1; + return 0; + } + + return (r); +} + +void mbox_unlock_compressed (CONTEXT *ctx, FILE *fp) +{ + if (ctx->locked) + { + fflush (fp); + + mx_unlock_file (ctx->realpath, fileno (fp), 1); + ctx->locked = 0; + } +} + +static int is_new (const char *path) +{ + return (access (path, W_OK) != 0 && errno == ENOENT) ? 1 : 0; +} + +static const char* find_compress_hook (int type, const char *path) +{ + const char* c = mutt_find_hook (type, path); + return (!c || !*c) ? NULL : c; +} + +int mutt_can_read_compressed (const char *path) +{ + return find_compress_hook (M_OPENHOOK, path) ? 1 : 0; +} + +/* if the file is new, we really do not append, but create, and so use + * close-hook, and not append-hook + */ +static const char* get_append_command (const char *path, const CONTEXT* ctx) +{ + COMPRESS_INFO *ci = (COMPRESS_INFO *) ctx->compressinfo; + return (is_new (path)) ? ci->close : ci->append; +} + +int mutt_can_append_compressed (const char *path) +{ + int magic; + + if (is_new (path)) + return (find_compress_hook (M_CLOSEHOOK, path) ? 1 : 0); + + magic = mx_get_magic (path); + + if (magic != 0 && magic != M_COMPRESSED) + return 0; + + return (find_compress_hook (M_APPENDHOOK, path) + || (find_compress_hook (M_OPENHOOK, path) + && find_compress_hook (M_CLOSEHOOK, path))) ? 1 : 0; +} + +/* open a compressed mailbox */ +static COMPRESS_INFO *set_compress_info (CONTEXT *ctx) +{ + COMPRESS_INFO *ci; + + /* Now lets uncompress this thing */ + ci = safe_malloc (sizeof (COMPRESS_INFO)); + ctx->compressinfo = (void*) ci; + ci->append = find_compress_hook (M_APPENDHOOK, ctx->path); + ci->open = find_compress_hook (M_OPENHOOK, ctx->path); + ci->close = find_compress_hook (M_CLOSEHOOK, ctx->path); + return ci; +} + +static void set_path (CONTEXT* ctx) +{ + char tmppath[_POSIX_PATH_MAX]; + + /* Setup the right paths */ + ctx->realpath = ctx->path; + + /* Uncompress to /tmp */ + mutt_mktemp (tmppath); + ctx->path = safe_malloc (strlen (tmppath) + 1); + strcpy (ctx->path, tmppath); +} + +static int get_size (const char* path) +{ + struct stat sb; + if (stat (path, &sb) != 0) + return 0; + return (sb.st_size); +} + +static void store_size (CONTEXT* ctx) +{ + COMPRESS_INFO *ci = (COMPRESS_INFO *) ctx->compressinfo; + ci->size = get_size (ctx->realpath); +} + +static const char * +compresshook_format_str (char *dest, size_t destlen, char op, const char *src, + const char *fmt, const char *ifstring, + const char *elsestring, unsigned long data, + format_flag flags) +{ + char tmp[SHORT_STRING]; + + CONTEXT *ctx = (CONTEXT *) data; + switch (op) + { + case 'f': + snprintf (tmp, sizeof (tmp), "%%%ss", fmt); + snprintf (dest, destlen, tmp, ctx->realpath); + break; + case 't': + snprintf (tmp, sizeof (tmp), "%%%ss", fmt); + snprintf (dest, destlen, tmp, ctx->path); + break; + } + return (src); +} + +/* check that the command has both %f and %t + * 0 means OK, -1 means error + */ +int mutt_test_compress_command (const char* cmd) +{ + return (strstr (cmd, "%f") && strstr (cmd, "%t")) ? 0 : -1; +} + +static char *get_compression_cmd (const char* cmd, const CONTEXT* ctx) +{ + char expanded[_POSIX_PATH_MAX]; + mutt_FormatString (expanded, sizeof (expanded), cmd, compresshook_format_str, + (unsigned long) ctx, 0); + return safe_strdup (expanded); +} + +int mutt_check_mailbox_compressed (CONTEXT* ctx) +{ + COMPRESS_INFO *ci = (COMPRESS_INFO *) ctx->compressinfo; + if (ci->size != get_size (ctx->realpath)) + { + FREE (&ctx->compressinfo); + FREE (&ctx->realpath); + mutt_error _("Mailbox was corrupted!"); + return (-1); + } + return (0); +} + +int mutt_open_read_compressed (CONTEXT *ctx) +{ + char *cmd; + FILE *fp; + int rc; + + COMPRESS_INFO *ci = set_compress_info (ctx); + if (!ci->open) { + ctx->magic = 0; + FREE (ctx->compressinfo); + return (-1); + } + if (!ci->close || access (ctx->path, W_OK) != 0) + ctx->readonly = 1; + + set_path (ctx); + store_size (ctx); + + if (!ctx->quiet) + mutt_message (_("Decompressing %s..."), ctx->realpath); + + cmd = get_compression_cmd (ci->open, ctx); + if (cmd == NULL) + return (-1); + dprint (2, (debugfile, "DecompressCmd: '%s'\n", cmd)); + + if ((fp = fopen (ctx->realpath, "r")) == NULL) + { + mutt_perror (ctx->realpath); + FREE (&cmd); + return (-1); + } + mutt_block_signals (); + if (mbox_lock_compressed (ctx, fp, 0, 1) == -1) + { + fclose (fp); + mutt_unblock_signals (); + mutt_error _("Unable to lock mailbox!"); + FREE (&cmd); + return (-1); + } + + endwin (); + fflush (stdout); + sprintf(echo_cmd,_("echo Decompressing %s..."),ctx->realpath); + mutt_system(echo_cmd); + rc = mutt_system (cmd); + mbox_unlock_compressed (ctx, fp); + mutt_unblock_signals (); + fclose (fp); + + if (rc) + { + mutt_any_key_to_continue (NULL); + ctx->magic = 0; + FREE (ctx->compressinfo); + mutt_error (_("Error executing: %s : unable to open the mailbox!\n"), cmd); + } + FREE (&cmd); + if (rc) + return (-1); + + if (mutt_check_mailbox_compressed (ctx)) + return (-1); + + ctx->magic = mx_get_magic (ctx->path); + + return (0); +} + +void restore_path (CONTEXT* ctx) +{ + FREE (&ctx->path); + ctx->path = ctx->realpath; +} + +/* remove the temporary mailbox */ +void remove_file (CONTEXT* ctx) +{ + if (ctx->magic == M_MBOX || ctx->magic == M_MMDF) + remove (ctx->path); +} + +int mutt_open_append_compressed (CONTEXT *ctx) +{ + FILE *fh; + COMPRESS_INFO *ci = set_compress_info (ctx); + + if (!get_append_command (ctx->path, ctx)) + { + if (ci->open && ci->close) + return (mutt_open_read_compressed (ctx)); + + ctx->magic = 0; + FREE (&ctx->compressinfo); + return (-1); + } + + set_path (ctx); + + ctx->magic = DefaultMagic; + + if (!is_new (ctx->realpath)) + if (ctx->magic == M_MBOX || ctx->magic == M_MMDF) + if ((fh = fopen (ctx->path, "w"))) + fclose (fh); + /* No error checking - the parent function will catch it */ + + return (0); +} + +/* close a compressed mailbox */ +void mutt_fast_close_compressed (CONTEXT *ctx) +{ + dprint (2, (debugfile, "mutt_fast_close_compressed called on '%s'\n", + ctx->path)); + + if (ctx->compressinfo) + { + if (ctx->fp) + fclose (ctx->fp); + ctx->fp = NULL; + /* if the folder was removed, remove the gzipped folder too */ + if (access (ctx->path, F_OK) != 0 && ! option (OPTSAVEEMPTY)) + remove (ctx->realpath); + else + remove_file (ctx); + + restore_path (ctx); + FREE (&ctx->compressinfo); + } +} + +/* return 0 on success, -1 on failure */ +int mutt_sync_compressed (CONTEXT* ctx) +{ + char *cmd; + int rc = 0; + FILE *fp; + COMPRESS_INFO *ci = (COMPRESS_INFO *) ctx->compressinfo; + + if (!ctx->quiet) + mutt_message (_("Compressing %s..."), ctx->realpath); + + cmd = get_compression_cmd (ci->close, ctx); + if (cmd == NULL) + return (-1); + + if ((fp = fopen (ctx->realpath, "a")) == NULL) + { + mutt_perror (ctx->realpath); + FREE (&cmd); + return (-1); + } + mutt_block_signals (); + if (mbox_lock_compressed (ctx, fp, 1, 1) == -1) + { + fclose (fp); + mutt_unblock_signals (); + mutt_error _("Unable to lock mailbox!"); + + store_size (ctx); + + FREE (&cmd); + return (-1); + } + + dprint (2, (debugfile, "CompressCommand: '%s'\n", cmd)); + + endwin (); + fflush (stdout); + sprintf(echo_cmd,_("echo Compressing %s..."), ctx->realpath); + mutt_system(echo_cmd); + if (mutt_system (cmd)) + { + mutt_any_key_to_continue (NULL); + mutt_error (_("%s: Error compressing mailbox! Original mailbox deleted, uncompressed one kept!\n"), ctx->path); + rc = -1; + } + + mbox_unlock_compressed (ctx, fp); + mutt_unblock_signals (); + fclose (fp); + + FREE (&cmd); + + store_size (ctx); + + return (rc); +} + +int mutt_slow_close_compressed (CONTEXT *ctx) +{ + FILE *fp; + const char *append; + char *cmd; + COMPRESS_INFO *ci = (COMPRESS_INFO *) ctx->compressinfo; + + dprint (2, (debugfile, "mutt_slow_close_compressed called on '%s'\n", + ctx->path)); + + if (! (ctx->append + && ((append = get_append_command (ctx->realpath, ctx)) + || (append = ci->close)))) + { /* if we can not or should not append, + * we only have to remove the compressed info, because sync was already + * called + */ + mutt_fast_close_compressed (ctx); + return (0); + } + + if (ctx->fp) + fclose (ctx->fp); + ctx->fp = NULL; + + if (!ctx->quiet) + { + if (append == ci->close) + mutt_message (_("Compressing %s..."), ctx->realpath); + else + mutt_message (_("Compressed-appending to %s..."), ctx->realpath); + } + + cmd = get_compression_cmd (append, ctx); + if (cmd == NULL) + return (-1); + + if ((fp = fopen (ctx->realpath, "a")) == NULL) + { + mutt_perror (ctx->realpath); + FREE (&cmd); + return (-1); + } + mutt_block_signals (); + if (mbox_lock_compressed (ctx, fp, 1, 1) == -1) + { + fclose (fp); + mutt_unblock_signals (); + mutt_error _("Unable to lock mailbox!"); + FREE (&cmd); + return (-1); + } + + dprint (2, (debugfile, "CompressCmd: '%s'\n", cmd)); + + endwin (); + fflush (stdout); + + if (append == ci->close) + sprintf(echo_cmd,_("echo Compressing %s..."), ctx->realpath); + else + sprintf(echo_cmd,_("echo Compressed-appending to %s..."), ctx->realpath); + mutt_system(echo_cmd); + + if (mutt_system (cmd)) + { + mutt_any_key_to_continue (NULL); + mutt_error (_(" %s: Error compressing mailbox! Uncompressed one kept!\n"), + ctx->path); + FREE (&cmd); + mbox_unlock_compressed (ctx, fp); + mutt_unblock_signals (); + fclose (fp); + return (-1); + } + + mbox_unlock_compressed (ctx, fp); + mutt_unblock_signals (); + fclose (fp); + remove_file (ctx); + restore_path (ctx); + FREE (&cmd); + FREE (&ctx->compressinfo); + + return (0); +} + +#endif /* USE_COMPRESSED */ diff -Pur mutt-1.5.8-base/compress.h mutt-1.5.8-mega/compress.h --- mutt-1.5.8-base/compress.h Wed Dec 31 18:00:00 1969 +++ mutt-1.5.8-mega/compress.h Thu Mar 10 17:50:15 2005 @@ -0,0 +1,27 @@ +/* + * Copyright (C) 1997 Alain Penders + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +int mutt_can_read_compressed (const char *); +int mutt_can_append_compressed (const char *); +int mutt_open_read_compressed (CONTEXT *); +int mutt_open_append_compressed (CONTEXT *); +int mutt_slow_close_compressed (CONTEXT *); +int mutt_sync_compressed (CONTEXT *); +int mutt_test_compress_command (const char *); +int mutt_check_mailbox_compressed (CONTEXT *); +void mutt_fast_close_compressed (CONTEXT *); diff -Pur mutt-1.5.8-base/config.h.in mutt-1.5.8-mega/config.h.in --- mutt-1.5.8-base/config.h.in Sat Feb 12 14:57:46 2005 +++ mutt-1.5.8-mega/config.h.in Thu Mar 10 17:53:36 2005 @@ -420,6 +420,9 @@ values other than (size_t)(-1) as equivalent. */ #undef ICONV_NONTRANS +/* Description */ +#undef IMAP_EDIT_THREADS + /* Where to find ispell on your system. */ #undef ISPELL @@ -497,6 +500,9 @@ /* Define to enable Sun mailtool attachments support. */ #undef SUN_ATTACHMENT + +/* Define to enable compressed folders support. */ +#undef USE_COMPRESSED /* Define to use dotlocking for mailboxes. */ #undef USE_DOTLOCK diff -Pur mutt-1.5.8-base/config.h.in~ mutt-1.5.8-mega/config.h.in~ --- mutt-1.5.8-base/config.h.in~ Wed Dec 31 18:00:00 1969 +++ mutt-1.5.8-mega/config.h.in~ Thu Mar 10 17:50:15 2005 @@ -0,0 +1,630 @@ +/* config.h.in. Generated from configure.in by autoheader. */ + +/* Define to enable the "buffy_size" feature. */ +#undef BUFFY_SIZE + +/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP + systems. This function is required for `alloca.c' support on those systems. + */ +#undef CRAY_STACKSEG_END + +/* Define if you want classic PGP support. */ +#undef CRYPT_BACKEND_CLASSIC_PGP + +/* Define if you want clasic S/MIME support. */ +#undef CRYPT_BACKEND_CLASSIC_SMIME + +/* Defined, if GPGME support is enabled */ +#undef CRYPT_BACKEND_GPGME + +/* Define to 1 if using `alloca.c'. */ +#undef C_ALLOCA + +/* Define to enable debugging info. */ +#undef DEBUG + +/* Define if you want to use an external dotlocking program. */ +#undef DL_STANDALONE + +/* Define your domain name. */ +#undef DOMAIN + +/* Define to 1 if translation of program messages to the user's native + language is requested. */ +#undef ENABLE_NLS + +/* Enable exact regeneration of email addresses as parsed? NOTE: this requires + significant more memory when defined. */ +#undef EXACT_ADDRESS + +/* program to use for shell commands */ +#undef EXECSHELL + +/* Define to 1 if you have `alloca', as a function or macro. */ +#undef HAVE_ALLOCA + +/* Define to 1 if you have and it should be used (not on Ultrix). + */ +#undef HAVE_ALLOCA_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_ARGZ_H + +/* Define to 1 if you have the `bind_textdomain_codeset' function. */ +#undef HAVE_BIND_TEXTDOMAIN_CODESET + +/* Define if you have bkgdset, as a function or macro. */ +#undef HAVE_BKGDSET + +/* Define if you have the C99 integer types */ +#undef HAVE_C99_INTTYPES + +/* Define if your curses library supports color. */ +#undef HAVE_COLOR + +/* Define if you have curs_set, as a function or macro. */ +#undef HAVE_CURS_SET + +/* Sleepycat DB4 Support */ +#undef HAVE_DB4 + +/* Define to 1 if you have the `dcgettext' function. */ +#undef HAVE_DCGETTEXT + +/* Define to 1 if you have the declaration of `sys_siglist', and to 0 if you + don't. */ +#undef HAVE_DECL_SYS_SIGLIST + +/* Define to 1 if you have the `fchdir' function. */ +#undef HAVE_FCHDIR + +/* Define to 1 if you have the `feof_unlocked' function. */ +#undef HAVE_FEOF_UNLOCKED + +/* Define to 1 if you have the `fgetpos' function. */ +#undef HAVE_FGETPOS + +/* Define to 1 if you have the `fgets_unlocked' function. */ +#undef HAVE_FGETS_UNLOCKED + +/* Define to 1 if you have the `ftruncate' function. */ +#undef HAVE_FTRUNCATE + +/* GDBM Support */ +#undef HAVE_GDBM + +/* Define to 1 if you have the `getaddrinfo' function. */ +#undef HAVE_GETADDRINFO + +/* Define to 1 if you have the `getcwd' function. */ +#undef HAVE_GETCWD + +/* Define to 1 if you have the `getegid' function. */ +#undef HAVE_GETEGID + +/* Define to 1 if you have the `geteuid' function. */ +#undef HAVE_GETEUID + +/* Define to 1 if you have the `getgid' function. */ +#undef HAVE_GETGID + +/* Define to 1 if you have the header file. */ +#undef HAVE_GETOPT_H + +/* Define to 1 if you have the `getpagesize' function. */ +#undef HAVE_GETPAGESIZE + +/* Define to 1 if you have the `getsid' function. */ +#undef HAVE_GETSID + +/* Define if the GNU gettext() function is already present or preinstalled. */ +#undef HAVE_GETTEXT + +/* Define to 1 if you have the `getuid' function. */ +#undef HAVE_GETUID + +/* Define to 1 if you have the header file. */ +#undef HAVE_GNUTLS_OPENSSL_H + +/* Define if your GSSAPI implementation is Heimdal */ +#undef HAVE_HEIMDAL + +/* Define if you have the iconv() function. */ +#undef HAVE_ICONV + +/* Define to 1 if you have the header file. */ +#undef HAVE_ICONV_H + +/* Define if defines iconv_t. */ +#undef HAVE_ICONV_T_DEF + +/* Define to 1 if you have the `idna_to_ascii_8z' function. */ +#undef HAVE_IDNA_TO_ASCII_8Z + +/* Define to 1 if you have the `idna_to_ascii_from_locale' function. */ +#undef HAVE_IDNA_TO_ASCII_FROM_LOCALE + +/* Define to 1 if you have the `idna_to_ascii_from_utf8' function. */ +#undef HAVE_IDNA_TO_ASCII_FROM_UTF8 + +/* Define to 1 if you have the `idna_to_ascii_lz' function. */ +#undef HAVE_IDNA_TO_ASCII_LZ + +/* Define to 1 if you have the `idna_to_unicode_8z8z' function. */ +#undef HAVE_IDNA_TO_UNICODE_8Z8Z + +/* Define to 1 if you have the `idna_to_unicode_utf8_from_utf8' function. */ +#undef HAVE_IDNA_TO_UNICODE_UTF8_FROM_UTF8 + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_IOCTL_H + +/* Define to 1 if you have the `iswalnum' function. */ +#undef HAVE_ISWALNUM + +/* Define to 1 if you have the `iswalpha' function. */ +#undef HAVE_ISWALPHA + +/* Define to 1 if you have the `iswcntrl' function. */ +#undef HAVE_ISWCNTRL + +/* Define to 1 if you have the `iswdigit' function. */ +#undef HAVE_ISWDIGIT + +/* Define to 1 if you have the `iswgraph' function. */ +#undef HAVE_ISWGRAPH + +/* Define to 1 if you have the `iswlower' function. */ +#undef HAVE_ISWLOWER + +/* Define to 1 if you have the `iswprint' function. */ +#undef HAVE_ISWPRINT + +/* Define to 1 if you have the `iswpunct' function. */ +#undef HAVE_ISWPUNCT + +/* Define to 1 if you have the `iswspace' function. */ +#undef HAVE_ISWSPACE + +/* Define to 1 if you have the `iswupper' function. */ +#undef HAVE_ISWUPPER + +/* Define to 1 if you have the `iswxdigit' function. */ +#undef HAVE_ISWXDIGIT + +/* Define if you have and nl_langinfo(CODESET). */ +#undef HAVE_LANGINFO_CODESET + +/* Define if you have and nl_langinfo(YESEXPR). */ +#undef HAVE_LANGINFO_YESEXPR + +/* Define if your file defines LC_MESSAGES. */ +#undef HAVE_LC_MESSAGES + +/* Define to 1 if you have the `crypto' library (-lcrypto). */ +#undef HAVE_LIBCRYPTO + +/* Define to 1 if you have the `idn' library (-lidn). */ +#undef HAVE_LIBIDN + +/* Define to 1 if you have the `intl' library (-lintl). */ +#undef HAVE_LIBINTL + +/* Define to 1 if you have the `nsl' library (-lnsl). */ +#undef HAVE_LIBNSL + +/* Define to 1 if you have the `sasl' library (-lsasl). */ +#undef HAVE_LIBSASL + +/* Define to 1 if you have the `sasl2' library (-lsasl2). */ +#undef HAVE_LIBSASL2 + +/* Define to 1 if you have the `socket' library (-lsocket). */ +#undef HAVE_LIBSOCKET + +/* Define to 1 if you have the `ssl' library (-lssl). */ +#undef HAVE_LIBSSL + +/* Define to 1 if you have the `termlib' library (-ltermlib). */ +#undef HAVE_LIBTERMLIB + +/* Define to 1 if you have the `x' library (-lx). */ +#undef HAVE_LIBX + +/* Define to 1 if you have the header file. */ +#undef HAVE_LIMITS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_LOCALE_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_MALLOC_H + +/* Define to 1 if you have the `memmove' function. */ +#undef HAVE_MEMMOVE + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the `mempcpy' function. */ +#undef HAVE_MEMPCPY + +/* Define if you have meta, as a function or macro. */ +#undef HAVE_META + +/* Define to 1 if you have a working `mmap' system call. */ +#undef HAVE_MMAP + +/* Define to 1 if you have the `munmap' function. */ +#undef HAVE_MUNMAP + +/* Define to 1 if you have the header file. */ +#undef HAVE_NCURSESW_NCURSES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NCURSES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NL_TYPES_H + +/* Define to 1 if you have the `putenv' function. */ +#undef HAVE_PUTENV + +/* Define to 1 if you have the `RAND_egd' function. */ +#undef HAVE_RAND_EGD + +/* Define to 1 if you have the `RAND_status' function. */ +#undef HAVE_RAND_STATUS + +/* Define to 1 if you have the `regcomp' function. */ +#undef HAVE_REGCOMP + +/* Define if you have resizeterm, as a function or macro. */ +#undef HAVE_RESIZETERM + +/* Define to 1 if you have the `setegid' function. */ +#undef HAVE_SETEGID + +/* Define to 1 if you have the `setenv' function. */ +#undef HAVE_SETENV + +/* Define to 1 if you have the `setlocale' function. */ +#undef HAVE_SETLOCALE + +/* Define to 1 if you have the `setrlimit' function. */ +#undef HAVE_SETRLIMIT + +/* Define to 1 if you have the `snprintf' function. */ +#undef HAVE_SNPRINTF + +/* Define to 1 if you have the `srand48' function. */ +#undef HAVE_SRAND48 + +/* Define if you have start_color, as a function or macro. */ +#undef HAVE_START_COLOR + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDARG_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDDEF_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the `stpcpy' function. */ +#undef HAVE_STPCPY + +/* Define to 1 if you have the `strcasecmp' function. */ +#undef HAVE_STRCASECMP + +/* Define to 1 if you have the `strchr' function. */ +#undef HAVE_STRCHR + +/* Define to 1 if you have the `strdup' function. */ +#undef HAVE_STRDUP + +/* Define to 1 if you have the `strerror' function. */ +#undef HAVE_STRERROR + +/* Define to 1 if you have the `strftime' function. */ +#undef HAVE_STRFTIME + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the `strtoul' function. */ +#undef HAVE_STRTOUL + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYSEXITS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_IOCTL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_PARAM_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_RESOURCE_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TIME_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the `towlower' function. */ +#undef HAVE_TOWLOWER + +/* Define to 1 if you have the `towupper' function. */ +#undef HAVE_TOWUPPER + +/* Define to 1 if you have the `tsearch' function. */ +#undef HAVE_TSEARCH + +/* Define if you have typeahead, as a function or macro. */ +#undef HAVE_TYPEAHEAD + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNIX_H + +/* Define if you have use_default_colors, as a function or macro. */ +#undef HAVE_USE_DEFAULT_COLORS + +/* Define to 1 if you have the `vsnprintf' function. */ +#undef HAVE_VSNPRINTF + +/* Define to 1 if you have the header file. */ +#undef HAVE_WCHAR_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_WCTYPE_H + +/* Define if you are using the system's wchar_t functions. */ +#undef HAVE_WC_FUNCS + +/* Define to 1 if you have the `__argz_count' function. */ +#undef HAVE___ARGZ_COUNT + +/* Define to 1 if you have the `__argz_next' function. */ +#undef HAVE___ARGZ_NEXT + +/* Define to 1 if you have the `__argz_stringify' function. */ +#undef HAVE___ARGZ_STRINGIFY + +/* Is mail spooled to the user's home directory? If defined, MAILPATH should + be set to the filename of the spool mailbox relative the the home + directory. use: configure --with-homespool=FILE */ +#undef HOMESPOOL + +/* Define as const if the declaration of iconv() needs const. */ +#undef ICONV_CONST + +/* Define as 1 if iconv() only converts exactly and we should treat all return + values other than (size_t)(-1) as equivalent. */ +#undef ICONV_NONTRANS + +/* Do you want to use the rethreading functions with IMAP + * (--enable-imap-edit-threads) */ +#undef IMAP_EDIT_THREADS + +/* Where to find ispell on your system. */ +#undef ISPELL + +/* Define if the result of isprint() is unreliable. */ +#undef LOCALES_HACK + +/* Where new mail is spooled. */ +#undef MAILPATH + +/* Where to find mixmaster on your system. */ +#undef MIXMASTER + +/* Define if you have problems with mutt not detecting new/old mailboxes over + NFS. Some NFS implementations incorrectly cache the attributes of small + files. */ +#undef NFS_ATTRIBUTE_HACK + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define to 1 if the C compiler supports function prototypes. */ +#undef PROTOTYPES + +/* Define as the return type of signal handlers (`int' or `void'). */ +#undef RETSIGTYPE + +/* Where to find sendmail on your system. */ +#undef SENDMAIL + +/* Some systems declare sig_atomic_t as volatile, some others -- no. This + define will have value `sig_atomic_t' or `volatile sig_atomic_t' + accordingly. */ +#undef SIG_ATOMIC_VOLATILE_T + +/* The size of a `int', as computed by sizeof. */ +#undef SIZEOF_INT + +/* The size of a `long', as computed by sizeof. */ +#undef SIZEOF_LONG + +/* The size of a `long long', as computed by sizeof. */ +#undef SIZEOF_LONG_LONG + +/* The size of a `short', as computed by sizeof. */ +#undef SIZEOF_SHORT + +/* If using the C implementation of alloca, define if you know the + direction of stack growth for your system; otherwise it will be + automatically deduced at run-time. + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown */ +#undef STACK_DIRECTION + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Is this the international version? */ +#undef SUBVERSION + +/* Define to enable Sun mailtool attachments support. */ +#undef SUN_ATTACHMENT + +/* The compressed mailboxes support */ +#undef USE_COMPRESSED + +/* Define to use dotlocking for mailboxes. */ +#undef USE_DOTLOCK + +/* Define to use fcntl() to lock folders. */ +#undef USE_FCNTL + +/* Define to use flock() to lock mailboxes. */ +#undef USE_FLOCK + +/* Define if you want support for SSL via the gnutls library. */ +#undef USE_GNUTLS + +/* Define if you want to use the included regex.c. */ +#undef USE_GNU_REGEX + +/* Define if you have GSSAPI libraries available */ +#undef USE_GSS + +/* Enable header caching */ +#undef USE_HCACHE + +/* Define if you want support for the IMAP protocol. */ +#undef USE_IMAP + +/* Define to sort files in a maildir by inode number. */ +#undef USE_INODESORT + +/* Define if you want support for SSL via the NSS library. */ +#undef USE_NSS + +/* Define if you want support for the POP3 protocol. */ +#undef USE_POP + +/* Define if want to use the Cyrus SASL library for POP/IMAP authentication. + */ +#undef USE_SASL + +/* Define if want to use version 2 of the Cyrus SASL library. */ +#undef USE_SASL2 + +/* Define if mutt should run setgid "mail". */ +#undef USE_SETGID + +/* Define if you compile with SLang instead of curses/ncurses. */ +#undef USE_SLANG_CURSES + +/* Include code for socket support. Set automatically if you enable POP3 or + IMAP */ +#undef USE_SOCKET + +/* Define if you want support for SSL. */ +#undef USE_SSL + +/* Version number of package */ +#undef VERSION + +#ifndef HAVE_C99_INTTYPES +# if SIZEOF_SHORT == 4 +typedef unsigned short uint32_t; +# elif SIZEOF_INT == 4 +typedef unsigned int uint32_t; +# elif SIZEOF_LONG == 4 +typedef unsigned long uint32_t; +# endif +# if SIZEOF_INT == 8 +typedef unsigned int uint64_t; +# elif SIZEOF_LONG == 8 +typedef unsigned long uint64_t; +# elif SIZEOF_LONG_LONG == 8 +typedef unsigned long long uint64_t; +# endif +#endif + + +/* Number of bits in a file offset, on hosts where this is settable. */ +#undef _FILE_OFFSET_BITS + +/* Enable GNU extensions on systems that have them. */ +#ifndef _GNU_SOURCE +# undef _GNU_SOURCE +#endif + +/* Define for large files, on AIX-style hosts. */ +#undef _LARGE_FILES + +/* Define like PROTOTYPES; this can be used by system headers. */ +#undef __PROTOTYPES + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +#undef inline +#endif + +/* Define to 'int' if system headers don't define. */ +#undef mbstate_t + +/* Define to `long' if does not define. */ +#undef off_t + +/* Define to `int' if does not define. */ +#undef pid_t + +/* Define to `int' if does not define. */ +#undef sig_atomic_t + +/* Define to `unsigned' if does not define. */ +#undef size_t + +/* Define to 'int' if doesn't have it. */ +#undef socklen_t + +/* Define to `int' if does not define. */ +#undef ssize_t + +/* Define to 'int' if system headers don't define. */ +#undef wchar_t + +/* Define to 'int' if system headers don't define. */ +#undef wint_t diff -Pur mutt-1.5.8-base/configure mutt-1.5.8-mega/configure --- mutt-1.5.8-base/configure Sat Feb 12 14:57:29 2005 +++ mutt-1.5.8-mega/configure Thu Mar 10 18:01:27 2005 @@ -858,6 +858,7 @@ --enable-external-dotlock Force use of an external dotlock program --enable-pop Enable POP3 support --enable-imap Enable IMAP support + --enable-imap-edit-threads Enable editing threads support for IMAP --enable-debug Enable debugging support --enable-flock Use flock() to lock files --disable-fcntl Do NOT use fcntl() to lock files @@ -866,6 +867,7 @@ --enable-nfs-fix Work around an NFS with broken attributes caching --enable-buffy-size Use file size attribute instead of access time --enable-mailtool Enable Sun mailtool attachments support + --enable-compressed Enable compressed folders support --enable-locales-fix The result of isprint() is unreliable --enable-exact-address Enable regeneration of email addresses --enable-hcache Enable header caching @@ -12117,7 +12119,7 @@ echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS -LIBS="-lgssapi_krb5 -lkrb5 -lk5crypto -lcom_err $LIBS" +LIBS="-lgssapi_krb5 -lkrb5 -lk5crypto -lcom_err -lresolv $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF @@ -12178,7 +12180,7 @@ if test $ac_cv_lib_gssapi_krb5_gss_init_sec_context = yes; then GSSAPI_IMPL="MIT", - GSSAPI_LIBS="$GSSAPI_LDFLAGS -lgssapi_krb5 -lkrb5 -lk5crypto -lcom_err" + GSSAPI_LIBS="$GSSAPI_LDFLAGS -lgssapi_krb5 -lkrb5 -lk5crypto -lcom_err -lresolv" fi @@ -12191,7 +12193,7 @@ echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS -LIBS="-lgssapi -lkrb5 -ldes -lasn1 -lroken -lcrypt -lcom_err $LIBS" +LIBS="-lgssapi -lkrb5 -ldes -lasn1 -lroken -lcrypt -lcom_err -lresolv $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF @@ -12253,7 +12255,7 @@ GSSAPI_IMPL="Heimdal" GSSAPI_LIBS="$GSSAPI_LDFLAGS -lgssapi -lkrb5 -ldes -lasn1 -lroken" - GSSAPI_LIBS="$GSSAPI_LIBS -lcrypt -lcom_err" + GSSAPI_LIBS="$GSSAPI_LIBS -lcrypt -lcom_err -lresolv" fi @@ -12267,7 +12269,7 @@ echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS -LIBS="-lgssapi_krb5 -lkrb5 -lcrypto -lcom_err $LIBS" +LIBS="-lgssapi_krb5 -lkrb5 -lcrypto -lcom_err -lresolv $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF @@ -12328,7 +12330,7 @@ if test $ac_cv_lib_gssapi_krb5_g_order_init = yes; then GSSAPI_IMPL="OldMIT", - GSSAPI_LIBS="$GSSAPI_LDFLAGS -lgssapi_krb5 -lkrb5 -lcrypto -lcom_err" + GSSAPI_LIBS="$GSSAPI_LDFLAGS -lgssapi_krb5 -lkrb5 -lcrypto -lcom_err -lresolv" fi @@ -12435,6 +12437,24 @@ +# Check whether --enable-imap-edit-threads or --disable-imap-edit-threads was given. +if test "${enable_imap_edit_threads+set}" = set; then + enableval="$enable_imap_edit_threads" + + if test "$enableval" = "yes"; then + if test "$need_imap" = "yes"; then + +cat >>confdefs.h <<\_ACEOF +#define IMAP_EDIT_THREADS +_ACEOF + + else + { echo "$as_me:$LINENO: WARNING: IMAP support for edit_threads is only useful with IMAP support" >&5 +echo "$as_me: WARNING: IMAP support for edit_threads is only useful with IMAP support" >&2;} + fi +fi +fi; + # Check whether --with-ssl or --without-ssl was given. if test "${with_ssl+set}" = set; then @@ -13961,6 +13981,18 @@ cat >>confdefs.h <<\_ACEOF #define SUN_ATTACHMENT 1 +_ACEOF + + fi +fi; + +# Check whether --enable-compressed or --disable-compressed was given. +if test "${enable_compressed+set}" = set; then + enableval="$enable_compressed" + if test x$enableval = xyes; then + +cat >>confdefs.h <<\_ACEOF +#define USE_COMPRESSED 1 _ACEOF fi diff -Pur mutt-1.5.8-base/configure.in mutt-1.5.8-mega/configure.in --- mutt-1.5.8-base/configure.in Sat Feb 12 14:57:16 2005 +++ mutt-1.5.8-mega/configure.in Thu Mar 10 17:50:15 2005 @@ -558,6 +558,16 @@ dnl -- end imap dependencies -- +AC_ARG_ENABLE(imap-edit-threads, [ --enable-imap-edit-threads Enable editing threads support for IMAP], +[ + if test "$enableval" = "yes"; then + if test "$need_imap" = "yes"; then + AC_DEFINE([IMAP_EDIT_THREADS], [], [Description]) + else + AC_MSG_WARN([IMAP support for edit_threads is only useful with IMAP support]) + fi +fi]) + AC_ARG_WITH(ssl, [ --with-ssl[=PFX] Compile in SSL support for POP/IMAP], [ if test "$with_ssl" != "no" then @@ -769,6 +779,11 @@ AC_ARG_ENABLE(mailtool, [ --enable-mailtool Enable Sun mailtool attachments support ], [if test x$enableval = xyes; then AC_DEFINE(SUN_ATTACHMENT,1,[ Define to enable Sun mailtool attachments support. ]) + fi]) + +AC_ARG_ENABLE(compressed, [ --enable-compressed Enable compressed folders support ], + [if test x$enableval = xyes; then + AC_DEFINE(USE_COMPRESSED,1,[ Define to enable compressed folders support. ]) fi]) AC_ARG_ENABLE(locales-fix, [ --enable-locales-fix The result of isprint() is unreliable ], diff -Pur mutt-1.5.8-base/copy.c mutt-1.5.8-mega/copy.c --- mutt-1.5.8-base/copy.c Thu Feb 3 12:47:52 2005 +++ mutt-1.5.8-mega/copy.c Thu Mar 10 17:51:39 2005 @@ -99,9 +99,19 @@ (ascii_strncasecmp ("Content-Length:", buf, 15) == 0 || ascii_strncasecmp ("Lines:", buf, 6) == 0)) continue; + if ((flags & CH_UPDATE_REFS) && + ascii_strncasecmp ("References:", buf, 11) == 0) + continue; + if ((flags & CH_UPDATE_IRT) && + ascii_strncasecmp ("In-Reply-To:", buf, 12) == 0) + continue; ignore = 0; } + if (flags & CH_UPDATE_LABEL && + mutt_strncasecmp ("X-Label:", buf, 8) == 0) + continue; + if (!ignore && fputs (buf, out) == EOF) return (-1); } @@ -197,6 +207,12 @@ ascii_strncasecmp ("type:", buf + 8, 5) == 0)) || ascii_strncasecmp ("mime-version:", buf, 13) == 0)) continue; + if ((flags & CH_UPDATE_REFS) && + ascii_strncasecmp ("References:", buf, 11) == 0) + continue; + if ((flags & CH_UPDATE_IRT) && + ascii_strncasecmp ("In-Reply-To:", buf, 12) == 0) + continue; /* Find x -- the array entry where this header is to be saved */ if (flags & CH_REORDER) @@ -330,6 +346,8 @@ CH_XMIT ignore Lines: and Content-Length: CH_WEED do header weeding CH_NOQFROM ignore ">From " line + CH_UPDATE_IRT update the In-Reply-To: header + CH_UPDATE_REFS update the References: header prefix string to use if CH_PREFIX is set @@ -339,6 +357,9 @@ mutt_copy_header (FILE *in, HEADER *h, FILE *out, int flags, const char *prefix) { char buffer[SHORT_STRING]; + + flags |= (h->irt_changed ? CH_UPDATE_IRT : 0) + | (h->refs_changed ? CH_UPDATE_REFS : 0); if (mutt_copy_hdr (in, out, h->offset, h->content->offset, flags, prefix) == -1) return (-1); @@ -362,7 +383,56 @@ if (flags & CH_UPDATE) { if ((flags & CH_NOSTATUS) == 0) +#ifdef IMAP_EDIT_THREADS +#define NEW_ENV new_env +#else +#define NEW_ENV env +#endif { + if (h->irt_changed && h->NEW_ENV->in_reply_to) + { + LIST *listp = h->NEW_ENV->in_reply_to; + + if (fputs ("In-Reply-To: ", out) == EOF) + return (-1); + + for (; listp; listp = listp->next) + if ((fputs (listp->data, out) == EOF) || (fputc (' ', out) == EOF)) + return (-1); + + if (fputc ('\n', out) == EOF) + return (-1); + } + + if (h->refs_changed && h->NEW_ENV->references) + { + LIST *listp = h->NEW_ENV->references, *refs = NULL, *t; + + if (fputs ("References: ", out) == EOF) + return (-1); + + /* Mutt stores references in reverse order, thus we create + * a reordered refs list that we can put in the headers */ + for (; listp; listp = listp->next, refs = t) + { + t = (LIST *)safe_malloc (sizeof (LIST)); + t->data = listp->data; + t->next = refs; + } + + for (; refs; refs = refs->next) + if ((fputs (refs->data, out) == EOF) || (fputc (' ', out) == EOF)) + return (-1); + + /* clearing refs from memory */ + for (t = refs; refs; refs = t->next, t = refs) + safe_free ((void **)&refs); + + if (fputc ('\n', out) == EOF) + return (-1); + } +#undef NEW_ENV + if (h->old || h->read) { if (fputs ("Status: ", out) == EOF) @@ -383,7 +453,7 @@ return (-1); } - if (h->flagged || h->replied) + if (h->flagged || h->replied | h->mdnsent) { if (fputs ("X-Status: ", out) == EOF) return (-1); @@ -400,6 +470,12 @@ return (-1); } + if (h->mdnsent) + { + if (fputc ('N', out) == EOF) + return (-1); + } + if (fputc ('\n', out) == EOF) return (-1); } @@ -414,6 +490,15 @@ fprintf (out, "Lines: %d\n", h->lines); } + if (flags & CH_UPDATE_LABEL && h->xlabel_changed) + { + h->xlabel_changed = 0; + if (h->env->x_label != NULL) + if (fprintf(out, "X-Label: %s\n", h->env->x_label) != + 10 + strlen(h->env->x_label)) + return -1; + } + if ((flags & CH_NONEWLINE) == 0) { if (flags & CH_PREFIX) @@ -493,6 +578,9 @@ else _mutt_make_string (prefix, sizeof (prefix), NONULL (Prefix), Context, hdr, 0); } + + if (hdr->xlabel_changed) + chflags |= CH_UPDATE_LABEL; if ((flags & M_CM_NOHEADER) == 0) { diff -Pur mutt-1.5.8-base/curs_lib.c mutt-1.5.8-mega/curs_lib.c --- mutt-1.5.8-base/curs_lib.c Thu Feb 3 12:47:52 2005 +++ mutt-1.5.8-mega/curs_lib.c Thu Mar 10 17:50:18 2005 @@ -304,7 +304,7 @@ dprint (1, (debugfile, "%s\n", Errorbuf)); mutt_format_string (Errorbuf, sizeof (Errorbuf), - 0, COLS-2, 0, 0, Errorbuf, sizeof (Errorbuf), 0); + 0, COLS-2, FMT_LEFT, 0, Errorbuf, sizeof (Errorbuf), 0); if (!option (OPTKEEPQUIET)) { @@ -328,7 +328,7 @@ va_end (ap); mutt_format_string (Errorbuf, sizeof (Errorbuf), - 0, COLS-2, 0, 0, Errorbuf, sizeof (Errorbuf), 0); + 0, COLS-2, FMT_LEFT, 0, Errorbuf, sizeof (Errorbuf), 0); if (!option (OPTKEEPQUIET)) { @@ -585,7 +585,7 @@ void mutt_format_string (char *dest, size_t destlen, int min_width, int max_width, - int right_justify, char m_pad_char, + int justify, char m_pad_char, const char *s, size_t n, int arboreal) { @@ -629,7 +629,7 @@ w = (int)destlen < min_width ? destlen : min_width; if (w <= 0) *p = '\0'; - else if (right_justify) + else if (justify == FMT_RIGHT) /* right justify */ { p[w] = '\0'; while (--p >= dest) @@ -637,7 +637,27 @@ while (--w >= 0) dest[w] = m_pad_char; } - else + else if (justify == FMT_CENTER) /* center */ + { + char *savedp = p; + int half = (w+1) / 2; /* half of cushion space */ + + p[w] = '\0'; + + /* move str to center of buffer */ + while (--p >= dest) + p[half] = *p; + + /* fill rhs */ + p = savedp + half; + while (--w >= half) + *p++ = m_pad_char; + + /* fill lhs */ + while (half--) + dest[half] = m_pad_char; + } + else /* left justify */ { while (--w >= 0) *p++ = m_pad_char; @@ -659,13 +679,15 @@ const char *s, int arboreal) { - int right_justify = 1; + int justify = FMT_RIGHT; char *p; int min_width; int max_width = INT_MAX; if (*prefix == '-') - ++prefix, right_justify = 0; + ++prefix, justify = FMT_LEFT; + else if (*prefix == '=') + ++prefix, justify = FMT_CENTER; min_width = strtol (prefix, &p, 10); if (*p == '.') { @@ -676,7 +698,7 @@ } mutt_format_string (dest, destlen, min_width, max_width, - right_justify, ' ', s, mutt_strlen (s), arboreal); + justify, ' ', s, mutt_strlen (s), arboreal); } void mutt_format_s (char *dest, @@ -697,7 +719,7 @@ /* * mutt_paddstr (n, s) is almost equivalent to - * mutt_format_string (bigbuf, big, n, n, 0, ' ', s, big, 0), addstr (bigbuf) + * mutt_format_string (bigbuf, big, n, n, FMT_LEFT, ' ', s, big, 0), addstr (bigbuf) */ void mutt_paddstr (int n, const char *s) diff -Pur mutt-1.5.8-base/curs_main.c mutt-1.5.8-mega/curs_main.c --- mutt-1.5.8-base/curs_main.c Sat Feb 12 13:22:15 2005 +++ mutt-1.5.8-mega/curs_main.c Thu Mar 10 17:51:39 2005 @@ -214,7 +214,7 @@ if (! Context->hdrs[Context->v2r[i]]->read && ! Context->hdrs[Context->v2r[i]]->deleted) { - if (! Context->hdrs[Context->v2r[i]]->old) + if (! (option(OPTSEEOLD) && Context->hdrs[Context->v2r[i]]->old)) return (i); else if (old == -1) old = i; @@ -317,7 +317,7 @@ mutt_sort_headers (Context, (check == M_REOPENED)); /* uncollapse threads with new mail */ - if ((Sort & SORT_MASK) == SORT_THREADS) + if (option(OPTUNCOLLAPSENEW) && ((Sort & SORT_MASK) == SORT_THREADS)) { if (check == M_REOPENED) { @@ -934,6 +934,11 @@ else { mutt_set_flag (Context, CURHDR, M_TAG, !CURHDR->tagged); + + Context->last_tag = CURHDR->tagged ? CURHDR : + ((Context->last_tag == CURHDR && !CURHDR->tagged) + ? NULL : Context->last_tag); + menu->redraw = REDRAW_STATUS; if (option (OPTRESOLVE) && menu->current < Context->vcount - 1) { @@ -1076,6 +1081,11 @@ { int check; +#ifdef USE_COMPRESSED + if (Context->compressinfo && Context->realpath) + mutt_str_replace (&LastFolder, Context->realpath); + else +#endif mutt_str_replace (&LastFolder, Context->path); oldcount = Context ? Context->msgcount : 0; @@ -1173,6 +1183,89 @@ } break; + case OP_MAIN_BREAK_THREAD: + + CHECK_MSGCOUNT; + CHECK_VISIBLE; + CHECK_READONLY; + + if ((Sort & SORT_MASK) != SORT_THREADS) + mutt_error _("Threading is not enabled."); + +#if defined (USE_IMAP) && ! defined (IMAP_EDIT_THREADS) + else if (Context->magic == M_IMAP) + mutt_error _("Compile Mutt with --enable-imap-edit-threads for break-thread support"); +#endif + + else + { + { + HEADER *oldcur = CURHDR; + + mutt_break_thread (CURHDR); + mutt_sort_headers (Context, 1); + menu->current = oldcur->virtual; + } + + Context->changed = 1; + mutt_message _("Thread broken"); + + if (menu->menu == MENU_PAGER) + { + op = OP_DISPLAY_MESSAGE; + continue; + } + else + menu->redraw |= REDRAW_INDEX; + } + + break; + + case OP_MAIN_LINK_THREADS: + + CHECK_MSGCOUNT; + CHECK_VISIBLE; + CHECK_READONLY; + + if ((Sort & SORT_MASK) != SORT_THREADS) + mutt_error _("Threading is not enabled."); + +#if defined (USE_IMAP) && ! defined (IMAP_EDIT_THREADS) + else if (Context->magic == M_IMAP) + mutt_error _("Compile Mutt with --enable-imap-edit-threads for link-threads support"); +#endif + + else if (!CURHDR->env->message_id) + mutt_error _("No Message-ID: header available to link thread"); + else if (!tag && (!Context->last_tag || !Context->last_tag->tagged)) + mutt_error _("First, please tag a message to be linked here"); + else + { + HEADER *oldcur = CURHDR; + + if (mutt_link_threads (CURHDR, tag ? NULL : Context->last_tag, + Context)) + { + mutt_sort_headers (Context, 1); + menu->current = oldcur->virtual; + + Context->changed = 1; + mutt_message _("Threads linked"); + } + else + mutt_error _("No thread linked"); + } + + if (menu->menu == MENU_PAGER) + { + op = OP_DISPLAY_MESSAGE; + continue; + } + else + menu->redraw |= REDRAW_STATUS | REDRAW_INDEX; + + break; + case OP_EDIT_TYPE: CHECK_MSGCOUNT; @@ -1364,7 +1457,7 @@ { if (first_unread == -1) first_unread = i; - if ((!CURHDRi->old) && first_new == -1) + if ((!(option(OPTSEEOLD) && CURHDRi->old)) && first_new == -1) first_new = i; } @@ -1467,7 +1560,7 @@ if (Context->hdrs[Context->v2r[j]]->tagged) { if (Context->hdrs[Context->v2r[j]]->read || - Context->hdrs[Context->v2r[j]]->old) + (option(OPTSEEOLD) && Context->hdrs[Context->v2r[j]]->old)) mutt_set_flag (Context, Context->hdrs[Context->v2r[j]], M_NEW, 1); else mutt_set_flag (Context, Context->hdrs[Context->v2r[j]], M_READ, 1); @@ -1477,7 +1570,7 @@ } else { - if (CURHDR->read || CURHDR->old) + if (CURHDR->read || (option(OPTSEEOLD) && CURHDR->old)) mutt_set_flag (Context, CURHDR, M_NEW, 1); else mutt_set_flag (Context, CURHDR, M_READ, 1); @@ -1851,6 +1944,21 @@ menu->redraw = REDRAW_FULL; break; + case OP_EDIT_LABEL: + + CHECK_MSGCOUNT; + CHECK_READONLY; + rc = mutt_label_message(tag ? NULL : CURHDR); + if (rc > 0) { + Context->changed = 1; + menu->redraw = REDRAW_FULL; + mutt_message ("%d label%s changed.", rc, rc == 1 ? "" : "s"); + } + else { + mutt_message _("No labels changed."); + } + break; + case OP_LIST_REPLY: CHECK_ATTACH; @@ -1942,6 +2050,32 @@ } menu->redraw = REDRAW_INDEX | REDRAW_STATUS; } + break; + + + case OP_MARK_MSG: + + if (CURHDR->env->message_id) + { + char str[STRING], macro[STRING]; + char buf[128]; + + buf[0] = '\0'; + if (!mutt_get_field ("Enter macro stroke: ", buf, sizeof(buf), + M_CLEAR) && buf[0]) + { + snprintf(str, sizeof(str), "%s%s", MarkMacroPrefix, buf); + snprintf(macro, sizeof(macro), + "~i \"%s\"\n", CURHDR->env->message_id); + km_bind(str, MENU_GENERIC, OP_MACRO, macro, "Message hotkey"); + + snprintf(buf, sizeof(buf), _("Message bound to %s."), str, macro); + mutt_message(buf); + dprint (1, (debugfile, "Mark: %s => %s\n", str, macro)); + } + } + else + mutt_error _("No message ID to macro."); break; case OP_RECALL_MESSAGE: diff -Pur mutt-1.5.8-base/doc/instdoc mutt-1.5.8-mega/doc/instdoc --- mutt-1.5.8-base/doc/instdoc Wed Dec 31 18:00:00 1969 +++ mutt-1.5.8-mega/doc/instdoc Thu Mar 10 18:05:33 2005 @@ -0,0 +1,24 @@ +#!/bin/sh -- + +prefix=/opt/pkgs/mutt_dev-1.5.8 +exec_prefix=${prefix} +bindir=${exec_prefix}/bin +libdir=${exec_prefix}/lib +mandir=${prefix}/man +srcdir=. +docdir=/opt/pkgs/mutt_dev-1.5.8/doc/mutt +includedir=${prefix}/include +top_srcdir=.. +top_builddir=.. + +SOURCE="$1" +TARGET="$2" + + +rm -f "$TARGET" + +sed -e "s;/usr/local/bin/;$bindir/;g" \ + -e "s;/usr/local/doc/mutt/;$docdir/;g" \ + "$SOURCE" > $TARGET + +chmod 644 "$TARGET" Only in mutt-1.5.8-base/doc: manual-1.html Only in mutt-1.5.8-base/doc: manual-2.html Only in mutt-1.5.8-base/doc: manual-3.html Only in mutt-1.5.8-base/doc: manual-4.html Only in mutt-1.5.8-base/doc: manual-5.html Only in mutt-1.5.8-base/doc: manual-6.html Only in mutt-1.5.8-base/doc: manual-7.html Only in mutt-1.5.8-base/doc: manual.html diff -Pur mutt-1.5.8-base/doc/manual.sgml mutt-1.5.8-mega/doc/manual.sgml --- mutt-1.5.8-base/doc/manual.sgml Sat Feb 12 14:57:47 2005 +++ mutt-1.5.8-mega/doc/manual.sgml Thu Mar 10 17:51:39 2005 @@ -2321,9 +2321,12 @@ name="$index_format"> variable's ``%y'' and ``%Y'' escapes can be used to expand ``X-Label:'' fields in the index, and Mutt's pattern-matcher can match regular expressions to -``X-Label:'' fields with the ``~y'' selector. ``X-Label:'' is not a +``X-Label:'' fields with the ``˜y'' selector. ``X-Label:'' is not a standard message header field, but it can easily be inserted by procmail and other mail filtering agents. +You can change or delete the ``X-Label:'' field within Mutt using the +``edit-label'' command, bound to the ``y'' key by default. This works +for tagged messages, too. Lastly, Mutt has the ability to the mailbox into . A thread is a group of messages which all relate to the same @@ -2537,6 +2540,168 @@ macro pager \cb |urlview\n +Compressed folders Support (OPTIONAL) +

+ +If Mutt was compiled with compressed folders support (by running the +, + and ) which define commands to uncompress and compress +a folder and to append messages to an existing compressed folder +respectively. + +For example: + + +open-hook \\.gz$ "gzip -cd %f > %t" +close-hook \\.gz$ "gzip -c %t > %f" +append-hook \\.gz$ "gzip -c %t >> %f" + + +You do not have to specify all of the commands. If you omit , the folder will be open and +closed again each time you will add to it. If you omit (or give empty command) , the +folder will be open in the mode. If you specify though you'll be able to append +to the folder. + +Note that Mutt will only try to use hooks if the file is not in one of +the accepted formats. In particular, if the file is empty, mutt +supposes it is not compressed. This is important because it allows the +use of programs that do not have well defined extensions. Just use +&dquot;.&dquot; as a regexp. But this may be surprising if your +compressing script produces empty files. In this situation, unset , so that the compressed file +will be removed if you delete all of the messages. + +Open a compressed mailbox for reading

+Usage: +open-hook \\.gz$ "gzip -cd %f > %t" + + +If the Write a compressed mailbox

+Usage: command after some changes were made to it. + +The command. Temporary folder +in this case is the folder previously produced by the < command. + +The +close-hook \\.gz$ "gzip -c %t > %f" + + +If the is not called when you exit +from the folder if the folder was not changed. + +Append a message to a compressed mailbox

+Usage: command. +The temporary folder in this case contains the messages that are being +appended. + +The +append-hook \\.gz$ "gzip -c %t >> %f" + + +When is used, the folder is +not opened, which saves time, but this means that we can not find out +what the folder type is. Thus the default () type is always supposed (i.e. +this is the format used for the temporary folder). + +If the file does not exist when you save to it, is called, and not . is only +for appending to existing folders. + +If the and respectively) each time you will add to it. + +Encrypted folders +

+The compressed folders support can also be used to handle encrypted +folders. If you want to encrypt a folder with PGP, you may want to use +the following hooks: + + +open-hook \\.pgp$ "pgp -f < %f > %t" +close-hook \\.pgp$ "pgp -fe YourPgpUserIdOrKeyId < %t > %f" + + +Please note, that PGP does not support appending to an encrypted +folder, so there is no append-hook defined. + +Mutt's MIME Support

Quite a bit of effort has been made to make Mutt the premier text-mode @@ -3116,6 +3281,8 @@ + + + diff -Pur mutt-1.5.8-base/doc/manual.sgml.head mutt-1.5.8-mega/doc/manual.sgml.head --- mutt-1.5.8-base/doc/manual.sgml.head Sat Feb 12 13:41:36 2005 +++ mutt-1.5.8-mega/doc/manual.sgml.head Thu Mar 10 17:51:40 2005 @@ -1699,6 +1699,63 @@ argument, or you can remove all hooks of a specific type by saying something like Format strings

+Format strings are a general concept you'll find in several locations +through the mutt configuration, especially in the +, +, +, +and other ``*_format'' variables. These can be very straightforward, +and it's quite possible you already know how to use them. +

+ +The most basic format string element is a percent symbol followed by +another character. For example, +variable. The ```expandos'' available are documented with each format +variable, but there are general modifiers available with all formatting +expandos, too. Those are our concern here. +

+ +Some of the modifers are borrowed right out of C (though you might +know them from Perl, Python, shell, or another langugage). These are +the [-]m.n modifiers, as in + +Mutt adds some other modifiers to format strings. If you use an equals +symbol ( + +There are two very little-known modifiers that affect the way that an +expando is replaced. If there is an underline (``_'') character +between any format modifiers (as above) and the expando letter, it will +expands in all lower case. And if you use a colon (``:''), it will +replace all decimal points with underlines. + + Advanced Usage Regular Expressions

Note that patterns matching 'lists' of addresses (notably c,C,p,P and t) @@ -1938,6 +1996,10 @@ ^~C \.de$ +Normally patterns are compared with the message that is being created. +If you want a pattern to match against a message that you are replying to, +you can prefix the pattern with %. + Complex Patterns

@@ -2321,9 +2383,12 @@ name="$index_format"> variable's ``%y'' and ``%Y'' escapes can be used to expand ``X-Label:'' fields in the index, and Mutt's pattern-matcher can match regular expressions to -``X-Label:'' fields with the ``~y'' selector. ``X-Label:'' is not a +``X-Label:'' fields with the ``˜y'' selector. ``X-Label:'' is not a standard message header field, but it can easily be inserted by procmail and other mail filtering agents. +You can change or delete the ``X-Label:'' field within Mutt using the +``edit-label'' command, bound to the ``y'' key by default. This works +for tagged messages, too. Lastly, Mutt has the ability to the mailbox into . A thread is a group of messages which all relate to the same @@ -2333,8 +2398,43 @@ with large volume mailing lists easier because you can easily delete uninteresting threads and quickly find topics of value. +Editing threads +

+Mutt has the ability to dynamically restructure threads that are broken +either by misconfigured software or bad behaviour from some +correspondents. This allows to clean your mailboxes formats) from these +annoyances which make it hard to follow a discussion. + +If you want to use these functions with IMAP, you need to compile Mutt +with the Linking threads +

+ +Some mailers tend to "forget" to correctly set the "In-Reply-To:" and +"References:" headers when replying to a message. This results in broken +discussions because Mutt has not enough information to guess the correct +threading. +You can fix this by tagging the reply, then moving to the parent message +and using the ``link-threads'' function (bound to & by default). The +reply will then be connected to this "parent" message. + +You can also connect multiple childs at once, tagging them and using the +tag-prefix command (';') or the auto_tag option. + +Breaking threads +

+ +On mailing lists, some people are in the bad habit of starting a new +discussion by hitting "reply" to any message from the list and changing +the subject to a totally unrelated one. +You can fix such threads by using the ``break-thread'' function (bound +by default to #), which will turn the subthread starting from the +current message into a whole different thread. + Delivery Status Notification (DSN) Support

+ RFC1894 defines a set of MIME content types for relaying information about the status of electronic mail messages. These can be thought of as ``return receipts.'' Berkeley sendmail 8.8.x currently has some command @@ -2537,6 +2637,168 @@ macro pager \cb |urlview\n +Compressed folders Support (OPTIONAL) +

+ +If Mutt was compiled with compressed folders support (by running the +, + and ) which define commands to uncompress and compress +a folder and to append messages to an existing compressed folder +respectively. + +For example: + + +open-hook \\.gz$ "gzip -cd %f > %t" +close-hook \\.gz$ "gzip -c %t > %f" +append-hook \\.gz$ "gzip -c %t >> %f" + + +You do not have to specify all of the commands. If you omit , the folder will be open and +closed again each time you will add to it. If you omit (or give empty command) , the +folder will be open in the mode. If you specify though you'll be able to append +to the folder. + +Note that Mutt will only try to use hooks if the file is not in one of +the accepted formats. In particular, if the file is empty, mutt +supposes it is not compressed. This is important because it allows the +use of programs that do not have well defined extensions. Just use +&dquot;.&dquot; as a regexp. But this may be surprising if your +compressing script produces empty files. In this situation, unset , so that the compressed file +will be removed if you delete all of the messages. + +Open a compressed mailbox for reading

+Usage: +open-hook \\.gz$ "gzip -cd %f > %t" + + +If the Write a compressed mailbox

+Usage: command after some changes were made to it. + +The command. Temporary folder +in this case is the folder previously produced by the < command. + +The +close-hook \\.gz$ "gzip -c %t > %f" + + +If the is not called when you exit +from the folder if the folder was not changed. + +Append a message to a compressed mailbox

+Usage: command. +The temporary folder in this case contains the messages that are being +appended. + +The +append-hook \\.gz$ "gzip -c %t >> %f" + + +When is used, the folder is +not opened, which saves time, but this means that we can not find out +what the folder type is. Thus the default () type is always supposed (i.e. +this is the format used for the temporary folder). + +If the file does not exist when you save to it, is called, and not . is only +for appending to existing folders. + +If the and respectively) each time you will add to it. + +Encrypted folders +

+The compressed folders support can also be used to handle encrypted +folders. If you want to encrypt a folder with PGP, you may want to use +the following hooks: + + +open-hook \\.pgp$ "pgp -f < %f > %t" +close-hook \\.pgp$ "pgp -fe YourPgpUserIdOrKeyId < %t > %f" + + +Please note, that PGP does not support appending to an encrypted +folder, so there is no append-hook defined. + +Mutt's MIME Support

Quite a bit of effort has been made to make Mutt the premier text-mode @@ -3029,6 +3291,21 @@ To remove a MIME type from the (-) and (+) +bindings.) Edit the descriptions, if you wish. Then tag the attachments +that are alternatives, and press the (&) binding +to group them together. The separate parts will be replaced by a single +new part with the multipart/alternative type. From this point on, the +alternatives must be manipulated or deleted as a group. + +Beware that such messages cannot be postponed. Once two attachments are +grouped as alternatives, they must be sent or lost. + + MIME Lookup

Mutt's mime_lookup list specifies a list of mime-types that should not @@ -3116,6 +3393,8 @@ + + + diff -Pur mutt-1.5.8-base/doc/manual.txt mutt-1.5.8-mega/doc/manual.txt --- mutt-1.5.8-base/doc/manual.txt Sat Feb 12 14:57:49 2005 +++ mutt-1.5.8-mega/doc/manual.txt Thu Mar 10 17:51:40 2005 @@ -2235,6 +2235,7 @@ ~v message is part of a collapsed thread. ~V cryptographically verified messages ~x EXPR messages which contain EXPR in the `References' field + ~X [MIN]-[MAX] messages with MIN - MAX attachments *) ~y EXPR messages which contain EXPR in the `X-Label' field ~z [MIN]-[MAX] messages with a size in the range MIN to MAX *) ~= duplicated messages (see $duplicate_threads) @@ -2614,9 +2615,12 @@ individually). The ``$index_format'' variable's ``%y'' and ``%Y'' escapes can be used to expand ``X-Label:'' fields in the index, and Mutt's pattern-matcher can match regular expressions to ``X-Label:'' - fields with the ``y'' selector. ``X-Label:'' is not a standard + fields with the ``~y'' selector. ``X-Label:'' is not a standard message header field, but it can easily be inserted by procmail and - other mail filtering agents. + other mail filtering agents. You can change or delete the + ``X-Label:'' field within Mutt using the ``edit-label'' command, + bound to the ``y'' key by default. This works for tagged messages, + too. Lastly, Mutt has the ability to ``sort'' the mailbox into ``threads''. A thread is a group of messages which all relate to the same subject. @@ -4543,6 +4547,8 @@ %v first name of the author, or the recipient if the message is from you + + %%XX number of attachments (%-X: number of top-level attachments) %y `x-label:' field, if present diff -Pur mutt-1.5.8-base/doc/muttrc.man mutt-1.5.8-mega/doc/muttrc.man --- mutt-1.5.8-base/doc/muttrc.man Sat Feb 12 14:54:45 2005 +++ mutt-1.5.8-mega/doc/muttrc.man Thu Mar 10 18:31:12 2005 @@ -316,6 +316,24 @@ to a certain recipient. The meaning of "key ID" is to be taken broadly: This can be a different e-mail address, a numerical key ID, or even just an arbitrary search string. +.PP +.nf +\fBopen-hook\fP \fIregexp\fP "\fIcommand\fP" +\fBclose-hook\fP \fIregexp\fP "\fIcommand\fP" +\fBappend-hook\fP \fIregexp\fP "\fIcommand\fP" +.fi +.IP +These commands provide a way to handle compressed folders. The given +\fBregexp\fP specifies which folders are taken as compressed (e.g. +"\fI\\\\.gz$\fP"). The commands tell Mutt how to uncompress a folder +(\fBopen-hook\fP), compress a folder (\fBclose-hook\fP) or append a +compressed mail to a compressed folder (\fBappend-hook\fP). The +\fIcommand\fP string is the +.BR printf (3) +like format string, and it should accept two parameters: \fB%f\fP, +which is replaced with the (compressed) folder name, and \fB%t\fP +which is replaced with the name of the temporary folder to which to +write. .TP \fBpush\fP \fIstring\fP This command adds the named \fIstring\fP to the keyboard buffer. @@ -435,6 +453,7 @@ ~U unread messages ~v message is part of a collapsed thread. ~x \fIEXPR\fP messages which contain \fIEXPR\fP in the \(lqReferences\(rq field +~X \fIMIN\fP-\fIMAX\fP messages with MIN - MAX attachments ~z \fIMIN\fP-\fIMAX\fP messages with a size in the range \fIMIN\fP to \fIMAX\fP ~= duplicated messages (see $duplicate_threads) ~$ unreferenced message (requries threaded view) @@ -442,7 +461,7 @@ .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~X\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 @@ -720,7 +739,11 @@ .IP %|X pad to the end of the line with character \(rqX\(rq -.RE +.IP %*X +soft-fill with character \(rqX\(rq as pad + +.REFor an explanation of `soft-fill', see the \(lq$index_format\(rq documentation. + .TP .B attach_sep @@ -748,6 +771,28 @@ .TP +.B attach_ignore_fundamental +.nf +Type: boolean +Default: yes +.fi +.IP +If set, Mutt's attachment counter discounts the fundamental MIME +part if its disposition is inline. + + +.TP +.B attach_recurse +.nf +Type: boolean +Default: yes +.fi +.IP +If set, Mutt's attachment counter (%X/~X) will examine message/* +components for attachments. + + +.TP .B attribution .nf Type: string @@ -884,6 +929,19 @@ .TP +.B uncollapse_new +.nf +Type: boolean +Default: yes +.fi +.IP +When \fIset\fP, Mutt will automatically uncollapse any collapsed thread +that receives a new message. When \fIunset\fP, collapsed threads will +remain collapsed. the presence of the new message will still affect +index sorting, though. + + +.TP .B compose_format .nf Type: string @@ -1109,17 +1167,6 @@ .TP -.B dotlock_program -.nf -Type: path -Default: \(lq/usr/local/bin/mutt_dotlock\(rq -.fi -.IP -Contains the path of the mutt_dotlock (8) binary to be used by -mutt. - - -.TP .B dsn_notify .nf Type: string @@ -1270,6 +1317,16 @@ .TP +.B flag_safe +.nf +Type: boolean +Default: no +.fi +.IP +If set, flagged messages cannot be deleted. + + +.TP .B folder .nf Type: path @@ -1333,7 +1390,11 @@ .IP %|X pad to the end of the line with character \(rqX\(rq -.RE +.IP %*X +soft-fill with character \(rqX\(rq as pad + +.REFor an explanation of `soft-fill', see the \(lq$index_format\(rq documentation. + .TP .B followup_to @@ -1938,6 +1999,9 @@ .IP %v first name of the author, or the recipient if the message is from you +.IP %X +number of attachments + .IP %y `x-label:' field, if present @@ -1974,7 +2038,16 @@ .IP %|X pad to the end of the line with character \(rqX\(rq -.RE +.IP %*X +soft-fill with character \(rqX\(rq as pad + +.RE`Soft-fill' deserves some explanation. Normal right-justification +will print everything to the left of the %>, displaying padding and +the whatever lies to the right only if there's room. By contrast, +soft-fill gives priority to the right-hand side, guaranteeing space +to display it and showing padding only if there's still room. If +necessary, soft-fill will eat text leftwards to make room for +rightward text. .IP See also: \(lq$to_chars\(rq. @@ -1983,7 +2056,7 @@ .B ispell .nf Type: path -Default: \(lq/usr/bin/ispell\(rq +Default: \(lq/opt/bin/ispell\(rq .fi .IP How to invoke ispell (GNU's spell-checking software). @@ -2013,6 +2086,18 @@ .TP +.B mark_macro_prefix +.nf +Type: string +Default: \(lq'\(rq +.fi +.IP +Prefix for macros created using mark-message. A new macro +automatically generated with \fIa\fP will be composed +from this prefix and the letter \fIa\fP. + + +.TP .B mail_check .nf Type: number @@ -2050,6 +2135,33 @@ .TP +.B header_cache +.nf +Type: path +Default: \(lq\(rq +.fi +.IP +The header_cache variable points to the header cache database. If +header_cache points to a directory there will be created one header cache +database per folder within this directory. If it doesn't point to a directory a +global header cache for all folders is used. Per default it is unset and so +no header caching will be used. + + +.TP +.B header_cache_pagesize +.nf +Type: string +Default: \(lq16384\(rq +.fi +.IP +Change the header cache database page size. Too large or to small values +can waste space, memory, or CPU time. The default should be more or +less the best you can get. For details google after mutt header +cache (first hit). + + +.TP .B maildir_trash .nf Type: boolean @@ -2074,6 +2186,12 @@ With this option set, the next time you start mutt, the messages will show up with an \(rqO\(rq next to them in the index menu, indicating that they are old. +.IP +If unset, messages remain \fInew\fP until they are read or the +\fInew\fP flag is explicitly removed. See also the \(lq$see_old\(rq +variable. +.IP +N.B. This variable does not affect IMAP folders. .TP @@ -2145,6 +2263,18 @@ .TP +.B menu_move_off +.nf +Type: boolean +Default: no +.fi +.IP +When \fIunset\fP, the bottom entry of menus will never scroll up past +the bottom of the screen, unless there are less entries than lines. +When \fIset\fP, the bottom entry may move off the bottom. + + +.TP .B menu_scroll .nf Type: boolean @@ -2174,6 +2304,31 @@ .TP +.B mdn_enable +.nf +Type: boolean +Default: no +.fi +.IP +When set, the message disposition notification support (RFC-2298) +is enabled. This shows an extra menu entry in the composer menu and +enables all the other MDN features. Keep it disabled to prevent any +disposition notifications to be send. + + +.TP +.B mdn_confirm +.nf +Type: boolean +Default: no +.fi +.IP +When set, a confirmation to send a message disposition +notification is always requested. When unset, a confirmation is +only requested for suspect messages as demanded by RFC-2298. + + +.TP .B mh_purge .nf Type: boolean @@ -2207,6 +2362,17 @@ .TP +.B mh_seq_mdnsent +.nf +Type: string +Default: \(lqmdnsent\(rq +.fi +.IP +The name of the MH sequence used to mark messages for whom a +message disposition notice has already been sent. + + +.TP .B mh_seq_unseen .nf Type: string @@ -3977,6 +4143,18 @@ .TP +.B see_old +.nf +Type: boolean +Default: yes +.fi +.IP +Controls whether or not Mutt makes the distinction between \fInew\fP +messages and \fIold\fP \fBunread\fP messages. In order to make Mutt +treat all unread messages as new only, you can unset this variable. + + +.TP .B score .nf Type: boolean @@ -4045,7 +4223,7 @@ .B sendmail .nf Type: path -Default: \(lq/usr/sbin/sendmail -oem -oi\(rq +Default: \(lq/usr/lib/sendmail -oem -oi\(rq .fi .IP Specifies the program and arguments used to deliver mail sent by Mutt. @@ -4448,7 +4626,10 @@ .IP %|X pad to the end of the line with \(rqX\(rq -.RE +.IP %*X +soft-fill with character \(rqX\(rq as pad + +.REFor an explanation of `soft-fill', see the \(lq$index_format\(rq documentation. .IP * = can be optionally printed if nonzero .IP @@ -4674,18 +4855,6 @@ sending messages. If \fIunset\fP, no `From:' header field will be generated unless the user explicitly sets one using the \(lqmy_hdr\(rq command. - - -.TP -.B use_idn -.nf -Type: boolean -Default: yes -.fi -.IP -When \fIset\fP, Mutt will show you international domain names decoded. -Note: You can use IDNs for addresses even if this is \fIunset\fP. -This variable only affects decoding. .TP diff -Pur mutt-1.5.8-base/doc/muttrc.man.head mutt-1.5.8-mega/doc/muttrc.man.head --- mutt-1.5.8-base/doc/muttrc.man.head Sat Jan 15 03:42:45 2005 +++ mutt-1.5.8-mega/doc/muttrc.man.head Thu Mar 10 17:50:15 2005 @@ -316,6 +316,24 @@ to a certain recipient. The meaning of "key ID" is to be taken broadly: This can be a different e-mail address, a numerical key ID, or even just an arbitrary search string. +.PP +.nf +\fBopen-hook\fP \fIregexp\fP "\fIcommand\fP" +\fBclose-hook\fP \fIregexp\fP "\fIcommand\fP" +\fBappend-hook\fP \fIregexp\fP "\fIcommand\fP" +.fi +.IP +These commands provide a way to handle compressed folders. The given +\fBregexp\fP specifies which folders are taken as compressed (e.g. +"\fI\\\\.gz$\fP"). The commands tell Mutt how to uncompress a folder +(\fBopen-hook\fP), compress a folder (\fBclose-hook\fP) or append a +compressed mail to a compressed folder (\fBappend-hook\fP). The +\fIcommand\fP string is the +.BR printf (3) +like format string, and it should accept two parameters: \fB%f\fP, +which is replaced with the (compressed) folder name, and \fB%t\fP +which is replaced with the name of the temporary folder to which to +write. .TP \fBpush\fP \fIstring\fP This command adds the named \fIstring\fP to the keyboard buffer. @@ -435,6 +453,7 @@ ~U unread messages ~v message is part of a collapsed thread. ~x \fIEXPR\fP messages which contain \fIEXPR\fP in the \(lqReferences\(rq field +~X \fIMIN\fP-\fIMAX\fP messages with MIN - MAX attachments ~z \fIMIN\fP-\fIMAX\fP messages with a size in the range \fIMIN\fP to \fIMAX\fP ~= duplicated messages (see $duplicate_threads) ~$ unreferenced message (requries threaded view) @@ -442,7 +461,7 @@ .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~X\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 Only in mutt-1.5.8-base/doc: stamp-doc-man Only in mutt-1.5.8-base/doc: stamp-doc-sgml diff -Pur mutt-1.5.8-base/flags.c mutt-1.5.8-mega/flags.c --- mutt-1.5.8-base/flags.c Thu Feb 3 12:47:52 2005 +++ mutt-1.5.8-mega/flags.c Thu Mar 10 17:50:20 2005 @@ -51,7 +51,8 @@ if (bf) { - if (!h->deleted && !ctx->readonly) + if (!h->deleted && !ctx->readonly + && (!h->flagged || !option(OPTFLAGSAFE))) { h->deleted = 1; if (upd_ctx) ctx->deleted++; @@ -102,7 +103,7 @@ if (bf) { - if (h->read || h->old) + if (h->read || (option(OPTSEEOLD) && h->old)) { h->old = 0; if (upd_ctx) ctx->new++; @@ -221,6 +222,24 @@ } break; + case M_MDNSENT: + if (bf) + { + if (!h->mdnsent) + { + h->mdnsent = bf; + h->changed = 1; + if (upd_ctx) ctx->changed = 1; + } + } + else if (h->mdnsent) + { + h->mdnsent = 0; + h->changed = 1; + if (upd_ctx) ctx->changed = 1; + } + break; + case M_FLAG: #ifdef USE_IMAP @@ -360,6 +379,11 @@ case 'o': case 'O': + if (!option(OPTSEEOLD)) { + mutt_error _("Set $see_old first"); + return (-1); + } + if (h) mutt_set_flag (Context, h, M_READ, !bf); else diff -Pur mutt-1.5.8-base/functions.h mutt-1.5.8-mega/functions.h --- mutt-1.5.8-base/functions.h Fri Jan 28 07:13:12 2005 +++ mutt-1.5.8-mega/functions.h Thu Mar 10 17:51:40 2005 @@ -49,6 +49,7 @@ { "previous-line", OP_PREV_LINE, "<" }, { "half-up", OP_HALF_UP, "[" }, { "half-down", OP_HALF_DOWN, "]" }, + { "mark-message", OP_MARK_MSG, "~" }, { "help", OP_HELP, "?" }, { "tag-prefix", OP_TAG_PREFIX, ";" }, { "tag-prefix-cond", OP_TAG_PREFIX_COND, NULL }, @@ -69,6 +70,7 @@ struct binding_t OpMain[] = { { "create-alias", OP_CREATE_ALIAS, "a" }, { "bounce-message", OP_BOUNCE_MESSAGE, "b" }, + { "break-thread", OP_MAIN_BREAK_THREAD, "#" }, { "change-folder", OP_MAIN_CHANGE_FOLDER, "c" }, { "change-folder-readonly", OP_MAIN_CHANGE_FOLDER_READONLY, "\033c" }, { "collapse-thread", OP_MAIN_COLLAPSE_THREAD, "\033v" }, @@ -81,6 +83,7 @@ { "delete-thread", OP_DELETE_THREAD, "\004" }, { "delete-subthread", OP_DELETE_SUBTHREAD, "\033d" }, { "edit", OP_EDIT_MESSAGE, "e" }, + { "edit-label", OP_EDIT_LABEL, "y" }, { "edit-type", OP_EDIT_TYPE, "\005" }, { "forward-message", OP_FORWARD_MESSAGE, "f" }, { "flag-message", OP_FLAG_MESSAGE, "F" }, @@ -95,6 +98,7 @@ { "next-undeleted", OP_MAIN_NEXT_UNDELETED, "j" }, { "previous-undeleted", OP_MAIN_PREV_UNDELETED, "k" }, { "limit", OP_MAIN_LIMIT, "l" }, + { "link-threads", OP_MAIN_LINK_THREADS, "&" }, { "list-reply", OP_LIST_REPLY, "L" }, { "mail", OP_MAIL, "m" }, { "toggle-new", OP_TOGGLE_NEW, "N" }, @@ -153,6 +157,7 @@ }; struct binding_t OpPager[] = { + { "break-thread", OP_MAIN_BREAK_THREAD, "#" }, { "create-alias", OP_CREATE_ALIAS, "a" }, { "bounce-message", OP_BOUNCE_MESSAGE, "b" }, { "change-folder", OP_MAIN_CHANGE_FOLDER, "c" }, @@ -163,6 +168,7 @@ { "delete-thread", OP_DELETE_THREAD, "\004" }, { "delete-subthread", OP_DELETE_SUBTHREAD, "\033d" }, { "edit", OP_EDIT_MESSAGE, "e" }, + { "edit-label", OP_EDIT_LABEL, "y" }, { "edit-type", OP_EDIT_TYPE, "\005" }, { "forward-message", OP_FORWARD_MESSAGE, "f" }, { "flag-message", OP_FLAG_MESSAGE, "F" }, @@ -175,6 +181,7 @@ { "next-entry", OP_NEXT_ENTRY, "J" }, { "previous-undeleted",OP_MAIN_PREV_UNDELETED, "k" }, { "previous-entry", OP_PREV_ENTRY, "K" }, + { "link-threads", OP_MAIN_LINK_THREADS, "&" }, { "list-reply", OP_LIST_REPLY, "L" }, { "redraw-screen", OP_REDRAW, "\014" }, { "mail", OP_MAIL, "m" }, @@ -289,11 +296,16 @@ { "edit-fcc", OP_COMPOSE_EDIT_FCC, "f" }, { "filter-entry", OP_FILTER, "F" }, { "get-attachment", OP_COMPOSE_GET_ATTACHMENT, "G" }, + { "group-alternatives", OP_COMPOSE_GROUP_ALTS, "&" }, + { "move-up", OP_COMPOSE_MOVE_UP, "-" }, + { "move-down", OP_COMPOSE_MOVE_DOWN, "+" }, { "display-toggle-weed", OP_DISPLAY_HEADERS, "h" }, { "ispell", OP_COMPOSE_ISPELL, "i" }, { "print-entry", OP_PRINT, "l" }, { "edit-mime", OP_COMPOSE_EDIT_MIME, "m" }, { "new-mime", OP_COMPOSE_NEW_MIME, "n" }, + { "edit-dnt", OP_COMPOSE_EDIT_DNT, "\033n" }, + { "switch-dnt", OP_COMPOSE_SWITCH_DNT, "\033N" }, { "postpone-message", OP_COMPOSE_POSTPONE_MESSAGE, "P" }, { "edit-reply-to", OP_COMPOSE_EDIT_REPLY_TO, "r" }, { "rename-file", OP_COMPOSE_RENAME_FILE, "R" }, diff -Pur mutt-1.5.8-base/globals.h mutt-1.5.8-mega/globals.h --- mutt-1.5.8-base/globals.h Sat Feb 12 14:01:02 2005 +++ mutt-1.5.8-mega/globals.h Thu Mar 10 17:50:20 2005 @@ -69,10 +69,12 @@ WHERE char *HeaderCache; WHERE char *HeaderCachePageSize; #endif +WHERE char *MarkMacroPrefix; WHERE char *MhFlagged; WHERE char *MhReplied; WHERE char *MhUnseen; WHERE char *MsgFmt; +WHERE char *MhMdnsent; #ifdef USE_SOCKET WHERE char *Preconnect INITVAL (NULL); @@ -133,10 +135,17 @@ WHERE LIST *AutoViewList INITVAL(0); WHERE LIST *AlternativeOrderList INITVAL(0); +WHERE LIST *AttachAllow INITVAL(0); +WHERE LIST *AttachExclude INITVAL(0); +WHERE LIST *InlineAllow INITVAL(0); +WHERE LIST *InlineExclude INITVAL(0); WHERE LIST *HeaderOrderList INITVAL(0); WHERE LIST *Ignore INITVAL(0); WHERE LIST *MimeLookupList INITVAL(0); WHERE LIST *UnIgnore INITVAL(0); +WHERE LIST *MdnAllow INITVAL(0); +WHERE LIST *MdnDeny INITVAL(0); +WHERE LIST *MdnDntDefaults INITVAL(0); WHERE RX_LIST *Alternates INITVAL(0); WHERE RX_LIST *UnAlternates INITVAL(0); diff -Pur mutt-1.5.8-base/handler.c mutt-1.5.8-mega/handler.c --- mutt-1.5.8-base/handler.c Thu Feb 3 12:47:52 2005 +++ mutt-1.5.8-mega/handler.c Thu Mar 10 17:50:20 2005 @@ -1807,6 +1807,8 @@ plaintext = 1; else if (!ascii_strcasecmp ("external-body", b->subtype)) handler = external_body_handler; + else if (!ascii_strcasecmp ("disposition-notification", b->subtype)) + plaintext = 1; } else if (b->type == TYPEMULTIPART) { diff -Pur mutt-1.5.8-base/hdrline.c mutt-1.5.8-mega/hdrline.c --- mutt-1.5.8-base/hdrline.c Sat Feb 12 12:53:35 2005 +++ mutt-1.5.8-mega/hdrline.c Thu Mar 10 17:50:14 2005 @@ -218,6 +218,7 @@ * %T = $to_chars * %u = user (login) name of author * %v = first name of author, unless from self + * %X = number of MIME attachments * %y = `x-label:' field (if present) * %Y = `x-label:' field (if present, tree unfolded, and != parent's x-label) * %Z = status flags */ @@ -322,6 +323,53 @@ const char *cp; struct tm *tm; time_t T; + int i = 0, invert = 0; + + if (optional && (op == '[' || op == '(')) { + char *is; + T = time(NULL); + T -= (op == '(') ? hdr->received : hdr->date_sent; + + is = (char *)prefix; + if( *is == '>' ) { + invert = 1; + ++is; + } + + while( *is && *is != '?' ) { + int t = strtol (is, &is, 10); + switch (*(is++)) { + case '?': + break; + case 'y': + t *= 365 * 24 * 60 * 60; + break; + case 'M': + t *= 30 * 24 * 60 * 60; + break; + case 'w': + t *= 7 * 24 * 60 * 60; + break; + case 'd': + t *= 24 * 60 * 60; + break; + case 'h': + t *= 60 * 60; + break; + case 'm': + t *= 60; + break; + } + i += t; + } + + if (i < 0) + i *= -1; + + if( (T > i || T < -1*i) ^ invert ) + optional = 0; + break; + } p = dest; @@ -571,7 +619,7 @@ ch = 'r'; else if (hdr->read && (ctx && ctx->msgnotreadyet != hdr->msgno)) ch = '-'; - else if (hdr->old) + else if (option(OPTSEEOLD) && hdr->old) ch = 'O'; else ch = 'N'; @@ -646,12 +694,50 @@ snprintf (buf2, sizeof (buf2), "%c%c%c", (THREAD_NEW ? 'n' : (THREAD_OLD ? 'o' : ((hdr->read && (ctx && ctx->msgnotreadyet != hdr->msgno)) - ? (hdr->replied ? 'r' : ' ') : (hdr->old ? 'O' : 'N')))), + ? (hdr->replied ? 'r' : ' ') : + ((option(OPTSEEOLD) && hdr->old) ? 'O' : 'N')))), 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 'X': + { + int i, flags; + struct body *parts; + + flags = 0; + + if (option(OPTATRECURSE)) + flags |= M_PARTS_MSGTRANS; + + /* Find whether MIME structure is parsed. */ + parts = hdr->content->parts; + + /* If not then parse it. */ + if (parts == NULL) + { + mutt_parse_mime_message(ctx, hdr); + } + + /* Count parts. */ + i = mutt_count_body_parts(hdr->content, flags); + + /* If not pre-parsed, throw out our work. */ + if (parts == NULL) + { + 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': diff -Pur mutt-1.5.8-base/headers.c mutt-1.5.8-mega/headers.c --- mutt-1.5.8-base/headers.c Thu Feb 3 12:47:52 2005 +++ mutt-1.5.8-mega/headers.c Thu Mar 10 17:51:40 2005 @@ -205,3 +205,59 @@ } } } + +/* + * dgc: Add an X-Label: field. + */ +static int label_message(HEADER *hdr, char *new) +{ + if (hdr == NULL) + return 0; + if (hdr->env->x_label == NULL && new == NULL) + return 0; + if (hdr->env->x_label != NULL && new != NULL && + strcmp(hdr->env->x_label, new) == 0) + return 0; + if (hdr->env->x_label != NULL) + FREE(&hdr->env->x_label); + if (new == NULL) + hdr->env->x_label = NULL; + else + hdr->env->x_label = safe_strdup(new); + return hdr->changed = hdr->xlabel_changed = 1; +} + +int mutt_label_message(HEADER *hdr) +{ + char buf[LONG_STRING], *new; + int i; + int changed; + + *buf = '\0'; + if (hdr != NULL && hdr->env->x_label != NULL) { + strncpy(buf, hdr->env->x_label, LONG_STRING); + } + + mutt_get_field("Label: ", buf, sizeof(buf), M_CLEAR); + new = buf; + SKIPWS(new); + if (*new == '\0') + new = NULL; + + changed = 0; + if (hdr != NULL) { + changed += label_message(hdr, new); + } else { +#define HDR_OF(index) Context->hdrs[Context->v2r[(index)]] + for (i = 0; i < Context->vcount; ++i) { + if (HDR_OF(i)->tagged) + if (label_message(HDR_OF(i), new)) { + ++changed; + mutt_set_flag(Context, HDR_OF(i), + M_TAG, 0); + } + } + } + + return changed; +} diff -Pur mutt-1.5.8-base/hook.c mutt-1.5.8-mega/hook.c --- mutt-1.5.8-base/hook.c Thu Feb 3 12:47:52 2005 +++ mutt-1.5.8-mega/hook.c Thu Mar 10 17:50:15 2005 @@ -24,6 +24,10 @@ #include "mailbox.h" #include "mutt_crypt.h" +#ifdef USE_COMPRESSED +#include "compress.h" +#endif + #include #include #include @@ -92,6 +96,16 @@ memset (&pattern, 0, sizeof (pattern)); pattern.data = safe_strdup (path); } +#ifdef USE_COMPRESSED + else if (data & (M_APPENDHOOK | M_OPENHOOK | M_CLOSEHOOK)) + { + if (mutt_test_compress_command (command.data)) + { + strfcpy (err->data, _("bad formatted command string"), err->dsize); + return (-1); + } + } +#endif else if (DefaultHook && !(data & (M_CHARSETHOOK | M_ACCOUNTHOOK)) && (!WithCrypto || !(data & M_CRYPTHOOK)) ) diff -Pur mutt-1.5.8-base/imap/Makefile.in mutt-1.5.8-mega/imap/Makefile.in --- mutt-1.5.8-base/imap/Makefile.in Sat Feb 12 14:58:24 2005 +++ mutt-1.5.8-mega/imap/Makefile.in Thu Mar 10 18:01:23 2005 @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.9.2 from Makefile.am. +# Makefile.in generated by automake 1.9 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, @@ -37,7 +37,6 @@ NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : -build_triplet = @build@ host_triplet = @host@ subdir = imap DIST_COMMON = README $(noinst_HEADERS) $(srcdir)/Makefile.am \ diff -Pur mutt-1.5.8-base/imap/imap.c mutt-1.5.8-mega/imap/imap.c --- mutt-1.5.8-base/imap/imap.c Thu Feb 3 12:47:54 2005 +++ mutt-1.5.8-mega/imap/imap.c Thu Mar 10 17:52:49 2005 @@ -975,7 +975,7 @@ /* save status changes */ for (n = 0; n < ctx->msgcount; n++) { - if (ctx->hdrs[n]->active && ctx->hdrs[n]->changed) + if (ctx->hdrs[n]->active && (ctx->hdrs[n]->changed || ctx->hdrs[n]->xlabel_changed)) { ctx->hdrs[n]->changed = 0; @@ -987,9 +987,12 @@ mutt_buffer_addstr (&cmd, "UID STORE "); mutt_buffer_addstr (&cmd, uid); - /* if attachments have been deleted we delete the message and reupload - * it. This works better if we're expunging, of course. */ - if (ctx->hdrs[n]->attach_del) + /* if the message has been rethreaded or attachments have been deleted + * we delete the message and reupload it. + * This works better if we're expunging, of course. */ + /* AFAICT (dgc) we need to do this for header changes, too. */ + if (ctx->hdrs[n]->refs_changed || ctx->hdrs[n]->irt_changed || + ctx->hdrs[n]->attach_del || ctx->hdrs[n]->xlabel_changed) { dprint (3, (debugfile, "imap_sync_mailbox: Attachments to be deleted, falling back to _mutt_save_message\n")); if (!appendctx) @@ -1000,6 +1003,7 @@ } else _mutt_save_message (ctx->hdrs[n], appendctx, 1, 0, 0); + ctx->hdrs[n]->xlabel_changed = 0; } flags[0] = '\0'; diff -Pur mutt-1.5.8-base/imap/message.c mutt-1.5.8-mega/imap/message.c --- mutt-1.5.8-base/imap/message.c Sat Feb 12 13:59:59 2005 +++ mutt-1.5.8-mega/imap/message.c Thu Mar 10 17:51:40 2005 @@ -332,6 +332,7 @@ IMAP_CACHE *cache; int read; int rc; + char *x_label = NULL; /* Sam's weird courier server returns an OK response even when FETCH * fails. Thanks Sam. */ short fetched = 0; @@ -469,8 +470,15 @@ hash_delete (ctx->id_hash, h->env->message_id, h, NULL); if (ctx->subj_hash && h->env->real_subj) hash_delete (ctx->subj_hash, h->env->real_subj, h, NULL); + /* And I hate to do this, but it's essential to keep an x-label across + * IMAP resync. */ + x_label = h->env->x_label; + h->env->x_label = NULL; mutt_free_envelope (&h->env); h->env = mutt_read_rfc822_header (msg->fp, h, 0, 0); + if (h->env->x_label) + FREE(&h->env->x_label); + h->env->x_label = x_label; if (ctx->id_hash && h->env->message_id) hash_insert (ctx->id_hash, h->env->message_id, h, 0); if (ctx->subj_hash && h->env->real_subj) @@ -1121,7 +1129,7 @@ if (*s == ')') { /* if a message is neither seen nor recent, it is OLD. */ - if (option (OPTMARKOLD) && !recent && !(h->read)) + if (!recent && !(h->read)) h->old = 1; s++; } diff -Pur mutt-1.5.8-base/init.c mutt-1.5.8-mega/init.c --- mutt-1.5.8-base/init.c Sat Feb 12 13:06:16 2005 +++ mutt-1.5.8-mega/init.c Thu Mar 10 17:50:20 2005 @@ -49,6 +49,8 @@ #include #include +extern char **envlist; + void toggle_quadoption (int opt) { int n = opt/4; @@ -774,6 +776,152 @@ return 0; } +static int parse_attach_list (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *err) +{ + ATTACH_MATCH *a; + LIST **ldata, *listp, *lastp; + char *p; + char *tmpminor; + int len; + + /* Find the last item in the list that data points to. */ + lastp = NULL; + ldata = (LIST **)data; + dprint(30, (debugfile, "parse_attach_list: ldata = %08x, *ldata = %08x\n", + (unsigned int)ldata, (unsigned int)*ldata)); + for (listp = *ldata; listp; listp = listp->next) + { + a = (ATTACH_MATCH *)listp->data; + dprint(30, (debugfile, "parse_attach_list: skipping %s/%s\n", + a->major, a->minor)); + lastp = listp; + } + + do + { + mutt_extract_token (buf, s, 0); + + if (!buf->data || *buf->data == '\0') + continue; + + a = safe_malloc(sizeof(ATTACH_MATCH)); + + /* some cheap hacks that I expect to remove */ + if (!mutt_strcasecmp(buf->data, "any")) + a->major = safe_strdup("*/.*"); + else if (!mutt_strcasecmp(buf->data, "none")) + a->major = safe_strdup("cheap_hack/this_should_never_match"); + else + a->major = safe_strdup(buf->data); + + if ((p = strchr(a->major, '/'))) + { + *p = '\0'; + ++p; + a->minor = p; + } + else + { + a->minor = "unknown"; + } + + len = strlen(a->minor); + tmpminor = safe_malloc(len+3); + strcpy(&tmpminor[1], a->minor); + tmpminor[0] = '^'; + tmpminor[len+1] = '$'; + tmpminor[len+2] = '\0'; + + a->major_int = mutt_check_mime_type(a->major); + regcomp(&a->minor_rx, tmpminor, REG_ICASE|REG_EXTENDED); + + safe_free(&tmpminor); + + dprint(30, (debugfile, "parse_attach_list: added %s/%s [%d]\n", + a->major, a->minor, a->major_int)); + + listp = safe_malloc(sizeof(LIST)); + listp->data = (char *)a; + listp->next = NULL; + if (lastp) + { + lastp->next = listp; + } + else + { + *ldata = listp; + } + lastp = listp; + } + while (MoreArgs (s)); + + return 0; +} + +static int parse_unattach_list (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *err) +{ + ATTACH_MATCH *a; + LIST **ldata, *lp, *lastp; + char *tmp; + int major; + char *minor; + + ldata = (LIST **)data; + do + { + mutt_extract_token (buf, s, 0); + + if (!mutt_strcasecmp(buf->data, "any")) + tmp = safe_strdup("*/.*"); + else if (!mutt_strcasecmp(buf->data, "none")) + tmp = safe_strdup("cheap_hack/this_should_never_match"); + else + tmp = safe_strdup(buf->data); + + if ((minor = strchr(tmp, '/'))) + { + *minor = '\0'; + ++minor; + } + else + { + minor = "unknown"; + } + major = mutt_check_mime_type(tmp); + + lastp = NULL; + for(lp = *ldata; lp; lp = lastp->next) + { + a = (ATTACH_MATCH *)lp->data; + dprint(30, (debugfile, "parse_unattach_list: check %s/%s [%d] : %s/%s [%d]\n", + a->major, a->minor, a->major_int, tmp, minor, major)); + if (a->major_int == major && !mutt_strcasecmp(minor, a->minor)) + { + dprint(30, (debugfile, "parse_unattach_list: removed %s/%s [%d]\n", + a->major, a->minor, a->major_int)); + regfree(&a->minor_rx); + free(a->major); + if (lastp) + { + lastp->next = lp->next; + } + lastp = lp; + free (lp->data); /* same as a */ + free (lp); + } + + lastp = lp; + lp = lp->next; + } + + remove_from_list ((LIST **) data, buf->data); + } + while (MoreArgs (s)); + + return 0; +} + + static int parse_unlists (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *err) { do @@ -1065,6 +1213,31 @@ return 0; } +/* FIXME? */ +static int parse_mdn_allow_deny (BUFFER *buf, BUFFER *s, + unsigned long data, BUFFER *err) +{ + do + { + mutt_extract_token (buf, s, 0); + add_to_list ((LIST **) data, buf->data); + } + while (MoreArgs (s)); + + return 0; +} + +static int parse_mdn_dnt_defaults (BUFFER *buf, BUFFER *s, + unsigned long data, BUFFER *err) +{ + + mutt_extract_token (buf, s, M_TOKEN_SPACE | M_TOKEN_QUOTE); + add_to_list ((LIST **) data, buf->data); + memset (buf, 0, sizeof (BUFFER)); + + return 0; +} + static void mutt_set_default (struct option_t *p) { switch (p->type & DT_MASK) @@ -1189,6 +1362,91 @@ set_option (OPTRESORTINIT); if (p->flags & R_TREE) set_option (OPTREDRAWTREE); +} + +static int parse_setenv(BUFFER *tmp, BUFFER *s, unsigned long data, BUFFER *err) +{ + int query, unset, len; + char work[LONG_STRING]; + char **save, **envp = envlist; + + query = 0; + unset = data & M_SET_UNSET; + + if (MoreArgs (s)) + { + if (*s->dptr == '?') + { + query = 1; + s->dptr++; + } + + /* get variable name */ + mutt_extract_token (tmp, s, M_TOKEN_EQUAL); + len = strlen(tmp->data); + + if (query) + { + while (envp && *envp) + { + if (!strncmp(tmp->data, *envp, len)) + { + snprintf(err->data, err->dsize, "%s", *envp); + return 0; + } + envp++; + } + snprintf (err->data, err->dsize, _("%s is unset"), tmp->data); + return -1; + } + + if (unset) + { + while (envp && *envp) + { + if (!strncmp(tmp->data, *envp, len) && (*envp)[len] == '=') + { + /* shuffle down */ + save = envp++; + while (*envp) + *save++ = *envp++; + *save = NULL; + return 0; + } + envp++; + } + return -1; + } + + while (envp && *envp) + { + if (!strncmp(tmp->data, *envp, len) && (*envp)[len] == '=') + { + /* shuffle down */ + save = envp++; + while (*envp) + *save++ = *envp++; + *save = NULL; + envp = save; + break; + } + envp++; + } + + strncpy(work, tmp->data, sizeof(work)); + len = strlen(work); + + mutt_extract_token (tmp, s, 0); + + strncpy(&work[len], tmp->data, sizeof(work)-len); + + *envp++ = strdup(work); + *envp = NULL; + + return 0; + } + + return -1; } static int parse_set (BUFFER *tmp, BUFFER *s, unsigned long data, BUFFER *err) diff -Pur mutt-1.5.8-base/init.h mutt-1.5.8-mega/init.h --- mutt-1.5.8-base/init.h Sat Feb 12 14:01:10 2005 +++ mutt-1.5.8-mega/init.h Thu Mar 10 18:30:43 2005 @@ -208,7 +208,9 @@ ** .dt %u .dd unlink (=to delete) flag ** .dt %>X .dd right justify the rest of the string and pad with character "X" ** .dt %|X .dd pad to the end of the line with character "X" + ** .dt %*X .dd soft-fill with character "X" as pad ** .de + ** For an explanation of `soft-fill', see the ``$$index_format'' documentation. */ { "attach_sep", DT_STR, R_NONE, UL &AttachSep, UL "\n" }, /* @@ -225,6 +227,18 @@ ** ``$$attach_sep'' separator is added after each attachment. When set, ** Mutt will operate on the attachments one by one. */ + { "attach_ignore_fundamental", DT_BOOL, R_INDEX, OPTATIGNORE, 1 }, + /* + ** .pp + ** If set, Mutt's attachment counter discounts the fundamental MIME + ** part if its disposition is inline. + */ + { "attach_recurse", DT_BOOL, R_INDEX, OPTATRECURSE, 1 }, + /* + ** .pp + ** If set, Mutt's attachment counter (%X/~X) will examine message/* + ** components for attachments. + */ { "attribution", DT_STR, R_NONE, UL &Attribution, UL "On %d, %n wrote:" }, /* ** .pp @@ -306,6 +320,14 @@ ** When \fIset\fP, Mutt will jump to the next unread message, if any, ** when the current thread is \fIun\fPcollapsed. */ + { "uncollapse_new", DT_BOOL, R_NONE, OPTUNCOLLAPSENEW, 1 }, + /* + ** .pp + ** When \fIset\fP, Mutt will automatically uncollapse any collapsed thread + ** that receives a new message. When \fIunset\fP, collapsed threads will + ** remain collapsed. the presence of the new message will still affect + ** index sorting, though. + */ { "compose_format", DT_STR, R_BOTH, UL &ComposeFormat, UL "-- Mutt: Compose [Approx. msg size: %l Atts: %a]%>-" }, /* ** .pp @@ -550,6 +572,11 @@ ** signed. ** (PGP only) */ + { "flag_safe", DT_BOOL, R_NONE, OPTFLAGSAFE, 0 }, + /* + ** .pp + ** If set, flagged messages cannot be deleted. + */ { "folder", DT_PATH, R_NONE, UL &Maildir, UL "~/Mail" }, /* ** .pp @@ -580,7 +607,9 @@ ** .dt %u .dd owner name (or numeric uid, if missing) ** .dt %>X .dd right justify the rest of the string and pad with character "X" ** .dt %|X .dd pad to the end of the line with character "X" + ** .dt %*X .dd soft-fill with character "X" as pad ** .de + ** For an explanation of `soft-fill', see the ``$$index_format'' documentation. */ { "followup_to", DT_BOOL, R_NONE, OPTFOLLOWUPTO, 1 }, /* @@ -960,6 +989,7 @@ ** .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 %X .dd number of attachments ** .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 @@ -978,7 +1008,15 @@ ** function ``strftime''; a leading bang disables locales. ** .dt %>X .dd right justify the rest of the string and pad with character "X" ** .dt %|X .dd pad to the end of the line with character "X" + ** .dt %*X .dd soft-fill with character "X" as pad ** .de + ** `Soft-fill' deserves some explanation. Normal right-justification + ** will print everything to the left of the %>, displaying padding and + ** the whatever lies to the right only if there's room. By contrast, + ** soft-fill gives priority to the right-hand side, guaranteeing space + ** to display it and showing padding only if there's still room. If + ** necessary, soft-fill will eat text leftwards to make room for + ** rightward text. ** .pp ** See also: ``$$to_chars''. */ @@ -1000,6 +1038,14 @@ ** The locale used by \fIstrftime(3)\fP to format dates. Legal values are ** the strings your system accepts for the locale variable \fILC_TIME\fP. */ + /* this absurd location avoids conflict with ats.mark_old patch */ + { "mark_macro_prefix",DT_STR, R_NONE, UL &MarkMacroPrefix, UL "'" }, + /* + ** .pp + ** Prefix for macros created using mark-message. A new macro + ** automatically generated with \fIa\fP will be composed + ** from this prefix and the letter \fIa\fP. + */ { "mail_check", DT_NUM, R_NONE, UL &BuffyTimeout, 5 }, /* ** .pp @@ -1049,7 +1095,7 @@ ** to maildir-style mailboxes. Setting it will have no effect on other ** mailbox types. */ - { "mark_old", DT_BOOL, R_BOTH, OPTMARKOLD, 1 }, + { "mark_old", DT_BOOL, R_BOTH, OPT_MARKOLD, 1 }, /* ** .pp ** Controls whether or not mutt marks \fInew\fP \fBunread\fP @@ -1057,6 +1103,12 @@ ** With this option set, the next time you start mutt, the messages ** will show up with an "O" next to them in the index menu, ** indicating that they are old. + ** .pp + ** If unset, messages remain \fInew\fP until they are read or the + ** \fInew\fP flag is explicitly removed. See also the ``$$see_old'' + ** variable. + ** .pp + ** N.B. This variable does not affect IMAP folders. */ { "markers", DT_BOOL, R_PAGER, OPTMARKERS, 1 }, /* @@ -1096,6 +1148,13 @@ ** This variable controls the number of lines of context that are given ** when scrolling through menus. (Similar to ``$$pager_context''.) */ + { "menu_move_off", DT_BOOL, R_NONE, OPTMENUMOVEOFF, 0 }, + /* + ** .pp + ** When \fIunset\fP, the bottom entry of menus will never scroll up past + ** the bottom of the screen, unless there are less entries than lines. + ** When \fIset\fP, the bottom entry may move off the bottom. + */ { "menu_scroll", DT_BOOL, R_NONE, OPTMENUSCROLL, 0 }, /* ** .pp @@ -1115,6 +1174,21 @@ ** high bit from ``0xf4'' is ``0x74'', which is the ASCII character ** ``x''. */ + { "mdn_enable", DT_BOOL, R_NONE, OPTMDNENABLE, 0 }, + /* + ** .pp + ** When set, the message disposition notification support (RFC-2298) + ** is enabled. This shows an extra menu entry in the composer menu and + ** enables all the other MDN features. Keep it disabled to prevent any + ** disposition notifications to be send. + */ + { "mdn_confirm", DT_BOOL, R_NONE, OPTMDNCONFIRM, 0 }, + /* + ** .pp + ** When set, a confirmation to send a message disposition + ** notification is always requested. When unset, a confirmation is + ** only requested for suspect messages as demanded by RFC-2298. + */ { "mh_purge", DT_BOOL, R_NONE, OPTMHPURGE, 0 }, /* ** .pp @@ -1133,6 +1207,12 @@ ** .pp ** The name of the MH sequence used to tag replied messages. */ + { "mh_seq_mdnsent", DT_STR, R_NONE, UL &MhMdnsent, UL "mdnsent" }, + /* + ** .pp + ** The name of the MH sequence used to mark messages for whom a + ** message disposition notice has already been sent. + */ { "mh_seq_unseen", DT_STR, R_NONE, UL &MhUnseen, UL "unseen" }, /* ** .pp @@ -2298,6 +2378,13 @@ ** .pp ** Also see the ``$$force_name'' variable. */ + { "see_old", DT_BOOL, R_BOTH, OPTSEEOLD, 1 }, + /* + ** .pp + ** Controls whether or not Mutt makes the distinction between \fInew\fP + ** messages and \fIold\fP \fBunread\fP messages. In order to make Mutt + ** treat all unread messages as new only, you can unset this variable. + */ { "score", DT_BOOL, R_NONE, OPTSCORE, 1 }, /* ** .pp @@ -2573,7 +2660,9 @@ ** .dt %V .dd currently active limit pattern, if any * ** .dt %>X .dd right justify the rest of the string and pad with "X" ** .dt %|X .dd pad to the end of the line with "X" + ** .dt %*X .dd soft-fill with character "X" as pad ** .de + ** For an explanation of `soft-fill', see the ``$$index_format'' documentation. ** .pp ** * = can be optionally printed if nonzero ** .pp @@ -2891,10 +2980,16 @@ static int parse_unignore (BUFFER *, BUFFER *, unsigned long, BUFFER *); static int parse_source (BUFFER *, BUFFER *, unsigned long, BUFFER *); static int parse_set (BUFFER *, BUFFER *, unsigned long, BUFFER *); +static int parse_setenv (BUFFER *, BUFFER *, unsigned long, BUFFER *); static int parse_my_hdr (BUFFER *, BUFFER *, unsigned long, BUFFER *); static int parse_unmy_hdr (BUFFER *, BUFFER *, unsigned long, BUFFER *); static int parse_subscribe (BUFFER *, BUFFER *, unsigned long, BUFFER *); static int parse_unsubscribe (BUFFER *, BUFFER *, unsigned long, BUFFER *); +static int parse_attach_list (BUFFER *, BUFFER *, unsigned long, BUFFER *); +static int parse_unattach_list (BUFFER *, BUFFER *, unsigned long, BUFFER *); +static int parse_mdn_allow_deny (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *err); +static int parse_mdn_dnt_defaults (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *err); + static int parse_alternates (BUFFER *, BUFFER *, unsigned long, BUFFER *); static int parse_unalternates (BUFFER *, BUFFER *, unsigned long, BUFFER *); @@ -2914,6 +3009,10 @@ { "account-hook", mutt_parse_hook, M_ACCOUNTHOOK }, #endif { "alias", parse_alias, 0 }, + { "attach-allow", parse_attach_list, UL &AttachAllow }, + { "attach-exclude", parse_attach_list, UL &AttachExclude }, + { "unattach-allow", parse_unattach_list, UL &AttachAllow }, + { "unattach-exclude", parse_unattach_list, UL &AttachExclude }, { "auto_view", parse_list, UL &AutoViewList }, { "alternative_order", parse_list, UL &AlternativeOrderList}, { "bind", mutt_parse_bind, 0 }, @@ -2926,15 +3025,27 @@ { "fcc-hook", mutt_parse_hook, M_FCCHOOK }, { "fcc-save-hook", mutt_parse_hook, M_FCCHOOK | M_SAVEHOOK }, { "folder-hook", mutt_parse_hook, M_FOLDERHOOK }, +#ifdef USE_COMPRESSED + { "open-hook", mutt_parse_hook, M_OPENHOOK }, + { "close-hook", mutt_parse_hook, M_CLOSEHOOK }, + { "append-hook", mutt_parse_hook, M_APPENDHOOK }, +#endif { "hdr_order", parse_list, UL &HeaderOrderList }, #ifdef HAVE_ICONV { "iconv-hook", mutt_parse_hook, M_ICONVHOOK }, #endif { "ignore", parse_ignore, 0 }, + { "inline-allow", parse_attach_list, UL &InlineAllow }, + { "inline-exclude", parse_attach_list, UL &InlineExclude }, + { "uninline-allow", parse_unattach_list, UL &InlineAllow }, + { "uninline-exclude", parse_unattach_list, UL &InlineExclude }, { "lists", parse_lists, 0 }, { "macro", mutt_parse_macro, 0 }, { "mailboxes", mutt_parse_mailboxes, M_MAILBOXES }, { "unmailboxes", mutt_parse_mailboxes, M_UNMAILBOXES }, + { "mdn_allow", parse_mdn_allow_deny, UL &MdnAllow }, + { "mdn_deny", parse_mdn_allow_deny, UL &MdnDeny }, + { "mdn_dnt_defaults", parse_mdn_dnt_defaults, UL &MdnDntDefaults }, { "message-hook", mutt_parse_hook, M_MESSAGEHOOK }, { "mbox-hook", mutt_parse_hook, M_MBOXHOOK }, { "mime_lookup", parse_list, UL &MimeLookupList }, @@ -2951,6 +3062,7 @@ { "send-hook", mutt_parse_hook, M_SENDHOOK }, { "send2-hook", mutt_parse_hook, M_SEND2HOOK }, { "set", parse_set, 0 }, + { "setenv", parse_setenv, 0 }, { "source", parse_source, 0 }, { "spam", parse_spam_list, M_SPAM }, { "nospam", parse_spam_list, M_NOSPAM }, @@ -2967,6 +3079,7 @@ { "unmy_hdr", parse_unmy_hdr, 0 }, { "unscore", mutt_parse_unscore, 0 }, { "unset", parse_set, M_SET_UNSET }, + { "unsetenv", parse_setenv, M_SET_UNSET }, { "unsubscribe", parse_unsubscribe, 0 }, { NULL } }; diff -Pur mutt-1.5.8-base/lib.h mutt-1.5.8-mega/lib.h --- mutt-1.5.8-base/lib.h Sat Feb 5 08:09:14 2005 +++ mutt-1.5.8-mega/lib.h Thu Mar 10 17:50:18 2005 @@ -84,6 +84,13 @@ # define MAX(a,b) ((a) < (b) ? (b) : (a)) # define MIN(a,b) ((a) < (b) ? (a) : (b)) +/* For mutt_format_string() justifications */ +/* Making left 0 and center -1 is of course completely nonsensical, but + * it retains compatibility for any patches that call mutt_format_string. + * Once patches are updated to use FMT_*, these can be made sane. */ +#define FMT_LEFT 0 +#define FMT_RIGHT 1 +#define FMT_CENTER -1 #define FOREVER while (1) diff -Pur mutt-1.5.8-base/m4/Makefile.in mutt-1.5.8-mega/m4/Makefile.in --- mutt-1.5.8-base/m4/Makefile.in Sat Feb 12 14:58:24 2005 +++ mutt-1.5.8-mega/m4/Makefile.in Thu Mar 10 18:01:23 2005 @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.9.2 from Makefile.am. +# Makefile.in generated by automake 1.9 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, @@ -33,7 +33,6 @@ NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : -build_triplet = @build@ host_triplet = @host@ subdir = m4 DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in diff -Pur mutt-1.5.8-base/main.c mutt-1.5.8-mega/main.c --- mutt-1.5.8-base/main.c Sat Feb 12 13:41:32 2005 +++ mutt-1.5.8-mega/main.c Thu Mar 10 17:50:19 2005 @@ -85,6 +85,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.\n\ "); +char **envlist; + void mutt_exit (int code) { mutt_endwin (NULL); @@ -239,6 +241,12 @@ "-USE_IMAP " #endif +#ifdef IMAP_EDIT_THREADS + "+IMAP_EDIT_THREADS " +#else + "-IMAP_EDIT_THREADS " +#endif + #ifdef USE_GSS "+USE_GSS " #else @@ -282,6 +290,12 @@ "-USE_GNU_REGEX " #endif +#ifdef USE_COMPRESSED + "+COMPRESSED " +#else + "-COMPRESSED " +#endif + "\n" #ifdef HAVE_COLOR @@ -500,7 +514,7 @@ #define M_RO (1<<3) /* -R */ #define M_SELECT (1<<4) /* -y */ -int main (int argc, char **argv) +int main (int argc, char **argv, char **env) { char folder[_POSIX_PATH_MAX] = ""; char *subject = NULL; @@ -519,6 +533,8 @@ int explicit_folder = 0; extern char *optarg; extern int optind; + + envlist = env; /* sanity check against stupid administrators */ diff -Pur mutt-1.5.8-base/mbox.c mutt-1.5.8-mega/mbox.c --- mutt-1.5.8-base/mbox.c Thu Feb 3 12:47:53 2005 +++ mutt-1.5.8-mega/mbox.c Thu Mar 10 17:50:20 2005 @@ -28,6 +28,10 @@ #include "sort.h" #include "copy.h" +#ifdef USE_COMPRESSED +#include "compress.h" +#endif + #include #include #include @@ -1020,6 +1024,12 @@ int mbox_close_mailbox (CONTEXT *ctx) { mx_unlock_file (ctx->path, fileno (ctx->fp), 1); + +#ifdef USE_COMPRESSED + if (ctx->compressinfo) + mutt_slow_close_compressed (ctx); +#endif + mutt_unblock_signals (); mx_fastclose_mailbox (ctx); return 0; @@ -1175,6 +1185,7 @@ mutt_set_flag (ctx, ctx->hdrs[i], M_REPLIED, old_hdrs[j]->replied); mutt_set_flag (ctx, ctx->hdrs[i], M_OLD, old_hdrs[j]->old); mutt_set_flag (ctx, ctx->hdrs[i], M_READ, old_hdrs[j]->read); + mutt_set_flag (ctx, ctx->hdrs[i], M_MDNSENT, old_hdrs[j]->mdnsent); } mutt_set_flag (ctx, ctx->hdrs[i], M_DELETE, old_hdrs[j]->deleted); mutt_set_flag (ctx, ctx->hdrs[i], M_TAG, old_hdrs[j]->tagged); diff -Pur mutt-1.5.8-base/menu.c mutt-1.5.8-mega/menu.c --- mutt-1.5.8-base/menu.c Sat Feb 12 14:01:55 2005 +++ mutt-1.5.8-mega/menu.c Thu Mar 10 18:30:43 2005 @@ -159,7 +159,7 @@ int shift = option (OPTARROWCURSOR) ? 3 : 0; int cols = COLS - shift; - mutt_format_string (s, n, cols, cols, 0, ' ', s, strlen (s), 1); + mutt_format_string (s, n, cols, cols, FMT_LEFT, ' ', s, strlen (s), 1); s[n - 1] = 0; } @@ -374,7 +374,7 @@ int c = MIN (MenuContext, menu->pagelen / 2); int old_top = menu->top; - if (menu->max <= menu->pagelen) /* less entries than lines */ + if (!option (OPTMENUMOVEOFF) && menu->max <= menu->pagelen) /* less entries than lines */ { if (menu->top != 0) { menu->top = 0; @@ -396,8 +396,8 @@ menu->top -= (menu->pagelen - c) * ((menu->top + menu->pagelen - 1 - menu->current) / (menu->pagelen - c)) - c; } - /* make entries stick to bottom */ - menu->top = MIN (menu->top, menu->max - menu->pagelen); + if (!option (OPTMENUMOVEOFF)) /* make entries stick to bottom */ + menu->top = MIN (menu->top, menu->max - menu->pagelen); menu->top = MAX (menu->top, 0); if (menu->top != old_top) @@ -433,10 +433,13 @@ { if (menu->max) { - if (menu->top + 1 < menu->max) + int c = MIN (MenuContext, menu->pagelen / 2); + + if (menu->top + 1 < menu->max - c + && (option(OPTMENUMOVEOFF) || (menu->max > menu->pagelen && menu->top < menu->max - menu->pagelen))) { menu->top++; - if (menu->current < menu->top) + if (menu->current < menu->top + c && menu->current < menu->max - 1) menu->current++; menu->redraw = REDRAW_INDEX; } @@ -451,8 +454,10 @@ { if (menu->top > 0) { + int c = MIN (MenuContext, menu->pagelen / 2); + menu->top--; - if (menu->current >= menu->top + menu->pagelen) + if (menu->current >= menu->top + menu->pagelen - c && menu->current > 1) menu->current--; menu->redraw = REDRAW_INDEX; } diff -Pur mutt-1.5.8-base/mh.c mutt-1.5.8-mega/mh.c --- mutt-1.5.8-base/mh.c Thu Feb 3 12:47:53 2005 +++ mutt-1.5.8-mega/mh.c Thu Mar 10 17:52:13 2005 @@ -69,6 +69,7 @@ #define MH_SEQ_UNSEEN (1 << 0) #define MH_SEQ_REPLIED (1 << 1) #define MH_SEQ_FLAGGED (1 << 2) +#define MH_SEQ_MDNSENT (1 << 3) static void mhs_alloc (struct mh_sequences *mhs, int i) { @@ -283,10 +284,12 @@ int unseen = 0; int flagged = 0; int replied = 0; + int mdnsent = 0; char seq_unseen[STRING]; char seq_replied[STRING]; char seq_flagged[STRING]; + char seq_mdnsent[STRING]; struct mh_sequences mhs; @@ -295,6 +298,7 @@ snprintf (seq_unseen, sizeof (seq_unseen), "%s:", NONULL (MhUnseen)); snprintf (seq_replied, sizeof (seq_replied), "%s:", NONULL (MhReplied)); snprintf (seq_flagged, sizeof (seq_flagged), "%s:", NONULL (MhFlagged)); + snprintf (seq_mdnsent, sizeof (seq_mdnsent), "%s:", NONULL (MhMdnsent)); if (mh_mkstemp (ctx, &nfp, &tmpfname) != 0) { @@ -316,13 +320,15 @@ continue; if (!mutt_strncmp (buff, seq_replied, mutt_strlen (seq_replied))) continue; + if (!mutt_strncmp (buff, seq_mdnsent, mutt_strlen (seq_mdnsent))) + continue; fprintf (nfp, "%s\n", buff); } } safe_fclose (&ofp); - /* now, update our unseen, flagged, and replied sequences */ + /* now, update our unseen, flagged, replied and mdnsent sequences */ for (l = 0; l < ctx->msgcount; l++) { if (ctx->hdrs[l]->deleted) @@ -350,6 +356,11 @@ mhs_set (&mhs, i, MH_SEQ_REPLIED); replied++; } + if (ctx->hdrs[l]->mdnsent) + { + mhs_set (&mhs, i, MH_SEQ_MDNSENT); + mdnsent++; + } } /* write out the new sequences */ @@ -359,6 +370,8 @@ mhs_write_one_sequence (nfp, &mhs, MH_SEQ_FLAGGED, NONULL (MhFlagged)); if (replied) mhs_write_one_sequence (nfp, &mhs, MH_SEQ_REPLIED, NONULL (MhReplied)); + if (mdnsent) + mhs_write_one_sequence (nfp, &mhs, MH_SEQ_MDNSENT, NONULL (MhMdnsent)); mhs_free_sequences (&mhs); @@ -467,6 +480,7 @@ md->h->read = (f & MH_SEQ_UNSEEN) ? 0 : 1; md->h->flagged = (f & MH_SEQ_FLAGGED) ? 1 : 0; md->h->replied = (f & MH_SEQ_REPLIED) ? 1 : 0; + md->h->mdnsent = (f & MH_SEQ_MDNSENT) ? 1 : 0; } } @@ -505,6 +519,7 @@ h->flagged = 0; h->read = 0; h->replied = 0; + h->mdnsent = 0; if ((p = strrchr (path, ':')) != NULL && mutt_strncmp (p + 1, "2,", 2) == 0) { @@ -533,10 +548,17 @@ break; case 'T': /* trashed */ - h->trash = 1; - h->deleted = 1; + if (!h->flagged || !option(OPTFLAGSAFE)) + { + h->trash = 1; + h->deleted = 1; + } break; + case 'N': /* MDN has already been sent */ + h->mdnsent = 1; + break; + default: *q++ = *p; break; @@ -756,10 +778,11 @@ { dprint (2, (debugfile, - "%s:%d Adding header structure. Flags: %s%s%s%s%s\n", __FILE__, + "%s:%d Adding header structure. Flags: %s%s%s%s%s%s\n", __FILE__, __LINE__, md->h->flagged ? "f" : "", md->h->deleted ? "D" : "", md->h->replied ? "r" : "", md->h->old ? "O" : "", - md->h->read ? "R" : "")); + md->h->read ? "R" : "", + md->h->mdnsent ? "N" : "")); if (ctx->msgcount == ctx->hdrmax) mx_alloc_memory (ctx); @@ -993,10 +1016,12 @@ { char tmp[LONG_STRING]; snprintf (tmp, sizeof (tmp), - "%s%s%s%s%s", + "%s%s%s%s%s%s", hdr->flagged ? "F" : "", hdr->replied ? "R" : "", - hdr->read ? "S" : "", hdr->deleted ? "T" : "", + hdr->read ? "S" : "", + hdr->deleted ? "T" : "", + hdr->mdnsent ? "N" : "", NONULL(hdr->maildir_flags)); if (hdr->maildir_flags) qsort (tmp, strlen (tmp), 1, ch_compar); @@ -1330,7 +1355,7 @@ { HEADER *h = ctx->hdrs[msgno]; - if (h->attach_del) + if (h->attach_del || h->refs_changed || h->irt_changed || h->xlabel_changed) if (mh_rewrite_message (ctx, msgno) != 0) return -1; @@ -1341,9 +1366,9 @@ { HEADER *h = ctx->hdrs[msgno]; - if (h->attach_del) + if (h->attach_del || h->refs_changed || h->irt_changed || h->xlabel_changed) { - /* when doing attachment deletion, fall back to the MH case. */ + /* when doing attachment deletion/rethreading, fall back to the MH case. */ if (mh_rewrite_message (ctx, msgno) != 0) return (-1); } @@ -1435,6 +1460,7 @@ } } else if (ctx->hdrs[i]->changed || ctx->hdrs[i]->attach_del || + ctx->hdrs[i]->xlabel_changed || (ctx->magic == M_MAILDIR && (option (OPTMAILDIRTRASH) || ctx->hdrs[i]->trash) && (ctx->hdrs[i]->deleted != ctx->hdrs[i]->trash))) @@ -1531,6 +1557,7 @@ */ mutt_set_flag (ctx, o, M_FLAG, n->flagged); mutt_set_flag (ctx, o, M_REPLIED, n->replied); + mutt_set_flag (ctx, o, M_MDNSENT, n->mdnsent); mutt_set_flag (ctx, o, M_READ, n->read); mutt_set_flag (ctx, o, M_OLD, n->old); diff -Pur mutt-1.5.8-base/mime.h mutt-1.5.8-mega/mime.h --- mutt-1.5.8-base/mime.h Wed Dec 11 05:19:40 2002 +++ mutt-1.5.8-mega/mime.h Thu Mar 10 17:50:14 2005 @@ -27,7 +27,8 @@ TYPEMODEL, TYPEMULTIPART, TYPETEXT, - TYPEVIDEO + TYPEVIDEO, + TYPEANY }; /* Content-Transfer-Encoding */ diff -Pur mutt-1.5.8-base/mutt.h mutt-1.5.8-mega/mutt.h --- mutt-1.5.8-base/mutt.h Sat Feb 12 14:01:20 2005 +++ mutt-1.5.8-mega/mutt.h Thu Mar 10 18:30:43 2005 @@ -85,6 +85,8 @@ #define CH_FROM (1<<4) /* retain the "From " message separator? */ #define CH_PREFIX (1<<5) /* use Prefix string? */ #define CH_NOSTATUS (1<<6) /* supress the status and x-status fields */ +/* this absurd location to avoid conflict with cd.edit_threads -- *sigh* */ +#define CH_UPDATE_LABEL (1<<20) /* update X-Label: from hdr->env->x_label? */ #define CH_REORDER (1<<7) /* Re-order output of headers */ #define CH_NONEWLINE (1<<8) /* don't output terminating newline */ #define CH_MIME (1<<9) /* ignore MIME fields */ @@ -94,6 +96,8 @@ #define CH_WEED_DELIVERED (1<<13) /* weed eventual Delivered-To headers */ #define CH_FORCE_FROM (1<<14) /* give CH_FROM precedence over CH_WEED? */ #define CH_NOQFROM (1<<15) /* give CH_FROM precedence over CH_WEED? */ +#define CH_UPDATE_IRT (1<<16) /* update In-Reply-To: */ +#define CH_UPDATE_REFS (1<<17) /* update References: */ /* flags for mutt_enter_string() */ #define M_ALIAS 1 /* do alias "completion" by calling up the alias-menu */ @@ -159,6 +163,11 @@ #define M_ACCOUNTHOOK (1<<9) #define M_REPLYHOOK (1<<10) #define M_SEND2HOOK (1<<11) +#ifdef USE_COMPRESSED +#define M_OPENHOOK (1<<12) +#define M_APPENDHOOK (1<<13) +#define M_CLOSEHOOK (1<<14) +#endif /* tree characters for linearize_tree and print_enriched_string */ #define M_TREE_LLCORNER 1 @@ -206,6 +215,7 @@ M_LIMIT, M_EXPIRED, M_SUPERSEDED, + M_MDNSENT, /* actions for mutt_pattern_comp/mutt_pattern_exec */ M_AND, @@ -239,6 +249,7 @@ M_CRYPT_ENCRYPT, M_PGP_KEY, M_XLABEL, + M_MIMEATTACH, /* Options for Mailcap lookup */ M_EDIT, @@ -275,6 +286,7 @@ OPT_DELETE, OPT_FORWEDIT, OPT_INCLUDE, + OPT_MARKOLD, OPT_MFUPTO, OPT_MIMEFWD, OPT_MIMEFWDREST, @@ -347,6 +359,7 @@ OPTFASTREPLY, OPTFCCATTACH, OPTFCCCLEAR, + OPTFLAGSAFE, OPTFOLLOWUPTO, OPTFORCENAME, OPTFORWDECODE, @@ -386,10 +399,12 @@ OPTMAILCAPSANITIZE, OPTMAILDIRTRASH, OPTMARKERS, - OPTMARKOLD, OPTMENUSCROLL, /* scroll menu instead of implicit next-page */ + OPTMENUMOVEOFF, /* allow menu to scroll past last entry */ OPTMETAKEY, /* interpret ALT-x as ESC-x */ OPTMETOO, + OPTMDNENABLE, /* enable the MDN support */ + OPTMDNCONFIRM, /* always require confirmation before sending an MDN */ OPTMHPURGE, OPTMIMEFORWDECODE, OPTNARROWTREE, @@ -414,6 +429,7 @@ OPTSAVEEMPTY, OPTSAVENAME, OPTSCORE, + OPTSEEOLD, OPTSIGDASHES, OPTSIGONTOP, OPTSORTRE, @@ -426,6 +442,7 @@ OPTTHREADRECEIVED, OPTTILDE, OPTUNCOLLAPSEJUMP, + OPTUNCOLLAPSENEW, OPTUSE8BITMIME, OPTUSEDOMAIN, OPTUSEFROM, @@ -445,6 +462,9 @@ OPTCRYPTUSEGPGME, + OPTATIGNORE, /* Ignore fundamental inline parts? */ + OPTATRECURSE, /* Recurse message/\* types? */ + /* PGP options */ OPTCRYPTAUTOSIGN, @@ -544,6 +564,7 @@ #define mutt_new_rx_list() safe_calloc (1, sizeof (RX_LIST)) #define mutt_new_spam_list() safe_calloc (1, sizeof (SPAM_LIST)) void mutt_free_list (LIST **); +LIST *mutt_copy_list (LIST *); void mutt_free_rx_list (RX_LIST **); void mutt_free_spam_list (SPAM_LIST **); int mutt_matches_ignore (const char *, LIST *); @@ -564,6 +585,13 @@ short num; } ALIAS; +typedef struct parameter +{ + char *attribute; + char *value; + struct parameter *next; +} PARAMETER; + typedef struct envelope { ADDRESS *return_path; @@ -574,6 +602,8 @@ ADDRESS *sender; ADDRESS *reply_to; ADDRESS *mail_followup_to; + ADDRESS *dnt; /* disposition-notification-to */ + PARAMETER *dno; /* disposition-notification-options */ char *list_post; /* this stores a mailto URL, or nothing */ char *subject; char *real_subj; /* offset of the real subject */ @@ -587,13 +617,6 @@ LIST *userhdrs; /* user defined headers */ } ENVELOPE; -typedef struct parameter -{ - char *attribute; - char *value; - struct parameter *next; -} PARAMETER; - /* Information that helps in determing the Content-* of an attachment */ typedef struct content { @@ -698,15 +721,19 @@ unsigned int expired : 1; /* already expired? */ unsigned int superseded : 1; /* got superseded? */ unsigned int replied : 1; + unsigned int mdnsent : 1; /* track whether an MDN has been sent*/ unsigned int subject_changed : 1; /* used for threading */ unsigned int threaded : 1; /* used for threading */ unsigned int display_subject : 1; /* used for threading */ + unsigned int irt_changed : 1; /* In-Reply-To changed to link/break threads */ + unsigned int refs_changed : 1; /* References changed to break thread */ unsigned int recip_valid : 1; /* is_recipient is valid */ unsigned int active : 1; /* message is not to be removed */ unsigned int trash : 1; /* message is marked as trashed on disk. * This flag is used by the maildir_trash * option. */ + unsigned int xlabel_changed : 1; /* editable - used for syncing */ /* timezone of the sender of this message */ unsigned int zhours : 5; @@ -741,6 +768,10 @@ char *tree; /* character string to print thread tree */ struct thread *thread; +#ifdef IMAP_EDIT_THREADS + ENVELOPE *new_env; /* envelope information for rethreading */ +#endif + #ifdef MIXMASTER LIST *chain; #endif @@ -787,6 +818,7 @@ short op; short not; short alladdr; + short parent; int min; int max; struct pattern_t *next; @@ -805,6 +837,7 @@ char *pattern; /* limit pattern string */ pattern_t *limit_pattern; /* compiled limit pattern */ HEADER **hdrs; + HEADER *last_tag; /* last tagged msg. used to link threads */ THREAD *tree; /* top of thread tree */ HASH *id_hash; /* hash table by msg id */ HASH *subj_hash; /* hash table by subject */ @@ -825,6 +858,11 @@ short magic; /* mailbox type */ +#ifdef USE_COMPRESSED + void *compressinfo; /* compressed mbox module private data */ + char *realpath; /* path to compressed mailbox */ +#endif /* USE_COMPRESSED */ + unsigned int locked : 1; /* is the mailbox locked? */ unsigned int changed : 1; /* mailbox has been modified */ unsigned int readonly : 1; /* don't allow changes to the mailbox */ @@ -883,6 +921,19 @@ void state_attach_puts (const char *, STATE *); void state_prefix_putc (char, STATE *); int state_printf(STATE *, const char *, ...); + +/* for attachment counter */ +typedef struct +{ + char *major; + int major_int; + char *minor; + regex_t minor_rx; +} ATTACH_MATCH; + +/* Flags for mutt_count_body_parts() */ +#define M_PARTS_MSGTRANS (1<<0) /* message/rfc822 is transparent */ +#define M_PARTS_TOPLEVEL (1<<1) /* is the top-level part */ #include "ascii.h" #include "protos.h" Only in mutt-1.5.8-base: mutt_dotlock.c diff -Pur mutt-1.5.8-base/muttlib.c mutt-1.5.8-mega/muttlib.c --- mutt-1.5.8-base/muttlib.c Sat Feb 12 13:30:16 2005 +++ mutt-1.5.8-mega/muttlib.c Thu Mar 10 17:50:20 2005 @@ -648,6 +648,9 @@ rfc822_free_address (&(*p)->bcc); rfc822_free_address (&(*p)->sender); rfc822_free_address (&(*p)->reply_to); + rfc822_free_address (&(*p)->dnt); + if ((*p)->dno) + mutt_free_parameter (&(*p)->dno); rfc822_free_address (&(*p)->mail_followup_to); FREE (&(*p)->list_post); @@ -933,7 +936,12 @@ { char prefix[SHORT_STRING], buf[LONG_STRING], *cp, *wptr = dest, ch; char ifstring[SHORT_STRING], elsestring[SHORT_STRING]; + char remainder[LONG_STRING]; size_t wlen, count, len, col, wid; + pid_t pid; + FILE *filter; + int n, dofilter = 0; + char *recycler; prefix[0] = '\0'; destlen--; /* save room for the terminal \0 */ @@ -956,7 +964,16 @@ if (*src == '?') { flags |= M_FORMAT_OPTIONAL; - src++; + ch = *(++src); /* save the character to switch on */ + cp = prefix; + ++src; + count = 0; + while (count < sizeof (prefix) && *src != '?') + { + *cp++ = *src++; + count++; + } + *cp = 0; } else { @@ -966,18 +983,18 @@ cp = prefix; count = 0; while (count < sizeof (prefix) && - (isdigit ((unsigned char) *src) || *src == '.' || *src == '-')) + (isdigit ((unsigned char) *src) || *src == '.' || *src == '-' || *src == '=')) { *cp++ = *src++; count++; } *cp = 0; - } - if (!*src) - break; /* bad format */ + if (!*src) + break; /* bad format */ - ch = *src++; /* save the character to switch on */ + ch = *src++; /* save the character to switch on */ + } if (flags & M_FORMAT_OPTIONAL) { @@ -990,6 +1007,12 @@ count = 0; while (count < sizeof (ifstring) && *src && *src != '?' && *src != '&') { + if (*src == '\\') + { + src++; + if (!*src) + break; + } *cp++ = *src++; count++; } @@ -1002,7 +1025,13 @@ count = 0; while (count < sizeof (elsestring) && *src && *src != '?') { - *cp++ = *src++; + if (*src == '\\') + { + src++; + if (!*src) + break; + } + *cp++ = *src++; count++; } *cp = 0; @@ -1058,6 +1087,46 @@ } break; /* skip rest of input */ } + /* soft fill */ + else if (ch == '*') + { + int space; + + /* truncate to fit remainder, pad with chr. */ + ch = *src++; /* pad chr */ + mutt_FormatString (remainder, sizeof(remainder), src, callback, + data, flags); + + len = mutt_strlen(remainder); + space = COLS - wlen - len; /* bytes remaining unformatted */ + + /* if space > 0, this is space that needs to be filled */ + if (space > 0) + { + memset(wptr, ch, space); + wptr += space; + wlen += space; + } + + /* if space < 0, there's not enough room for remainder -- backtrack */ + else if (space < 0) { + wptr += space; + wlen += space; + if (wlen < 0) { + wptr = dest; + wlen = 0; + } + } + + /* Since remainder is already formatted, copy it * + * in. This prevents having to format it twice. */ + if (len > COLS) + len = COLS; + memcpy(wptr, remainder, len); + wptr += len; + wlen += len; + } + else { short tolower = 0; @@ -1125,6 +1194,20 @@ wlen++; col++; } + else if (*src == '|') + { + if (*++src != '\0') + { + /* Not end of string - copy '|' */ + *wptr++ = '|'; + wlen++; + } + else + { + /* End of string - wants to be filtered */ + dofilter = 1; + } + } else { *wptr++ = *src++; @@ -1133,6 +1216,39 @@ } } *wptr = 0; + + /* Filter this string? */ + if (dofilter) + { + wptr = dest; /* reset write ptr */ + wlen = (flags & M_FORMAT_ARROWCURSOR && option (OPTARROWCURSOR)) ? 3 : 0; + if ((pid = mutt_create_filter(dest, NULL, &filter, NULL))) + { + n = fread(dest, 1, destlen /* already decremented */, filter); + fclose(filter); + dest[n] = '\0'; + if (pid != -1) + mutt_wait_filter(pid); + + /* If ends with '%', recycle through FormatString :P */ + /* To really end with '%', use "%%" */ + if (dest[--n] == '%') + { + dest[n] = '\0'; /* remove '%' */ + if (dest[--n] != '%') + { + recycler = safe_strdup(dest); + mutt_FormatString(dest, destlen++, recycler, callback, data, flags); + safe_free(&recycler); + } + } + } + else + { + /* Filter failed; erase write buffer */ + *wptr = '\0'; + } + } #if 0 if (flags & M_FORMAT_MAKEPRINT) diff -Pur mutt-1.5.8-base/mx.c mutt-1.5.8-mega/mx.c --- mutt-1.5.8-base/mx.c Thu Feb 3 12:47:53 2005 +++ mutt-1.5.8-mega/mx.c Thu Mar 10 17:50:16 2005 @@ -30,6 +30,10 @@ #include "keymap.h" #include "url.h" +#ifdef USE_COMPRESSED +#include "compress.h" +#endif + #ifdef USE_IMAP #include "imap.h" #endif @@ -454,6 +458,11 @@ return (-1); } +#ifdef USE_COMPRESSED + if (magic == 0 && mutt_can_read_compressed (path)) + return M_COMPRESSED; +#endif + return (magic); } @@ -493,6 +502,13 @@ { struct stat sb; +#ifdef USE_COMPRESSED + /* special case for appending to compressed folders - + * even if we can not open them for reading */ + if (mutt_can_append_compressed (ctx->path)) + mutt_open_append_compressed (ctx); +#endif + ctx->append = 1; #ifdef USE_IMAP @@ -654,6 +670,11 @@ ctx->magic = mx_get_magic (path); +#ifdef USE_COMPRESSED + if (ctx->magic == M_COMPRESSED) + mutt_open_read_compressed (ctx); +#endif + if(ctx->magic == 0) mutt_error (_("%s is not a mailbox."), path); @@ -759,6 +780,10 @@ mutt_free_header (&ctx->hdrs[i]); FREE (&ctx->hdrs); FREE (&ctx->v2r); +#ifdef USE_COMPRESSED + if (ctx->compressinfo) + mutt_fast_close_compressed (ctx); +#endif FREE (&ctx->path); FREE (&ctx->pattern); if (ctx->limit_pattern) @@ -816,13 +841,19 @@ if (tmp && tmp->new == 0) mutt_update_mailbox (tmp); #endif + +#ifdef USE_COMPRESSED + if (rc == 0 && ctx->compressinfo) + return mutt_sync_compressed (ctx); +#endif + return rc; } /* save changes and close mailbox */ int mx_close_mailbox (CONTEXT *ctx, int *index_hint) { - int i, move_messages = 0, purge = 1, read_msgs = 0; + int i, move_messages = 0, purge = 1, mark_old = 1, read_msgs = 0, new_msgs = 0; int check; int isSpool = 0; CONTEXT f; @@ -855,6 +886,8 @@ if (!ctx->hdrs[i]->deleted && ctx->hdrs[i]->read && !(ctx->hdrs[i]->flagged && option (OPTKEEPFLAGGED))) read_msgs++; + if (!ctx->hdrs[i]->deleted && !ctx->hdrs[i]->read && !ctx->hdrs[i]->old) + new_msgs++; } if (read_msgs && quadoption (OPT_MOVE) != M_NO) @@ -884,6 +917,14 @@ } } + if (new_msgs) + { + snprintf (buf, sizeof (buf), new_msgs == 1 + ? _("Mark new message as old?") : _("Mark new messages as old?")); + if ((mark_old = query_quadoption (OPT_MARKOLD, buf)) < 0) + return (-1); + } + /* * There is no point in asking whether or not to purge if we are * just marking messages as "trash". @@ -904,7 +945,7 @@ /* IMAP servers manage the OLD flag themselves */ if (ctx->magic != M_IMAP) #endif - if (option (OPTMARKOLD)) + if (mark_old) { for (i = 0; i < ctx->msgcount; i++) { @@ -1021,6 +1062,11 @@ !mutt_is_spool(ctx->path) && !option (OPTSAVEEMPTY)) mx_unlink_empty (ctx->path); +#ifdef USE_COMPRESSED + if (ctx->compressinfo && mutt_slow_close_compressed (ctx)) + return (-1); +#endif + mx_fastclose_mailbox (ctx); return 0; @@ -1165,6 +1211,8 @@ ctx->deleted = 0; } } + else if (ctx->last_tag && ctx->last_tag->deleted) + ctx->last_tag = NULL; /* reset last tagged msg now useless */ } /* really only for IMAP - imap_sync_mailbox results in a call to @@ -1324,6 +1372,11 @@ int mx_check_mailbox (CONTEXT *ctx, int *index_hint, int lock) { int rc; + +#ifdef USE_COMPRESSED + if (ctx->compressinfo) + return mutt_check_mailbox_compressed (ctx); +#endif if (ctx) { diff -Pur mutt-1.5.8-base/mx.h mutt-1.5.8-mega/mx.h --- mutt-1.5.8-base/mx.h Tue Aug 5 08:58:16 2003 +++ mutt-1.5.8-mega/mx.h Thu Mar 10 17:50:16 2005 @@ -40,6 +40,9 @@ #ifdef USE_POP , M_POP #endif +#ifdef USE_COMPRESSED + , M_COMPRESSED +#endif }; WHERE short DefaultMagic INITVAL (M_MBOX); diff -Pur mutt-1.5.8-base/pager.c mutt-1.5.8-mega/pager.c --- mutt-1.5.8-base/pager.c Sat Feb 12 13:30:16 2005 +++ mutt-1.5.8-mega/pager.c Thu Mar 10 17:51:40 2005 @@ -2498,6 +2498,11 @@ case OP_TAG: CHECK_MODE(IsHeader (extra)); mutt_set_flag (Context, extra->hdr, M_TAG, !extra->hdr->tagged); + + Context->last_tag = extra->hdr->tagged ? extra->hdr : + ((Context->last_tag == extra->hdr && !extra->hdr->tagged) + ? NULL : Context->last_tag); + redraw = REDRAW_STATUS | REDRAW_INDEX; if (option (OPTRESOLVE)) { @@ -2514,7 +2519,7 @@ CHECK_IMAP_ACL(IMAP_ACL_SEEN); #endif - if (extra->hdr->read || extra->hdr->old) + if (extra->hdr->read || (option(OPTSEEOLD) && extra->hdr->old)) mutt_set_flag (Context, extra->hdr, M_NEW, 1); else if (!first) mutt_set_flag (Context, extra->hdr, M_READ, 1); @@ -2595,6 +2600,18 @@ redraw = REDRAW_FULL; break; + case OP_EDIT_LABEL: + CHECK_MODE(IsHeader (extra)); + rc = mutt_label_message(extra->hdr); + if (rc > 0) { + Context->changed = 1; + redraw = REDRAW_STATUS; + mutt_message ("%d label%s changed.", rc, rc == 1 ? "" : "s"); + } + else { + mutt_message _("No labels changed."); + } + break; case OP_MAIL_KEY: if (!(WithCrypto & APPLICATION_PGP)) diff -Pur mutt-1.5.8-base/parse.c mutt-1.5.8-mega/parse.c --- mutt-1.5.8-base/parse.c Thu Feb 3 12:47:53 2005 +++ mutt-1.5.8-mega/parse.c Thu Mar 10 17:50:20 2005 @@ -300,6 +300,10 @@ return TYPEVIDEO; else if (ascii_strcasecmp ("model", s) == 0) return TYPEMODEL; + else if (ascii_strcasecmp ("*", s) == 0) + return TYPEANY; + else if (ascii_strcasecmp (".*", s) == 0) + return TYPEANY; else return TYPEOTHER; } @@ -1029,6 +1033,25 @@ hdr->date_sent = mutt_parse_date (p, hdr); matched = 1; } + else if (!ascii_strcasecmp (line + 1, "isposition-notification-to")) + { + e->dnt = rfc822_parse_adrlist (e->dnt, p); + matched = 1; + } + else if (!ascii_strcasecmp (line + 1, "isposition-notification-options")) + { + if (!e->dno) + e->dno = parse_parameters (p); + else + { + PARAMETER *tmp; + + for (tmp=e->dno; tmp->next; tmp = tmp->next) + ; + tmp->next = parse_parameters (p); + } + matched = 1; + } break; case 'e': @@ -1222,6 +1245,9 @@ case 'F': hdr->flagged = 1; break; + case 'N': + hdr->mdnsent = 1; + break; default: break; } @@ -1406,6 +1432,7 @@ rfc2047_decode_adrlist (e->to); rfc2047_decode_adrlist (e->cc); rfc2047_decode_adrlist (e->reply_to); + rfc2047_decode_adrlist (e->dnt); rfc2047_decode_adrlist (e->mail_followup_to); rfc2047_decode_adrlist (e->return_path); rfc2047_decode_adrlist (e->sender); @@ -1455,4 +1482,153 @@ p = rfc822_parse_adrlist (p, s); return p; +} + +/* Compares mime types to the ok and except lists */ +int count_body_parts_check(LIST **checklist, BODY *b, int dflt) +{ + LIST *type; + ATTACH_MATCH *a; + + /* If list is null, use default behavior. */ + if (! *checklist) + { + /*return dflt;*/ + return 0; + } + + for (type = *checklist; type; type = type->next) + { + a = (ATTACH_MATCH *)type->data; + dprint(30, (debugfile, "cbpc: %s %d/%s ?? %s/%s [%d]... ", + dflt ? "[OK] " : "[EXCL] ", + b->type, b->subtype, a->major, a->minor, a->major_int)); + if ((a->major_int == TYPEANY || a->major_int == b->type) && + !regexec(&a->minor_rx, b->subtype, 0, NULL, 0)) + { + dprint(30, (debugfile, "yes\n")); + return 1; + } + else + { + dprint(30, (debugfile, "no\n")); + } + } + + return 0; +} + +/* + * Define CBP_DEBUG to rewrite content-descs indicating why a body part + * counts or does not count. This is bad code, but it's only for debugging. + */ +#undef CBP_DEBUG +#ifdef CBP_DEBUG +# define AT_COUNT(why) { shallcount = 1; \ + bp->description = strdup("yes: " ## why); } +# define AT_NOCOUNT(why) { shallcount = 0; \ + bp->description = strdup(" no: " ## why); } +#else +# define AT_COUNT(why) { shallcount = 1; } +# define AT_NOCOUNT(why) { shallcount = 0; } +#endif + +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. */ + AT_COUNT("default"); + 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; + + /* If it's an external body pointer, don't recurse it. */ + if (!ascii_strcasecmp (bp->subtype, "external-body")) + shallrecurse = 0; + + /* Don't count containers if they're top-level. */ + if (flags & M_PARTS_TOPLEVEL) + AT_NOCOUNT("top-level message/*"); + } + else if (bp->type == TYPEMULTIPART) + { + /* Always recurse multiparts. */ + shallrecurse = 1; + + /* Don't count containers if they're top-level. */ + if (flags & M_PARTS_TOPLEVEL) + AT_NOCOUNT("top-level multipart"); + } + + /* Do not count the fundamental part if it is inlined and + * attach_ignore_fundamental is set. + */ + if (option(OPTATIGNORE) && (bp->disposition == DISPINLINE) && + bp->type != TYPEMULTIPART && bp->type != TYPEMESSAGE && bp == body) + AT_NOCOUNT("ignore fundamental inlines"); + + /* If this body isn't scheduled for enumeration already, don't bother + * profiling it further. + */ + if (shallcount) + { + /* Turn off shallcount if message type is not in ok list, + * or if it is in except list. Check is done separately for + * inlines vs. attachments. + */ + + if (bp->disposition == DISPATTACH) + { + if (!count_body_parts_check(&AttachAllow, bp, 1)) + AT_NOCOUNT("attach not allowed"); + if (count_body_parts_check(&AttachExclude, bp, 0)) + AT_NOCOUNT("attach excluded"); + } + else + { + if (!count_body_parts_check(&InlineAllow, bp, 1)) + AT_NOCOUNT("inline not allowed"); + if (count_body_parts_check(&InlineExclude, bp, 0)) + AT_NOCOUNT("excluded"); + } + } + + if (shallcount) + count++; + + dprint(30, (debugfile, "cbp: %08x shallcount = %d\n", (unsigned int)bp, shallcount)); + + if (shallrecurse) + { + dprint(30, (debugfile, "cbp: %08x pre count = %d\n", (unsigned int)bp, count)); + count += count_body_parts(bp->parts, flags & ~M_PARTS_TOPLEVEL); + dprint(30, (debugfile, "cbp: %08x post count = %d\n", (unsigned int)bp, count)); + } + } + + 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) +{ + return count_body_parts(body, flags | M_PARTS_TOPLEVEL); } diff -Pur mutt-1.5.8-base/pattern.c mutt-1.5.8-mega/pattern.c --- mutt-1.5.8-base/pattern.c Wed Feb 9 03:07:45 2005 +++ mutt-1.5.8-mega/pattern.c Thu Mar 10 17:50:14 2005 @@ -83,6 +83,7 @@ { 'U', M_UNREAD, 0, NULL }, { 'v', M_COLLAPSED, 0, NULL }, { 'V', M_CRYPT_VERIFIED, 0, NULL }, + { 'X', M_MIMEATTACH, 0, eat_range }, { 'x', M_REFERENCE, 0, eat_regexp }, { 'y', M_XLABEL, 0, eat_regexp }, { 'z', M_SIZE, 0, eat_range }, @@ -708,6 +709,7 @@ pattern_t *last = NULL; int not = 0; int alladdr = 0; + int parent = 0; int or = 0; int implicit = 1; /* used to detect logical AND operator */ struct pattern_flags *entry; @@ -728,6 +730,10 @@ ps.dptr++; alladdr = !alladdr; break; + case '%': + ps.dptr++; + parent = !parent; + break; case '!': ps.dptr++; not = !not; @@ -757,6 +763,7 @@ implicit = 0; not = 0; alladdr = 0; + parent = 0; break; case '~': if (implicit && or) @@ -773,8 +780,10 @@ tmp = new_pattern (); tmp->not = not; tmp->alladdr = alladdr; + tmp->parent = parent; not = 0; alladdr=0; + parent=0; if (last) last->next = tmp; @@ -840,8 +849,10 @@ last = tmp; tmp->not ^= not; tmp->alladdr |= alladdr; + tmp->parent |= parent; not = 0; alladdr = 0; + parent = 0; ps.dptr = p + 1; /* restore location */ break; default: @@ -955,13 +966,24 @@ mutt_pattern_exec (struct pattern_t *pat, pattern_exec_flag flags, CONTEXT *ctx, HEADER *h) { char buf[STRING]; + HEADER *cur_head; + + cur_head = h; + + if (pat->parent) + { + if (h->thread && h->thread->parent && h->thread->parent->message ) + h = h->thread->parent->message; + else + return pat->not; + } switch (pat->op) { case M_AND: - return (pat->not ^ (perform_and (pat->child, flags, ctx, h) > 0)); + return (pat->not ^ (perform_and (pat->child, flags, ctx, cur_head) > 0)); case M_OR: - return (pat->not ^ (perform_or (pat->child, flags, ctx, h) > 0)); + return (pat->not ^ (perform_or (pat->child, flags, ctx, cur_head) > 0)); case M_ALL: return (!pat->not); case M_EXPIRED: @@ -973,13 +995,14 @@ case M_TAG: return (pat->not ^ h->tagged); case M_NEW: - return (pat->not ? h->old || h->read : !(h->old || h->read)); + return (pat->not ^ !((option(OPTSEEOLD) && h->old) || h->read)); case M_UNREAD: return (pat->not ? h->read : !h->read); case M_REPLIED: return (pat->not ^ h->replied); case M_OLD: - return (pat->not ? (!h->old || h->read) : (h->old && !h->read)); + return (pat->not ? (!(option(OPTSEEOLD) && h->old) || h->read) : + ((option(OPTSEEOLD) && h->old) && !h->read)); case M_READ: return (pat->not ^ h->read); case M_DELETED: @@ -1055,6 +1078,19 @@ return (pat->not ^ (h->env->spam && h->env->spam->data && regexec (pat->rx, h->env->spam->data, 0, NULL, 0) == 0)); case M_DUPLICATED: return (pat->not ^ (h->thread && h->thread->duplicate_thread)); + case M_MIMEATTACH: + { + int i, flags = 0; + + if (option(OPTATRECURSE)) + flags |= M_PARTS_MSGTRANS; + + 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_UNREFERENCED: return (pat->not ^ (h->thread && !h->thread->child)); } diff -Pur mutt-1.5.8-base/po/POTFILES.in mutt-1.5.8-mega/po/POTFILES.in --- mutt-1.5.8-base/po/POTFILES.in Wed Mar 27 02:44:17 2002 +++ mutt-1.5.8-mega/po/POTFILES.in Thu Mar 10 17:50:16 2005 @@ -8,6 +8,7 @@ color.c commands.c compose.c +compress.c crypt.c curs_lib.c curs_main.c diff -Pur mutt-1.5.8-base/protos.h mutt-1.5.8-mega/protos.h --- mutt-1.5.8-base/protos.h Tue Feb 1 02:59:02 2005 +++ mutt-1.5.8-mega/protos.h Thu Mar 10 17:51:40 2005 @@ -165,9 +165,11 @@ void mutt_block_signals_system (void); void mutt_body_handler (BODY *, STATE *); int mutt_bounce_message (FILE *fp, HEADER *, ADDRESS *); +void mutt_break_thread (HEADER *); void mutt_buffy (char *, size_t); int mutt_buffy_list (void); 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 *); @@ -179,6 +181,7 @@ void mutt_edit_content_type (HEADER *, BODY *, FILE *); void mutt_edit_file (const char *, const char *); void mutt_edit_headers (const char *, const char *, HEADER *, char *, size_t); +int mutt_label_message (HEADER *); void mutt_curses_error (const char *, ...); void mutt_curses_message (const char *, ...); void mutt_enter_command (void); @@ -297,7 +300,8 @@ int mutt_get_postponed (CONTEXT *, HEADER *, HEADER **, char *, size_t); int mutt_get_tmp_attachment (BODY *); int mutt_index_menu (void); -int mutt_invoke_sendmail (ADDRESS *, ADDRESS *, ADDRESS *, ADDRESS *, const char *, int); +int mutt_send_message_direct (HEADER *msg, int nullrp); +int mutt_invoke_sendmail (ADDRESS *, ADDRESS *, ADDRESS *, ADDRESS *, const char *, int, int); int mutt_is_autoview (BODY *, const char *); int mutt_is_mail_list (ADDRESS *); int mutt_is_message_type(int, const char *); @@ -306,6 +310,7 @@ int mutt_is_subscribed_list (ADDRESS *); int mutt_is_text_part (BODY *); int mutt_is_valid_mailbox (const char *); +int mutt_link_threads (HEADER *, HEADER *, CONTEXT *); int mutt_lookup_mime_type (BODY *, const char *); int mutt_match_rx_list (const char *, RX_LIST *); int mutt_match_spam_list (const char *, SPAM_LIST *, char *, int); diff -Pur mutt-1.5.8-base/query.c mutt-1.5.8-mega/query.c --- mutt-1.5.8-base/query.c Thu Feb 3 12:47:53 2005 +++ mutt-1.5.8-mega/query.c Thu Mar 10 17:50:19 2005 @@ -203,7 +203,7 @@ mutt_format_string (buf2, sizeof (buf2), FirstColumn + 2, FirstColumn + 2, - 0, ' ', table[num].data->name, + FMT_LEFT, ' ', table[num].data->name, mutt_strlen (table[num].data->name), 0); snprintf (s, slen, " %c %3d %s %-*.*s %s", diff -Pur mutt-1.5.8-base/recvcmd.c mutt-1.5.8-mega/recvcmd.c --- mutt-1.5.8-base/recvcmd.c Thu Feb 3 12:47:53 2005 +++ mutt-1.5.8-mega/recvcmd.c Thu Mar 10 17:50:19 2005 @@ -182,7 +182,7 @@ if (mutt_strwidth (prompt) > COLS - extra_space) { mutt_format_string (prompt, sizeof (prompt) - 4, - 0, COLS-extra_space, 0, 0, + 0, COLS-extra_space, FMT_LEFT, 0, prompt, sizeof (prompt), 0); safe_strcat (prompt, sizeof (prompt), "...?"); } diff -Pur mutt-1.5.8-base/send.c mutt-1.5.8-mega/send.c --- mutt-1.5.8-base/send.c Thu Feb 3 12:47:53 2005 +++ mutt-1.5.8-mega/send.c Thu Mar 10 17:50:21 2005 @@ -301,7 +301,9 @@ else if (ascii_strncasecmp ("to:", uh->data, 3) != 0 && ascii_strncasecmp ("cc:", uh->data, 3) != 0 && ascii_strncasecmp ("bcc:", uh->data, 4) != 0 && - ascii_strncasecmp ("subject:", uh->data, 8) != 0) + ascii_strncasecmp ("subject:", uh->data, 8) != 0 && + !(ascii_strncasecmp ("disposition-notification-to:", + uh->data, 28) == 0 && env->dnt)) { if (last) { @@ -951,7 +953,7 @@ return (adr); } -static int send_message (HEADER *msg) +static int send_message (HEADER *msg, int nullrp) { char tempfile[_POSIX_PATH_MAX]; FILE *tempfp; @@ -991,10 +993,17 @@ #endif i = mutt_invoke_sendmail (msg->env->from, msg->env->to, msg->env->cc, - msg->env->bcc, tempfile, (msg->content->encoding == ENC8BIT)); + msg->env->bcc, tempfile, (msg->content->encoding == ENC8BIT), nullrp); return (i); } +/* Send a message as defined by MSG without any user interaction. If + NULLRP is set to true, a NULL return path (<>) will be used. */ +int mutt_send_message_direct (HEADER *msg, int nullrp) +{ + return send_message (msg, nullrp); +} + /* rfc2047 encode the content-descriptions */ static void encode_descriptions (BODY *b, short recurse) { @@ -1149,6 +1158,13 @@ } } + /* set parent, for use by % flag in send-hooks */ + if (cur && !(flags & (SENDPOSTPONED|SENDRESEND))) + { + msg->thread = safe_calloc (1, sizeof (THREAD)); + msg->thread->parent = hash_find (ctx->thread_hash, cur->env->message_id); + } + /* this is handled here so that the user can match ~f in send-hook */ if (cur && option (OPTREVNAME) && !(flags & (SENDPOSTPONED|SENDRESEND))) { @@ -1673,7 +1689,7 @@ * the send failed as well so we give the user a chance to fix the * error. */ - if (fcc_error || (i = send_message (msg)) == -1) + if (fcc_error || (i = send_message (msg, 0)) == -1) { if (!(flags & SENDBATCH)) { diff -Pur mutt-1.5.8-base/sendlib.c mutt-1.5.8-mega/sendlib.c --- mutt-1.5.8-base/sendlib.c Thu Feb 3 12:47:53 2005 +++ mutt-1.5.8-mega/sendlib.c Thu Mar 10 17:50:21 2005 @@ -1659,6 +1659,12 @@ mutt_write_address_list (env->mail_followup_to, fp, 18, 0); } + if (env->dnt && !privacy) + { + fputs ("Disposition-Notification-To: ", fp); + mutt_write_address_list (env->dnt, fp, 29, 0); + } + if (mode <= 0) { if (env->references) @@ -1989,7 +1995,8 @@ mutt_invoke_sendmail (ADDRESS *from, /* the sender */ ADDRESS *to, ADDRESS *cc, ADDRESS *bcc, /* recips */ const char *msg, /* file containing message */ - int eightbit) /* message contains 8bit chars */ + int eightbit, /* message contains 8bit chars */ + int nullrp) { char *ps = NULL, *path = NULL, *s = safe_strdup (Sendmail), *childout = NULL; char **args = NULL; @@ -2022,6 +2029,11 @@ if (eightbit && option (OPTUSE8BITMIME)) args = add_option (args, &argslen, &argsmax, "-B8BITMIME"); + if (nullrp) + { + args = add_option (args, &argslen, &argsmax, "-f"); + args = add_option (args, &argslen, &argsmax, "<>"); + } if (option (OPTENVFROM) && from && !from->next) { args = add_option (args, &argslen, &argsmax, "-f"); @@ -2170,6 +2182,7 @@ rfc2047_encode_adrlist (env->from, "From"); rfc2047_encode_adrlist (env->mail_followup_to, "Mail-Followup-To"); rfc2047_encode_adrlist (env->reply_to, "Reply-To"); + rfc2047_encode_adrlist (env->dnt, "Disposition-Notification-To"); if (env->subject) { @@ -2192,6 +2205,7 @@ rfc2047_decode_adrlist (env->cc); rfc2047_decode_adrlist (env->from); rfc2047_decode_adrlist (env->reply_to); + rfc2047_decode_adrlist (env->dnt); rfc2047_decode (&env->subject); } @@ -2238,7 +2252,7 @@ fclose (f); ret = mutt_invoke_sendmail (env_from, to, NULL, NULL, tempfile, - h->content->encoding == ENC8BIT); + (h->content->encoding == ENC8BIT), 0); } if (msg) Only in mutt-1.5.8-base: stamp-doc-rc diff -Pur mutt-1.5.8-base/status.c mutt-1.5.8-mega/status.c --- mutt-1.5.8-base/status.c Thu Feb 3 12:47:53 2005 +++ mutt-1.5.8-mega/status.c Thu Mar 10 17:50:16 2005 @@ -97,6 +97,14 @@ case 'f': snprintf (fmt, sizeof(fmt), "%%%ss", prefix); +#ifdef USE_COMPRESSED + if (Context && Context->compressinfo && Context->realpath) + { + strfcpy (tmp, Context->realpath, sizeof (tmp)); + mutt_pretty_mailbox (tmp); + } + else +#endif if (Context && Context->path) { strfcpy (tmp, Context->path, sizeof (tmp)); @@ -163,9 +171,11 @@ if (!optional) { snprintf (fmt, sizeof (fmt), "%%%sd", prefix); - snprintf (buf, buflen, fmt, Context ? Context->new : 0); + snprintf (buf, buflen, fmt, Context ? + (option(OPTSEEOLD) ? Context->new : Context->unread) : 0); } - else if (!Context || !Context->new) + else if (!Context || + !(option(OPTSEEOLD) ? Context->new : Context->unread)) optional = 0; break; @@ -173,9 +183,11 @@ if (!optional) { snprintf (fmt, sizeof (fmt), "%%%sd", prefix); - snprintf (buf, buflen, fmt, Context ? Context->unread - Context->new : 0); + snprintf (buf, buflen, fmt, (Context && option(OPTSEEOLD)) ? + Context->unread - Context->new : 0); } - else if (!Context || !(Context->unread - Context->new)) + else if (!Context || !option(OPTSEEOLD) || + !(Context->unread - Context->new)) optional = 0; break; diff -Pur mutt-1.5.8-base/thread.c mutt-1.5.8-mega/thread.c --- mutt-1.5.8-base/thread.c Thu Feb 3 12:47:53 2005 +++ mutt-1.5.8-mega/thread.c Thu Mar 10 17:50:13 2005 @@ -1145,7 +1145,7 @@ if (!cur->read && CHECK_LIMIT) { - if (cur->old) + if (option(OPTSEEOLD) && cur->old) old = 2; else new = 1; @@ -1222,7 +1222,7 @@ if (!cur->read && CHECK_LIMIT) { - if (cur->old) + if (option(OPTSEEOLD) && cur->old) old = 2; else new = 1; @@ -1343,4 +1343,106 @@ } return hash; +} + +static void clean_references (THREAD *brk, THREAD *cur) +{ + THREAD *p; + LIST *ref = NULL; + int done = 0; + + for (; cur; cur = cur->next, done = 0) + { + /* parse subthread recursively */ + clean_references (brk, cur->child); + + if (!cur->message) + break; /* skip pseudo-message */ + + /* Looking for the first bad reference according to the new threading. + * Optimal since Mutt stores the references in reverse order, and the + * first loop should match immediatly for mails respecting RFC2822. */ + for (p = brk; !done && p; p = p->parent) + for (ref = cur->message->env->references; p->message && ref; ref = ref->next) + if (!mutt_strcasecmp (ref->data, p->message->env->message_id)) + { + done = 1; + break; + } + + if (done) + { + HEADER *h = cur->message; + + /* clearing the References: header from obsolete Message-Id(s) */ + mutt_free_list (&ref->next); + +#ifdef IMAP_EDIT_THREADS + if (h->new_env) + mutt_free_list (&h->new_env->references); + else + h->new_env = mutt_new_envelope (); + + h->new_env->references = mutt_copy_list (h->env->references); +#endif + + h->refs_changed = h->changed = 1; + } + } +} + +void mutt_break_thread (HEADER *hdr) +{ + mutt_free_list (&hdr->env->in_reply_to); + mutt_free_list (&hdr->env->references); + hdr->irt_changed = hdr->refs_changed = hdr->changed = 1; + +#ifdef IMAP_EDIT_THREADS + if (hdr->new_env) + { + mutt_free_list (&hdr->new_env->in_reply_to); + mutt_free_list (&hdr->new_env->references); + } + else + hdr->new_env = mutt_new_envelope (); +#endif + + clean_references (hdr->thread, hdr->thread->child); +} + +static int link_threads (HEADER *parent, HEADER *child, CONTEXT *ctx) +{ + if (child == parent) + return 0; + + mutt_break_thread (child); + + child->env->in_reply_to = mutt_new_list (); + child->env->in_reply_to->data = safe_strdup (parent->env->message_id); + +#ifdef IMAP_EDIT_THREADS + child->new_env->in_reply_to = mutt_new_list (); + child->new_env->in_reply_to->data = safe_strdup (parent->env->message_id); +#endif + + mutt_set_flag (ctx, child, M_TAG, 0); + + child->irt_changed = child->changed = 1; + return 1; +} + +int mutt_link_threads (HEADER *cur, HEADER *last, CONTEXT *ctx) +{ + int i, changed = 0; + + if (!last) + { + for (i = 0; i < ctx->vcount; i++) + if (ctx->hdrs[Context->v2r[i]]->tagged) + changed |= link_threads (cur, ctx->hdrs[Context->v2r[i]], ctx); + } + else + changed = link_threads (cur, last, ctx); + + return changed; }