]> granicus.if.org Git - mutt/commitdiff
CVS branch clean-up.
authorThomas Roessler <roessler@does-not-exist.org>
Tue, 25 Aug 1998 22:33:07 +0000 (22:33 +0000)
committerThomas Roessler <roessler@does-not-exist.org>
Tue, 25 Aug 1998 22:33:07 +0000 (22:33 +0000)
94 files changed:
ChangeLog
Changes [deleted file]
INSTALL
Makefile.in
Muttrc.in
NEWS
OPS
README
TODO
acconfig.h
addrbook.c
alias.c
attach.c
attach.h
bind.c [deleted file]
browser.c
buffy.c
color.c
commands.c
compose.c
config.guess [new file with mode: 0755]
config.h.in
config.sub [new file with mode: 0755]
configure
configure.in
copy.c
curs_lib.c
curs_main.c
date.c
doc/Makefile.in
doc/PGP-Notes.txt
doc/dotlock.man.in [new file with mode: 0644]
doc/manual.sgml
doc/manual.txt
doc/mutt.man.in [moved from doc/mutt.man with 64% similarity]
dotlock.c [new file with mode: 0644]
dotlock.h [new file with mode: 0644]
edit.c
enter.c
from.c
functions.h
globals.h
handler.c
hash.c
hdrline.c
headers.c
help.c
history.c [new file with mode: 0644]
history.h [new file with mode: 0644]
hook.c
imap.c
imap.h
init.c
init.h
keymap.c
keymap.h
lib.c
mailbox.h
main.c
mbox.c
menu.c
mh.c
mime.h
mutt.h
mutt_menu.h
mutt_socket.h [new file with mode: 0644]
mx.c
mx.h
pager.c
pager.h
parse.c
patch.slang-1.2.2.keypad.1 [new file with mode: 0644]
pattern.c
pgp.c
pgppubring.c
pop.c
postpone.c
protos.h
query.c
reap.pl
recvattach.c
reldate.h
rfc1524.c
rfc1524.h
rfc2047.c
rfc822.c
sample.muttrc
send.c
sendlib.c
snprintf.c
socket.c [new file with mode: 0644]
sort.h
status.c
thread.c

index 2a49ca4524867a7e812400b78435990363568106..fc2c1211e8d721072fa2fe3765ff489b01b8c96d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
-Changes since 0.88
-------------------
+Mon Aug 24 09:24:28 1998  Thomas Roessler  <roessler@guug.de>
+
+       * doc/manual.txt, doc/manual.sgml: Documenting $hidden_host.
+
+       * thread.c, curs_main.c: Fix "previous-subthread"
+       in reverse-threads mode, allow next-(sub)thread
+       and previous-(sub)thread to work in limited mode.
+       (From: Liviu Daia)
+
+Sun Aug 23 10:05:41 1998  Thomas Roessler  <roessler@guug.de>
+
+       * sendlib.c, send.c, protos.h, mutt.h, main.c,
+       init.h, init.c, configure.in, configure,
+       config.h.in, alias.c, acconfig.h, INSTALL:
+       [patch-0.94.3i.tlr.hidden_host.1] Replace the
+       --enable-hidden-host configure switch by a
+       configuration variable $hidden_host which can be
+       changed at run-time. This variable will _not_
+       affect the generation of message-IDs since we'll
+       get into uniqueness problems if we just use the
+       domain here.
+
+       Needs to be documented.
+
+       * doc/manual.txt: Committing the latest manual
+       changes.
+
+       * Attic/socket.c, imap.c:
+       [patch-0.94.3.bl.imap_buffy.1-2] Fixing the
+       buffered read stuff.
+
+       * Attic/mutt_socket.h: Ups, this one was missing
+       from Brandon's IMAP patch.
+
+Sat Aug 22 14:24:18 1998  Thomas Roessler  <roessler@guug.de>
+
+       * help.c: [patch-0.94.3i.gt.beautify_help.1.gz]
+       General help beautification.  From Gero Treuner.
+
+       * doc/manual.sgml, keymap.h, keymap.c, help.c,
+       Muttrc.in: [patch-0.94.3i.gt.description.1]
+       Introduce macro descriptions.
+
+       * doc/manual.sgml, init.h, init.c, browser.c: Add
+       a negation operator "!" to $mask's syntax (as in
+       the *-hooks).  From Liviu.
+
+       * recvattach.c: Make Vikas' attach_split and
+       Brandon's other_type patches fit together.
+
+       * recvattach.c, mutt.h, init.h, globals.h,
+       compose.c: [patch-0.94.3.vikas.attach_split.3]
+       Re-introduce attach_split.
+
+       * Attic/socket.c: [patch-0.94.3.bl.imap_buffy.1]
+       Adding Brandon's IMAP buffy support.
+
+       * mx.c, mutt.h, mailbox.h, imap.h, imap.c,
+       curs_lib.c, configure.in, configure, buffy.c,
+       browser.c, Attic/BUGS:
+       [patch-0.94.3.bl.imap_buffy.1] Adding Brandon's
+       IMAP buffy support.
 
-- [patch-0.88.me.buffy_zero.1] 0 length mbox and MMDF mailboxes should never
-  be marked as having new mail in them
+Fri Aug 21 08:17:09 1998  Thomas Roessler  <roessler@guug.de>
+
+       * browser.c: Enter the file browser, type a mask
+       which doesn't match any file in the current
+       directory, clean the mask. Segfault.  Fix from
+       Liviu Daia.
+
+Thu Aug 20 22:32:46 1998  Thomas Roessler  <roessler@guug.de>
+
+       * sendlib.c, recvattach.c, parse.c, mutt.h,
+       mime.h, lib.c, handler.c, globals.h, compose.c,
+       commands.c, attach.c, Attic/BUGS:
+       [patch-0.94.3.bl.other_types.1] This patch adds
+       support for the model MIME type.  Additionally,
+       along the lines of "strict in what you generate,
+       accepting in what you receive", this patch will
+       keep the name of major mime types it doesn't
+       recognize (instead of using x-unknown).
+
+       * compose.c, Attic/BUGS:
+       [patch-0.94.3i.jmy.attachmessage-fix.1] This patch
+       fixes a bug in the allocation of space for new
+       pointers to the attachments, it would make mutt
+       seg-fault when attaching 5 or more messages at the
+       same time. (From: Jimmy Mäkelä
+       <jmy@flashback.net>)
+
+       * handler.c: [SECURITY] mutt_sanitize_filename()
+       should be called when creating temporary files for
+       autoview.  (From: Liviu Daia.)
+
+       * sendlib.c, send.c, attach.c: Try this: set
+       $mime_forward, forward a PGP-encrypted message,
+       then in the "compose" menu try to view the
+       forwarded message. If you didn't enter a
+       passphrase before, Mutt won't ask for it either.
+       (From: Liviu Daia)
+
+       * sendlib.c, attach.c: When you forward a message
+       with $mime_forward set, or when you attach a
+       message with the "attach-message" command from the
+       "compose" menu, there is a memory leak.  The real
+       reason for this leak is that multipart attachments
+       are not supported in the "compose" menu, so you
+       need to go through quite a few contortions in
+       order to handle message/rfc822 attachments.
+       Consequently, the patch below is just an ugly
+       hack.  (From: Liviu Daia)
+
+Sun Aug 16 06:22:51 1998  Thomas Roessler  <roessler@guug.de>
+
+       * rfc822.c: Bringing 128-byte strings to "STRING".
 
-- [patch-0.88.me.enter_string.1] rewrote ci_enter_string() to remove
-  duplicated redraw code, and renamed to mutt_enter_string()
+       * sendlib.c: Use add_option, not add_arg, for
+       strings such as "--".
 
-- [patch-0.88.ld.ctx_changed.1] fixed problem with setting the changed flag
-  for the mailbox when recovering from an externally modified mailbox
+       * sendlib.c: Pass an "--" argument to sendmail
+       before the address arguments, so addresses with a
+       leading dash don't lead to problems. (From Liviu.)
 
-- [patch-0.88.pk.signed.1] fixed comparison between short and unsigned short
-  in the pager
+       * sendlib.c, rfc822.c, rfc1524.c, parse.c, mx.c,
+       main.c, lib.c, keymap.c, hash.c, handler.c,
+       edit.c, curs_lib.c, alias.c: Replacing a bunch of
+       free() and malloc() calls by safe_free() and
+       safe_malloc().  (From Liviu.)
 
-- [patch-0.88.me.set_no.1] makes "unset no<var>" equivalent to "set <var>"
+Sat Aug 15 18:27:45 1998  Thomas Roessler  <roessler@guug.de>
 
-- [patch-0.88.me.state_flag] removes the OPTVERIFYSIG pseudo-option and
-  replaces it with a "flags" member in the STATE structure
+       * imap.c: read() can't read buffers larger than
+       SSIZE_MAX.
 
-- [patch-0.88.me.short] use 'int' instead of 'unsigned short' for message
-  numbers to allow mutt to read mailboxes larger than 65535 messages
+       * hook.c: [patch-0.94.3i.tlr.empty_hook.1] Ignore
+       empty hooks instead of segfaulting.
 
-- [patch-0.88.me.hold.1] removed the $hold variable.  the same functionality
-  is provided by "set nomove"
+       * protos.h, init.c, Attic/history.h:
+       [patch-0.94.3i.tlr.history.1] Adding history class
+       support.
 
-- [patch-0.88.me.buffy_notify.1] move the notification of new mail out of
-  mutt_buffy_check() into a separate routine
+       * Attic/history.c: [patch-0.94.3i.tlr.history.1]
+       Adding history class support.
 
-- [patch-0.88.me.empty_fields.1] skip processing of empty header fields in
-  _mutt_read_rfc822_header()
+       * enter.c, TODO, Makefile.in:
+       [patch-0.94.3i.tlr.history.1] Adding history class
+       support.
 
-- [patch-0.88.me.var_table.1] use the .data field instead of .bit for
-  storing the option for DT_BOOL and DT_QUAD vars
+       * sendlib.c:
+       [patch-0.94.3i.tlr.attach_msg_fmt.1-2] When
+       generating a message/rfc822 type attachment, parse
+       its header so that the attachment format routines
+       can properly display the default description.
 
-- [patch-0.88.me.rx_not.1] regexps in the *-hook commands can now optionally
-  be prefixed with a "!" (exclamation point) to indicate that the hook
-  should be executed when the target does NOT match the following pattern
+       * init.h: Change attach_format's default to limit
+       the attachment description's length.
 
-- [patch-0.88.me.sig.2] removes the $local_site, $remote_sig and $local_sig
-  variables.  the same functionality is provided by using a send-hook to set
-  the $signature variable:
-       send-hook       .               set signature=~/.sig-local
-       send-hook       !hmc\\.edu      set signature=~/.sig-remote
+Thu Aug 13 22:09:16 1998  Thomas Roessler  <roessler@guug.de>
 
-- [patch-0.88.me.from.1] honor $reverse_name even when $use_from is unset
+       * pgppubring.c: Fixing another memory leak in the
+       pubring parser.
 
-- [patch-0.88.bj.status_color.1] removed hack needed to reset the background
-  color before the buffy_notify patch
+       * recvattach.c, Attic/BUGS:
+       [patch-0.94.3i.tlr.attach_msg_fmt.1] When parsing
+       the "%d" format option in the attachment format,
+       use the message format as a fall-back if no
+       explicit description is provided.  This fixes the
+       following bug:
 
-- [patch-0.88.me.parse_param.2] whitespace after a MIME content-type
-  parameter was not stripped (eg.  "charset =us-ascii" would result in the
-  parameter "charset " in the structure)
+         set mime_forward. Forward any mesage. The
+         compose menu will show the description as
+         "Forwarded message from ...." which is fine.
+         Pressing 'd' to edit the description brings up
+         the above string for editing.
 
-Changes since 0.88.1
---------------------
+         Now hit Enter on the message/rfc822 attachment
+         to view it. Quit out of the pager.
 
-- split up mutt.h into several smaller files with groups of related data
-  in order to reduce the dependencies on mutt.h
+         The description field has now changed to the
+         Subject: of the forwarded message. Pressing 'd'
+         still brings up the 'Forwarded message from....'
+         string.
 
-- removed the $point_new variable
+       (Noted by Vikas.)
 
-- the .not member of the REGEXP struct was not initialized for the *-hook
-  commands, thus causing them not to work properly
+       * doc/manual.txt, doc/manual.sgml, sendlib.c,
+       mutt.h, init.h: [patch-0.94.3i.tlr.write_bcc.1]
+       This patch adds an option $write_bcc which
+       controls whether the Bcc header is written out or
+       not.  This can be used to work around broken MTA's
+       (Exim seems to leave Bcc headers in).
 
-- removed bogus ! handling code in the DT_RX variables
+       The problem was noted independently by Peter
+       Radcliffe <pir@pir.net> and by Dave Holland
+       <dave@zenda.demon.co.uk> (Debian Bug #25687).
 
-- [patch-0.88.ld.magic.1] fix to return type MBOX for the default magic 
-  for zero length files if $mbox_type is something other than "mbox" or 
-  "mmdf"
+       * pgppubring.c: [patch-0.94.3i.tlr.pubring_leak.1]
+       Fixing a memory leak. Bug noted by Liviu Daia.
 
-Changes since 0.88.2
---------------------
+       * reldate.h: 0.94.3i.
 
-- [patch-0.88.2.kd.buffy_pop.2] support for --enable-buffy-size and
-  --enable-pop were broken after the reorganization of mutt.h
+       * configure.in, configure, ChangeLog: Preparing
+       0.94.3i.
 
-- [patch-0.88.2.me.ignore_rx.1] removes the ignore and unignore commands and
-  replaces them with the $ignore and $unignore variables, which are regular
-  expressions used for matching lines to weed/show
+       * compose.c: indentation cosmetics.
 
-- [patch-0.88.2.me.followup.1] adds support for the Mail-Reply-To: and
-  Mail-Followup-To: header fields
+       * compose.c: Update menu->data when OP_COMPOSE_EDIT_HDRS is called.
+       From Vikas.
 
-- [patch-0.88.me.hdrline.1] fixed segfault with %t in $hdr_format if neither
-  the to: or cc: field exists
+       * compose.c: Update the encoding after using ispell from the compose
+       menu.  From Vikas.
 
-- [patch-0.88.me.abort_subject.1] print error message if
-  $abort_nosubject=yes and the user deletes the default subject and tries to
-  send instead of just silently ignoring the send
+       * sendlib.c, send.c, protos.h, pgppubring.c,
+       pattern.c, lib.c, curs_main.c, compose.c,
+       attach.c: Various nits from Liviu; encoding fixes.
 
-- [patch-0.88.me.long_re.1] increased the max length for regexp's in
-  send-hook's to be 256 chars
+       * rfc822.c: Fixing a buffer overflow in rfc822_cat().  tmplen could
+       underflow.
 
-- [patch-0.88.bj.isprint.1] treat chars >= 0xa0 as printable
+Wed Aug 12 11:50:59 1998  Thomas Roessler  <roessler@guug.de>
 
-- [patch-0.88.me.half_page.1] adds the half-up and half-down functions to
-  the index and generic key maps.  scrolls the page 1/2 screen up or down
+       * init.c: Yet another memory leak fix from Liviu.
 
-- [patch-0.88.me.useraddr.1] $alternates would not be consulted when the
-  address to be matches was not fully qualified
+       * rfc2047.c: Fixing a stupid buffer overflow plus some flawed logic.
 
-- [patch-0.88.me.from_quote.1] add support for messages separators in mbox
-  mailboxes where the mailbox part of the return-path is a quoted-string
-  eg:  From "michael elkins"@cs.hmc.edu Sat Nov 22 15:55:07 PST 1997
+       * functions.h, compose.c, OPS:
+       Adding an update-encoding function to the compose menu.
+       This is useful if the user has externally modified an
+       attachment and _wants_ to adjust the encoding afterwards.
+       Also, this patch fixes some redraw-related problems in the
+       compose menu.
 
-- [patch-0.88.me.mx.1] moved code for adding the From_ line to new messages
-  in mbox/mmdf mailboxes to mx_open_new_message(), and removes the
-  postponed_mail() func from send.c in favor of mutt_num_postponed()
+       * sendlib.c, mutt.h, compose.c, Attic/BUGS:
+       When changing or deleting attachments, the compose menu
+       now notices this and complains or asks accordingly.
+       Partially from Vikas.
 
-- [patch-0.88.2.me.post_err.1] abort exiting the compose menu if there was a
-  problem writing the message to the $postponed mailbox
+Tue Aug 11 08:14:38 1998  Thomas Roessler  <roessler@guug.de>
 
-- [patch-0.88.2.me.find_lists.1] if the to: list was missing, the cc: list
-  was not searched for mailing lists when doing a list-reply
+       * Attic/BUGS: Yet another outstanding bug.
 
-- [patch-0.88.2.me.buffy_notify.1] makes mutt keep track of the number of
-  mailboxes for which the user has not been notified of new mail so that
-  mutt_buffy_notify() can exit immediately without traversing the mailbox
-  list if there are no pending notifications
+       * doc/manual.txt: This now contains the latest changes to manual.sgml.
 
-- [patch-0.88.2.bugfix.mtsirkin.buffy_size.1] fixed some bugs with the
-  buffy_size pacth
+       * sendlib.c, rfc2047.c, rfc1524.c, pgppubring.c, pager.c, hdrline.c:
+       Fixing various nits noted by Liviu and his colleagues.
 
-Changes since 0.88.3
---------------------
+Mon Aug 10 15:30:02 1998  Thomas Roessler  <roessler@guug.de>
 
-- undid previous patch-0.88.2.me.ignore_rx.1 which changed `ignore' and
-  `unignore' to regexp vars instead of commands
+       * sendlib.c: This patches makes the message-id persistant when
+       postponing messages.  (From: Janos Farkas)
 
-- [patch-0.88.3.me.attach_file.2] with $edit_hdrs set, files can be attached
-  to the message by placing `Attach: <filename>' in the message header while
-  editing the message
+       * doc/manual.sgml, sample.muttrc, lib.c, init.h:
+       This patch introduces "unhdr_order" to reset the hdr_order
+       command's effect.  (From: Janos Farkas)
 
-- [patch-0.88.3.me.find_lists.1] fixed bug in the list-reply function
+       * color.c: Drop the free_rx parameter from muitt_free_color_line(),
+       as it's always 1.
 
-- [patch-0.88.3.me.followup.1] the mail-followup-to: field should be set for
-  all types of messages, not just group-reply
+       * color.c: Adding mutt_free_color_line() and replacing varous
+       "manual" free()s of color lines by calls to this function.
 
-- [patch-0.88.3.pk.fccdate.1] the date in fcc:'s to mbox/mmdf mailboxes was
-  incorrect
+       * bind.c: Removing bind.c.  Pointed out by Gero Treuner
+       <gero@faveve.uni-stuttgart.de>.
 
-- [patch-0.88.3.bugfix.mtsirkin.buffy_size.1] fixed some more bugs in the
-  buffy_size handling
+Sun Aug  9 18:43:45 1998  Thomas Roessler  <roessler@guug.de>
 
-- [patch-0.88.3.me.menu.1] adds the $menu_scroll which causes mutt not to do
-  an implicit next-page when doing a next-message on the last message
-  displayed on the screen, and adds the current-top, current-middle,
-  current-bottom functions to reposition the current message at the top,
-  middle and bottom of the screen, respectively
+       * color.c: With SLang, init_pair is (void), so we must not check its
+       return value.
 
-- [patch-0.88.3.me.buffy.1] avoid the double-stat() in mutt_buffy_check() by
-  saving the magic in the BUFFY struct
+       * color.c: Restructuring color.c.  This patch fixes the "default"
+       problem from 0.94.2i and makes the code more
+       comprehensible than that version and more consie than
+       0.94.1i.
 
-- [patch-0.88.3.me.buffy_config.1] the interval that mutt will check for new
-  mail in the `mailboxes' list is now configurable via the $mail_check
-  variable (default: 3 seconds)
+Sat Aug  8 21:40:12 1998  Thomas Roessler  <roessler@guug.de>
 
-- [patch-0.88.3.me.hook.1] fixed the !-handling in the *-hook commands to
-  allow specification of ! (shortcut for $spoolfile) in folder-hook by
-  placing quotes around it (eg., folder-hook '!' set signature=~/.signature)
+       * rfc2047.c: Fixing the "=?" detection in rfc2047_encode_string().  Bug
+       noted by David Jeske <jeske@home.chat.net>.
 
-Changes since 0.88.4
---------------------
+       * compose.c: If you press t to add a recipient in the compose menu,
+       then press tab, q, and aborts with ctrl-g, mutt won't
+       redraw the menu.  Noted by Jimmy Mäkelä
+       <jmy@flashback.net>.
 
-- changed default value of $move to `no'
+       * alias.c: Entering an un-parsable address when creating an alias
+       would make mutt segfault.  Noted by brian moore
+       <bem@cmc.net>.
 
-- [patch-0.88.4.me.from.1] fixed problem with duplicate From_ lines when
-  saving from mbox/mmdf mailboxes
+       * browser.c: If you press tab in the file-browser to see the inboxes
+       and the current row is greater than the inbox-screens
+       max-rows then the screen gets garbled.
+       (From: Jimmy Mäkelä <jmy@flashback.net>)
 
-- [patch-0.88.4.thread.1] modified threading algorithm such that the entire
-  mailbox does not need to be rethreaded when new mail arrives or when
-  switching among the different sorting methods
+       * doc/manual.txt, doc/manual.sgml: I made the manual more up to date:
 
-- [patch-0.88.4.de.buffy_stuff.1] removed code for testing newly created
-  mailboxes based upon the magic type
+       * new version
+       * new mailing list and home page addresses
+       * made the terminology a bit more consistent regarding
+         'pattern' and 'regular expression'
+       * added a note about expanding UNIX environments
+       * added a note about <, >, in range patterns like ~m
+       * added a note about the urlview program
+       * changed tables to not use tabs, because it doesn't work
+         right in my favourite web browsers lynx and netscape
 
-- [patch-0.884.de.buffy_new_folder.1] adds support for detecting created
-  buffy mailboxes
+       (From: Gero Treuner <gero@faveve.uni-stuttgart.de>)
 
-- [patch-0.88.4.speedup.mtsirkin.buffy_size.1] speeds up startup time with
-  the --enable-buffy-size configure option
+       * pattern.c: This patch makes pattern ranges more logical. Before '~m
+       <5' would show message 1-5, with this patch it shows 1-4.
+       Inclusive ranges is still avaible if you use '~m -5'.
+       (From: Jimmy Mäkelä <jmy@flashback.net>)
 
-Changes since 0.88.5
---------------------
+       * init.c: Various improvements to the mutt_command_complete
+       function.  From Stephen Hack <shack@rsn.hp.com>.
 
-- [patch-0.88.5.bugfix.mtsirkin.buffy_size.1] fix bug in buffy_size
+       * browser.c: If you specify 'mailboxes ""' mutt will seg-fault. (From:
+       Jimmy Mäkelä <jmy@flashback.net>)
 
-- [patch-0.88.5.de.pop_var.1] remove unneeded variable
+       * color.c: Fixing a memory leak.  Thanks, Liviu.
 
-- [patch-0.88.5.me.thread.2] fix segfault on sync
+       * commands.c: When printing a message, headers are now sorted according
+       to hdr_order.  From Liviu.
 
-- [patch-0.88.5.me.rx.1] a path may now be specified with --with-rx
+       * browser.c: Fixing an off-by-one buffer overflow in browser.c.  Noted
+       by Liviu.
 
-- [patch-0.88.5.de.aliasnull.1] fixed segfault when creating an alias while
-  in limited view
+       * lib.c, attach.c: This patch adds some more "safe" characters to
+       mutt_sanitize_filename and fixes its usage in
+       mutt_view_attachment().  (From: Liviu Daia
+       <daia@stoilow.imar.ro>)
 
-- [patch-0.88.5.me.hook.1] fixed a bug which caused *-hook's with the same
-  regexp to be ignored
+       * status.c, sort.h, sendlib.c, send.c, query.c, protos.h, postpone.c, pager.h, pager.c, mutt_menu.h, menu.c, main.c, init.c, headers.c, functions.h, curs_main.c, curs_lib.c, compose.c, commands.c, browser.c, addrbook.c, OPS:
+       Adding the attach message patch.  From Vikas Agnihotri
+       <VikasA@att.com>.
 
-- [patch-0.88.5.me.followup.1] the Mail-Followup-To: field was not rfc2047
-  encoded
+       * Makefile.in: There is no "compile" rule for dotlock in the Makefile.
+       (From: Dan Nelson <dnelson@emsphone.com>)
 
-- [patch-0.88.5.me.menu.2] fixed some miscellaneous redraw problems related
-  to the menu movement commands
+       * imap.c: Thispatch to imap.c allows the user to specify a port
+       number in the folder name in the general form
+       {hostname:portnum}foldername. (From: Andy Sloane
+       <andude@guildsoftware.com>)
 
-- [patch-0.88.4.me.str_sub.2] moves handling of backquotes (``) in muttrc
-  commands to mutt_extract_token() so that they are only evaluated in
-  appropriate places
+       * imap.c: imap_close_connection() was being called even though the
+       client was using mulitple mailboxes over the same
+       connection.  (From: Brandon Long <blong@fiction.net>)
 
-- [patch-0.88.5.me.generic_menu.2] created the `generic' keymap which the
-  other menus (except for pager and editor) default to if a key is not found
-  in the menu specific keymap
 
-- [patch-0.88.5.nit.mtsirkin.buffy_time.1] disable the utime() call when
-  BUFFY_SIZE is enabled
+Fri Jul 31 08:17:50 1998  Thomas Roessler  <roessler@guug.de>
 
-- [patch-0.88.5.me.mx_cleanup.1] separates append code out of
-  mx_open_mailbox() into mx_open_mailbox_append() for better code
-  readability.
+       * rfc1524.c: Changing an sprintf to an snprintf (which it was meant to
+       be.)
 
-- [patch-0.88.5.me.pattern.2] rewrite of searching/limiting code to
-  pre-compile the search pattern
+       * protos.h: mutt_sanitize_filename takes char *, not const char *.
 
-Changes since 0.88.6
---------------------
+       * protos.h, lib.c, attach.c:
+       Introducing mutt_sanitize_filename().  The code is similar
+       to patch-0.91.1i.tlr.rfc1524_sanitize.1 and to Peter
+       Holzer's patch against 0.91.
 
-- [patch-0.88.6.bigfix.init.mtsirkin.1] fixed variable type problem
+       * rfc1524.h, rfc1524.c, postpone.c, attach.c:
+       Avoid possible buffer overflows in mutt_adv_mktemp().
 
-- [patch-0.88.6.jf.followup.1] fix off by 1 error in parsing of the
-  mail-followup-to: field
+       * sendlib.c: Interpret sysexits-style exit values from sendmail.
 
-- [patch-0.88.6.me.backtic.2] backtics were not handled in the alias and
-  my_hdr commands
+       * configure.in, configure, config.h.in, acconfig.h:
+       Check for sysexits.h.
 
-- [patch-0.88.6.me.bindings.1] added missing J and K bindings for the index
-  menu
+Thu Jul 30 09:30:38 1998  Thomas Roessler  <roessler@guug.de>
 
-- [patch-0.88.6.me.pattern.2] fixed bugs in the search pattern compiler
+       * edit.c: When reading in files, be_snarf_file() wouldn't recognize
+       '~' as the user's home directory.
 
-- [patch-0.88.6.de.sortbug.1] fixed coredump when resorting when new mail
-  arrives in an empty box
+Wed Jul 29 10:54:09 1998  Thomas Roessler  <roessler@guug.de>
 
-- [patch-0.88.6.de.in_reply_to.1] increased length of buffer used to store
-  the message-id from the in-reply-to: header field
+       * README, Changes: Finalizing 0.93.2i.
 
-- [patch-0.88.6.bl.doc_nits.1] updated docs on the alias expansion
+       * configure.in, configure: Bumping to 0.93.2(i).
 
-- [patch-0.88.6.de.remove_search_body.1] removes the search-body function
-  from the index menu now that the same feature is supported with the
-  rewritten search functions
+       * parse.c: Fixing a buffer overflow in parse.c which presented a
+       serious security thread.  Noted by Paul Boehm
+       <paul@boehm.org>.
 
-- [patch-0.88.6.de.search-body-doc.1] removes documentation references for
-  the search-body command
+Tue Jul 28 08:21:49 1998  Thomas Roessler  <roessler@guug.de>
 
-- [patch-0.88.6.nit.pattern.mtsirkin.1] fixed compiler warning about const
-  being ignored
+       * Attic/patch.slang-1.2.2.keypad.1: Adding a patch for a SLang bug.
 
-- [patch-0.88.6.me.help_unbound.1] unbound functions are now displayed in
-  the help menus
+       * INSTALL: Adding a patch for a SLang bug.
 
-- [patch-0.88.6.me.received.1] if no From_ line is found, parse the first
-  Received: header field to get the local delivery date instead of using the
-  file modification time
+       * mx.c: Doing 'mutt -f NoSuchFile' just flickers the screen and
+       silently exits. Earlier (0.92.14 at least), it used to
+       spit out the error 'NoSuchFile: no such file or directory
+       (errno = 2)'.  (Noted and tracked down by Vikas Agnihotri
+       <VikasA@att.com>)
 
-- [patch-0.88.6.kd.half_up.1] fixed bug in half-up function
+       * color.c: The index cache should be updated even without color
+       support.
 
-- fixed the eat_regexp() function to use _mutt_extract_token() so that
-  things like \n and \t get expanded
+Mon Jul 27 13:39:39 1998  Thomas Roessler  <roessler@guug.de>
 
-- extended _mutt_extract_token() to be able to be used in eat_regexp()
-  by adding the option not to reap quotes, and to recognize the logic
-  operators for the pattern matching
+       * Attic/BUGS: Adding a notice about some more nits.
 
-Changes since 0.88.7
---------------------
+       * main.c: Change the error reporting mail address from
+       <mutt-dev@cs.hmc.edu> to <mutt-dev@mutt.org>.
 
-- changed handling of \ to not be interpreted inside of single quotes
+       * protos.h, init.h, color.c:
+       This patch fixes index "color" patterns when using a
+       non-color capable curses library.  While working on color
+       support, I've thrown together the mutt_parse_color() and
+       mutt_parse_mono() functions as they are sharing most of
+       their code.  Additionally, a new directive called "unmono"
+       is introduced.  The implementation consists in adding a
+       flag and very few lines of code (plus ifdefs) to
+       mutt_parse_uncolor().
 
-- runs of quotes in muttrc commands are now supported, so that
-  the following are equivalent:
-       michael\ elkins
-       michael' 'elkins
-       "michael"' 'elkins
+       * snprintf.c, rfc1524.h, rfc1524.c, date.c:
+       Fixing some minor nits: missing #includes in date.c and
+       snprintf.c, and a not-so-nice declaration of
+       rfc1524_new_entry().  Noted by Digital cc and gcc.
 
-- fixed backtic handling so that the output is considered as separate tokens
-  unless, so that you may do:  mailboxes `echo ~/Mail/Lists/*`
+Fri Jul 24 08:12:46 1998  Thomas Roessler  <roessler@guug.de>
 
-- "ignore from_" is no longer supported, you should use
-       ignore "From "
+       * copy.c, attach.c:
+       Fiddling around with message/rfc822 attachments once again.
 
-- created new menu function menu_check_recenter() in menu.c which is
-  responsible for checking if the current message has moved off the current
-  displayed range and recenters if needed
+Thu Jul 23 20:57:50 1998  Thomas Roessler  <roessler@guug.de>
 
-- removed support for old-style Mutt postponed mailboxes which used the
-  X-Mutt-Attachment: header field
+       * status.c, sendlib.c, send.c, rfc2047.c, pop.c, pager.c, mx.c, mh.c, mbox.c, lib.c, init.c, imap.c, edit.c, curs_lib.c, compose.c, commands.c, color.c, browser.c, attach.c, alias.c:
+       Guard lots of global (char *) variable deferences against
+       NULL pointers.
 
-- [patch-0.88.7.me.alias.1] fix segfault on recursive aliases
+       * copy.c, attach.c:
+       Yet another patch about saving message/rfc822 attachments.
 
-- [patch-0.88.7.me.attach_desc.1] allow optional specification of the
-  attachment description after the filename in the 'Attach:' header field
-  with $edit_hdrs
+       * main.c, send.c: Fixing potential NULL pointer deferences.
 
-- [patch-0.88.7.me.help.1] fixed display of unbound functions in help to
-  crossref between the generic and menu specific keymaps so that functions
-  which are bound do not show up as unbound
+Wed Jul 22 22:47:57 1998  Thomas Roessler  <roessler@guug.de>
 
-- [patch-0.88.7.me.pager_search.1] regexps should be compiled with
-  REG_NEWLINE
+       * recvattach.c: Another fix from Liviu.
 
-- [patch-0.88.7.me.rx.1] use macro REGCOMP() instead of directly calling
-  regcomp()
+       * recvattach.c, from.c, attach.c:
+       Another patch from liviu to fix the message/rfc822
+       behaviour.
 
-- [patch-0.88.7.me.parse.1] received: parsing did not work, and copying a
-  message to =postponed and recalling it resulted in some duplicate fields
-  in the header
+       * recvattach.c, mx.c, attach.c:
+       This patch fixes the saving of message/rfc822 attachments
+       to mail folders.  Additionally, it fixes an outstanding
+       bug with From_ lines being written to MH folders.
 
-- [patch-0.88.6.kd.help_length.1] shortened descriptions of several help
-  strings
+       (From: Liviu Daia <daia@stoilow.imar.ro>)
 
-- [patch-0.88.7.de.pattern.1] fixed off by one errors in selecting ranges of
-  messages
+       * menu.c, functions.h, browser.c, OPS:
+       1. When I hit 'c' (change dir) in browser, it gives me the
+          directory, but without the final '/', so I have to add
+          '/' to add a subdirectory name. This patch fixes it.
 
-- [patch-0.88.7.kd.half_down.1] fixed half-down op to mimic the next-page op
-  where if there is no next page, the pointer is moved to the last entry in
-  the menu instead of printing an error
+       2. check-new now will recheck mailbox folders for new
+          mail.
 
-- added a sleep() call after the info about the state of the mailbox after a
-  sync operation so that the user has time to read it before the message
-  about sorting pops up
+       3. added a function toggle-mailboxes which toggles in
+          browser between mailboxes view and directory view.
+          (bound to TAB by default).
 
-Changes since 0.88.8
---------------------
+       (From: "Michael S. Tsirkin" <mtsirkin@iil.intel.com>)
 
-- [patch-0.88.8.me.no_url.1, patch-0.88.8.no_url.1-2] the url menu and all
-  referecnes to it has been removed.  equivalent functionality can be
-  obtained by using the external program
-  ftp://ftp.cs.hmc.edu/pub/me/urlview-0.3.tar.gz and the following macro:
-       macro index \cb |urlview\n
+       * send.c: Correct an error message in send.c.
+       (From: Byrial Jensen <byrial@post3.tele.dk>)
 
-- [patch-0.88.8.me.refresh.1] patch to avoid calls to refresh() in the
-  middle of executing macros
+       * sendlib.c, recvattach.c, protos.h, postpone.c,
+       pager.c, mx.c, mutt.h, lib.c, keymap.c, handler.c,
+       compose.c, commands.c, attach.h, attach.c:
 
-- [patch-0.88.8.me.nested_quote.1] fixed problem with nested quotes in
-  muttrc commands
+       These changes fix some of the bugs which were
+       recently reported to mutt-dev.  To be more specific,
+       message-type attachments are saved to mail folders
+       from the receive attachment menu, some of the
+       sending code has been made more robust against
+       disappearing attachments, and "tag" is rebound to
+       "T" on the compose menu.
 
-- [patch-0.88.8.me.tag_thread.1] adds the tag-thread (ESC-t) function
+       (Some part of this patch comes from Vikas Agnihotri
+       <VikasA@att.com>.)
 
-- [patch-0.88.me.reply_self.1] change handling of $metoo so that it will
-  leave the user's address on the to: line if it is the only address in the
-  list
+       * send.c: Avoid a potential segmentation fault when
+       trying to postpone, but Postponed equals NULL.
 
-- [patch-0.88.me.decode_copy.1] removes the $forw_decode, $decode_format
-  variables, the decode-save and decode-copy functions, and rewrite of the
-  attachment handling functions to be much simpler
+       * Attic/BUGS: This file is intended to contain known
+       bugs which still have to be fixed.
 
-- [patch-0.88.8.me.thread.1] fixed segfault on thread resort when new mail
-  arrives is a message in the mailbox has no message-id: field
+       * doc/manual.txt:
+       Committing the changes previously made to manual.sgml.
 
-- mutt would dump core if given a bad date for the ~d search pattern
+       * imap.c: Include Message-ID and Reply-To headers
+       when fetching a message's headers from an IMAP
+       server. (From: Andy Sloane <andude@incarnate.net>)
 
-- [patch-0.88.8i.de.fast_forward.1] skip prompt for subject when forwarding
-  if $fast_reply is set
+Tue Jul 21 07:54:03 1998  Thomas Roessler  <roessler@guug.de>
 
-- fixed compilation error on systems without support for color related to
-  the color quoting support (SunOS 4.1.x)
+       * recvattach.c:
+       The old behaviour of the %d (for description) specifier is
+       recreated by this patch.
+       (From: Byrial Jensen <byrial@post3.tele.dk>)
 
-- [patch-0.88.8-bugfix.buffy_size.mtsirkin.2] fixed a bug in buffy_size
-  support
+       * protos.h, lib.c, attach.c:
+       You should never _ever_ do something like this:
+
+              [process A]  ---[piped write until EOF]---> [process B]
+              [process A]  <---[piped read until EOF]--- [process B]
 
-- [patch-0.88.8.kd.help_length.1] fix to truncate macro descriptions in the
-  help menu at the screen edge, and updated docs with new short function
-  descriptions
+       Basically, what happens is something like this: A
+       feeds data to B; B processes the data, and feeds it
+       to the pipe until the pipe buffer is full; at this
+       point, A writes to its pipe until its buffer is full
+       too, and if it still has more data to write, that's
+       it, it never gets to the read part to flush B's
+       buffer --- both processes are blocked on write.
 
-- increased size of buffer used to store regepxs for the *-hook commands
-  from SHORT_STRING to STRING
+       This patch fixes such a situation in the compose menu.
 
-Changes since 0.88.9
---------------------
+       (From: Liviu Daia <daia@stoilow.imar.ro>)
 
-- [patch-0.88.8-bugfix.buffy_size.mtsirkin.1] missed patch from previous
-  buffy_size fix
+Mon Jul 20 21:01:05 1998  Thomas Roessler  <roessler@guug.de>
+
+       * reap.pl: Perl lies in /usr/bin on my machines.
 
-- [patch-0.89.9.bl.fcc_fix.1] body of message was not written out for fcc
-  and postponement
+       * pop.c: It seems that if you don't enter any
+       password at all when prompted for the POP password,
+       Mutt will die with a segmentation fault also. (Bug
+       reported by Steve Mayer <smayer@rtd.com> via the
+       Debian bug tracking system, fix from Thomas
+       Roessler.)
+
+       * postpone.c: When you send a message which have
+       been postponed before sending, then all its
+       attachments (if there are more than one) will have a
+       content-disposition header which includes a
+       filename, even if there isn't a real filename but
+       only random choosen temporary one. (From: Byrial
+       Jensen <byrial@post3.tele.dk>)
+
+Sat Jul 18 09:18:31 1998  Thomas Roessler  <roessler@guug.de>
+
+       * recvattach.c: "Set mime_forward, and forward a
+       message --- Mutt will segfault." The obvious fix for
+       this is to check for aptr->content->hdr in
+       mutt_attach_fmt() before invoking
+       _mutt_make_string().  Anyway, I suspect that the
+       real fix may involve something like parsing the
+       rfc822 attachment in question.
+
+       * sendlib.c: Postponing messages behaves funny when the $postponed
+       folder is in Maildir format; I traced this down to the
+       fact that postponed messages are saved in "cur" while
+       mutt_num_postponed() is looking at "new".
+       (From: Liviu Daia <daia@stoilow.imar.ro>)
+
+Fri Jul 17 08:37:02 1998  Thomas Roessler  <roessler@guug.de>
+
+       * compose.c: Removing the old snd_entry() code.
+
+       * doc/manual.sgml, protos.h, pgp.c, mutt.h, init.h, hook.c:
+       When sending encrypted messages, it may arrive that Mutt
+       can't determine the PGP key of the recipient (presumably
+       because her address has changed, but she hasn't updated
+       her PGP key yet). In this situation it's convenient to be
+       able to associate a keyID with an address automatically.
+       The attached patch is an attempt to implement this idea
+       using a "pgp-hook". (From: Liviu Daia <daia@stoilow.imar.ro>).
+
+       * recvattach.c: Removing the old attach_entry() code.
+
+       * recvattach.c, protos.h, mutt.h, init.h, globals.h, compose.c:
+       This patch adds a string variable $attach_format which
+       controls the look of the compose and attach menus.
+       Unfortunately, I was not able to make things so that it
+       would look exactly the same as the hardcoded versions, so
+       the default format is a bit different, but I think it is
+       quite usable.  (From Michael Elkins <me@cs.hmc.edu>).
+
+       * functions.h, browser.c, OPS:
+       This patch allows you to view files from the browser
+       window, useful if you are searching for a file to attach
+       to your message. It uses the standard mailcap stuff (and
+       the lookup mime types) to use the correct "viewer" for the
+       file.  (From Brandon Long <blong@fiction.net>)
+
+       * doc/Attic/dotlock.man.in, doc/Makefile.in, configure.in, configure, Makefile.in:
+       Dotlock-related changes: We call it mutt.dotlock to avoid
+       conflicts with certain NFS versions' dotlocking utilities
+       (pointed out by Liviu Daia).  Additionally, we need to
+       compile it as an external utility on systems which don't
+       have an fchdir(2) system call.
+
+Thu Jul 16 16:39:53 1998  Thomas Roessler  <roessler@guug.de>
+
+       * mx.c: Fixing a small typographic error.
+
+       * mx.c: Mutt doesn't retry locking if it doesn't succeed at once.
+       The code in mx_lock_file is supposed to retry but it
+       doesn't work because of a mistake in operator precedence.
+       (From: Petri Kaukasoina <kaukasoi@elektroni.ee.tut.fi>)
 
-- [patch-0.88.9i.me.copy.1] created unified functions to copying/appending
-  messages.  adds $forw_decode, $forw_quote, decode-save and decode-copy
+       * Attic/dotlock.c:
+       The dotlock.c file tries to include <posix1_lim.h> if
+       _POSIX_PATH_MAX isn't defined but it doesn't include
+       <limits.h>, where this symbol should be defined.  (From
+       Marc.Baudoin@solsoft.com)
 
-- [patch-0.88.9.me.refresh.1] use mutt_refresh() instead of refresh() in
-  mutt_enter_string()
+       * send.c: When several messages are tagged and the user applies
+       reply, group-reply, or list-reply to these messages, the
+       reply's references and in-reply-to headers are constructed
+       from the tagged message which comes last in the current
+       index.  This patch constructs the references header from
+       _all_ messages' message-id and references headers. (tlr)
 
-- with $edit_hdrs, if you delete the in-reply-to: field Mutt will
-  automatically remove the References: field as well
+       * reldate.h, configure.in, configure, Changes, ChangeLog:
+       Preparing mutt 0.94.
 
-- mutt_query_exit() should call timeout(-1) so the prompt doesn't abort.
+       * imap.c: "My two remaining issues are the speed at which it
+       downloads the headers, and support of PREAUTH. I'm
+       enclosing a patch (to stock mutt-0.92.13i) which addresses
+       these issues." (From Brian Marcotte
+       <marcotte@panix7.panix.com>)
 
-- [patch-0.88.9.me.fcc.1] removed the fcc-hook command
+       * color.c: This patch fixes two problems reported on mutt-users.
 
-- the return value of mutt_send_message() was not checked so if sending mail
-  failed for some reason (like a full $tmpdir or error invoking $sendmail),
-  Mutt would incorrectly report that the mail had been sent
+       (1) the error message about "default colors not supported"
+       when not using a color xterm should not be printed.  The
+       existing code did not check the value of has_colors() in
+       conjunction with use_default_colors()
 
-- [patch-0.88.9.me.pseudo_thread.1] fixed problem with rethreading messages
-  with no real reference when new mail arrives
+       (2) mutt would crash when sending mail in batch mode
+       because use_default_colors() could be used without doing
+       an initscr()
 
-- [patch-0.88.9i.kd.first_entry.1] fixed segfault on first-entry function if
-  there are no entries in the menu
+       (From Michael Elkins.)
 
-- added a section to the doc describing the features of $edit_hdrs (fcc:,
-  attach: and references-magic)
+Wed Jul 15 17:15:46 1998  Thomas Roessler  <roessler@guug.de>
 
-- [patch-0.88.bj.browser.1] fixed some problems with the file browser
+       * mx.h, mx.c, main.c, Attic/dotlock.h,
+       Attic/dotlock.c, configure.in, configure,
+       Makefile.in: Finalizing the external dotlock
+       support: If group mail privileges are needed, the
+       dotlock is compiled as a separate program.  If
+       there is no need for privileges, it remains a
+       module which is compiled into mutt. Also, there is
+       no more need for the SLang buffer overflow
+       work-around in main().  We drop it, but let mutt
+       bail out instead if it's installed setgid
+       something.
 
-Changes since 0.88.10
----------------------
+       * doc/Attic/dotlock.man.in, Attic/dotlock.c:
+       Fix the race condition in dotlock.c.
 
-- return is now bound to `tag-entry' for the alias menu
+       * doc/Attic/mutt.man.in:
+       Putting the manual page under autoconf control.
 
-- configure --with-homespool is now equivalent to --with-homespool=mailbox
+       * doc/Attic/mutt.man.in:
+       file mutt.man.in was initially added on branch mutt-0-94.
 
-- [patch-0.88.10.me.invoke_sendmail.1] remove check for return value of
-  invoke_sendmail() since mutt_system() always returns -1 on some systems
+       * doc/mutt.man: Putting the manual page under autoconf control.
 
-- [patch-0.88.10.me.push_refresh.1] fixed bug with mailbox parsing status
-  not being displayed if the user has a `push' command in their muttrc or in
-  a folder-hook
+       * doc/Attic/dotlock.man.in:
+       Adding external dotlocking.  For bugs, see the manual page
+       and the comments in dotlock.c.
 
-- [patch-0.88.10.de.thread-commands.1] cleans up the subthread operations
+       * doc/Attic/dotlock.man.in:
+       file dotlock.man.in was initially added on branch mutt-0-94.
 
-- [patch-0.88.10i.de.sort_case.1] sorting by subject/author should be case
-  insensitive
+       * doc/Makefile.in, protos.h, mx.c, mbox.c, main.c, globals.h, Attic/dotlock.h:
+       Adding external dotlocking.  For bugs, see the manual page
+       and the comments in dotlock.c.
 
-- [patch-0.88.10.me.pipe_attach.2] piping attachments did not work
+       * Attic/dotlock.h:
+       file dotlock.h was initially added on branch mutt-0-94.
 
-- [patch-0.88.10.kd.doc_nit.1] fixed doc bug wrt $forw_quote
+       * Attic/dotlock.c:
+       Adding external dotlocking.  For bugs, see the manual page
+       and the comments in dotlock.c.
 
-- manual.html readded to the `all' target in doc/makefile
+       * Attic/dotlock.c:
+       file dotlock.c was initially added on branch mutt-0-94.
 
-Changes since 0.88.11
----------------------
+       * configure.in, configure, Makefile.in:
+       Adding external dotlocking.  For bugs, see the manual page
+       and the comments in dotlock.c.
 
-- changed default binding of pipe-entry to `|' in the compose menu
+       * doc/mutt.man: More roff fixes.
 
-- changed default binding of filter-entry to `F' in the compose menu
+       * doc/mutt.man: More groff fixes.
 
-- auto_view was not used when decoding messages with $pipe_decode set
+Tue Jul 14 16:01:07 1998  Thomas Roessler  <roessler@guug.de>
 
-- piping messages did not use the new mutt_copy_message() function
+       * reldate.h, configure.in, configure, Changes, ChangeLog:
+       Preparing mutt 0.93.1i.
 
-- use AC_REPLACE_FUNCS for check of strcasecmp() instead of AC_CHECK_FUNCS
+       * rfc2047.c, mime.h, handler.c: More unsigned fixes.
 
-- [patch-0.88.11.me.copy_header.1] fixed problem when message header is
-  terminated by CRLF instead of just LF
+       * pattern.c, parse.c:
+       Changing (int) casts in is* arguments to (unsigned char).
 
-- [patch-0.88.11.de.reverse_name.1] $reverse_name should override a default
-  `my_hdr' command
+       * rfc2047.c: Removing a superfluous (unsigned char) cast in an IsPrint
+       argument.
 
-Changes since 0.88.12
----------------------
+Mon Jul 13 10:50:39 1998  Thomas Roessler  <roessler@guug.de>
 
-- [patch-0.88.12.me.broswer.1] fixed bug in status line for generic menu
-  code, and added entry numbers so that `jump' can be used effectively in
-  the file browser
+       * doc/mutt.sgml, doc/mutt.man, doc/Makefile.in:
+       Since manual page generation seems to be broken in the
+       SGML-tools package, we remove the SGML version of mutt.man
+       and make the troff source the master copy.  Suggested by
+       Roland Rosenfeld <roland@luv.rhein.de> who also provided
+       the corrected mutt.man file.
 
-- [patch-0.88.12.me.attach_reply.1] fixed segfault when replying to a single
-  message/rfc822 attachment
+Sun Jul 12 13:15:31 1998  Thomas Roessler  <roessler@guug.de>
 
-- [patch-0.88.12.kd.alias_redraw.1] fixed redraw bug when exiting the alias
-  menu
+       * protos.h: Replace calloc by safe_calloc in new_pattern.
 
-- [patch-0.88.12.kd.help_wrap.2] fixed display of long macros in the help
-  display
+Sat Jul 11 05:10:29 1998  Thomas Roessler  <roessler@guug.de>
 
-- [patch-0.88.12.kd.resort.1] cause a resort on ':set sort=xxx'
+       * doc/manual.txt, doc/manual.sgml: Key bindings documentation.
 
-- fixed bug where it was impossible to search for strings with any of
-  !, ~ or | in them
+Fri Jul 10 17:58:26 1998  Thomas Roessler  <roessler@guug.de>
 
-- removed prototype for mutt_new_address() in rfc822.h since it is a macro
+       * NEWS: s/fwd_decode/forward_decode/ (Noted by Lars Hecking)
 
-- added doc blurb for $forw_decode
+       * pop.c: tmp[] wasn't initialized when asking for the POP password.
 
-- optimized loop for marking messages as `old' by checking if OPTMARKOLD is
-  set before entering the loop
+       * buffy.c: On SunOS 4.1, one must include unistd.h in order to
+       declare SEEK_END.  (Fabrice Noilhan)
 
-- $timeout should only affect the first keystroke of a multi-key command in
-  the `index' menu
+       * mutt.h: include <posix1_lim.h> if limits.h doesn't defile
+       _POSIX_PATH_MAX.
 
-Changes since 0.88.13
----------------------
+       * Changes, ChangeLog: *** empty log message ***
 
-- [patch-0.88.13.me.date.1] fixed problems with the date (~d) pattern
-  matching code
+       * doc/PGP-Notes.txt: Adding a notice about core dumps.
 
-- [patch-0.88.13.me.send.2] fixed some deficiencies in replying to tagged
-  messages
+       * reldate.h, README, INSTALL: Preparing 0.93i.
 
-- fixed segfault when downloading POP3 mail
+       * handler.c: Fix text/enriched decoding: if there's a tag mismatch in
+       the last paragraph in the attachment, the whole paragraph
+       wouldn't be displayed.
 
-- [patch-0.88.13.me.cache.1] fixed problem with search cache when status
-  flags on messages change
+Thu Jul  9 19:51:36 1998  Thomas Roessler  <roessler@guug.de>
 
-- [patch-0.88.13.me.fcc_hook.1] restored the fcc-hook command
+       * configure.in, configure, Attic/config.sub:
+       Use CC -Ae -D_HPUX_SOURCE on HP/UX.
 
+       * Attic/config.sub:
+       file config.sub was initially added on branch mutt-0-93.
 
-PGP related changes since 0.88.13i
-----------------------------------
+       * Attic/config.guess: Use CC -Ae -D_HPUX_SOURCE on HP/UX.
 
-- [patch-0.88.13i.tlr.pgp3_fingerprint.1] Code clean-up
-  with respect to PGP version 3 fingerprints.
+       * Attic/config.guess:
+       file config.guess was initially added on branch mutt-0-93.
 
-- [patch-0.88.13i.tlr.pgp_invoke.1] New PGP invocation
-  code which enables PGP 5 to check signatures and will
-  make the integration of other PGP implementations with
-  mutt easier.
+       * INSTALL: Use CC -Ae -D_HPUX_SOURCE on HP/UX.
 
-Changes since 0.88.15
----------------------
+Wed Jul  8 21:59:43 1998  Thomas Roessler  <roessler@guug.de>
 
-- [patch-0.88.14i.ds.flagdoc.1] fixed the description of the flags in
-  $hdr_format in the manual
+       * snprintf.c, pattern.c, parse.c, mx.c, mh.c, lib.c, keymap.c, init.c, from.c, edit.c, curs_main.c:
+       Changing (int) casts in is* arguments to (unsigned char)
+       casts to avoid mis-casting of signed chars.  (From Michael
+       Elkins.)
 
-- messages were not included in replies in the non-PGP version of Mutt
+Tue Jul  7 09:22:40 1998  Thomas Roessler  <roessler@guug.de>
 
-- [patch-0.88.15.me.reply_attach.1] fixed segfault when using replying to an
-  attachment from the `attach' menu
+       * rfc822.c: Change one int to size_t in rfc822.c.
 
-- [patch-0.88.15.me.followup.1] fixed bug in generation of the
-  mail-followup-to: field
+       * rfc822.c: Fix the parsing of route addresses a la RFC 822.  Patch
+       from Michael Elkins.
 
-- [patch-0.88.15.me.ret_val.1] fixed some unchecked return values from
-  mx_open_new_message() and mx_append()
+       * snprintf.c, sendlib.c, pattern.c, parse.c, mx.c, mh.c, lib.c, keymap.c, init.c, from.c, edit.c, curs_main.c:
+       Cast the arguments of the is* functions to int.  Patch
+       from Michael Elkins.
 
+Thu Jul  2 21:15:18 1998  Thomas Roessler  <roessler@guug.de>
 
-PGP related changes since 0.88.14i
-----------------------------------
+       * hdrline.c:
+       Using the correct version of O'Shaughnessy Evans' %O patch.
 
-- [patch-0.88.14i.tlr.pgp_cleanup.1] Random clean-up
+       * configure.in, configure, Changes, ChangeLog: Preparig 0.92.14i
 
-- [patch-0.88.14i.tlr.pgp_flags.2] Display key
-  capabilities as ls(1) style flags on the key selection
-  menu.
+       * doc/manual.txt, doc/manual.sgml: s/&setmn;/&bsol;/
 
-- [patch-0.88.14i.tlr.pgp_invoke.1] Fix a typo in
-  pgpinvoke.c.
+       * hdrline.c: Adding the %O expansion.
 
-- [patch-0.88.14i.tlr.pgp_long_ids.1] Introduces a
-  pgp_long_ids option.  If set, 64 Bit Key IDs will be
-  passed to PGP.
-  
-- [patch-0.88.14i.tlr.pgp_sendkey.1] Fixes a segmentation
-  fault when sending PGP keys.
+       * doc/manual.sgml: Applying the various manual_nits patches.
 
-- [patch-0.88.14i.tlr.pgp_tempfiles.2] Cleans up a
-  temporary file leak in the PGP code.
+Wed Jul  1 17:01:50 1998  Thomas Roessler  <roessler@guug.de>
 
-Changes since 0.89
-------------------
+       * curs_main.c: Fixing a reverse-threading problem.
 
-- [patch-0.89i.de.no_subj.1] fixed possible coredump on NULL subject
+       * imap.c: Fixing an imap-related segmentation fault.
 
-- [patch-0.89i.tlr.snprintf.1] added unsigned hexadecimal support to the
-  supplied snprintf() routine
+Tue Jun 30 06:38:02 1998  Thomas Roessler  <roessler@guug.de>
 
-- [patch-0.89.bl.rfc1524_ws.1] fixed problem with whitespace in mailcap
-  entries
+       * reldate.h, Changes, ChangeLog:
+       These are the last tiny bits of preparing 0.92.13i.
 
-- [patch-0.89.bj.slang10config.1] fixed configure script to work with
-  slang-1.0 beta
+       * configure.in, configure, TODO, README, NEWS:
+       Updating some of the documentation for 0.93.
 
-- [patch-0.89.bugfix.buffycheck.mtsirkin.1] fixed bug with buffy
-  notification not being updated when entering a mailbox
+       * doc/Attic/NEWS: *** empty log message ***
 
-- when compiling with slang, set ESCDELAY to 300 because the default is too
-  fast for slow terminals (this is what ncurses uses by default)
+       * doc/Attic/NEWS: file NEWS was initially added on branch mutt-0-93.
 
-- [patch-0.88.13i.de.buffy_notify.1] fixed problem with new mail
-  notification in the current mailbox being clobbered by notifications in
-  other mailboxes
+       * doc/manual.txt: Incorporate the recent changes to manual.sgml.
 
-- truncated the ChangeLog to entries after version 0.88
+       * main.c: Work around a buffer overflow in SLang.  (This is the same
+       bug which is fixed by 0.91.2i.)
 
-- [patch-0.88.14.tlr.msg_7bit.1] fixed problem with $mime_fwd
+Fri Jun 26 10:31:28 1998  Thomas Roessler  <roessler@guug.de>
 
-- [patch-0.89.bj.set_followup_to.1] the user's address was added to the
-  mail-followup-to field if $metoo is set
+       * doc/manual.sgml, send.c, init.h, globals.h, Muttrc.in:
+       Removing $empty_to.
 
-PGP related changes since 0.89i
--------------------------------
+Thu Jun 25 22:31:46 1998  Thomas Roessler  <roessler@guug.de>
 
-- [patch-0.89i.tlr.pgp_sigvrfy.1] When verifying PGP/MIME
-  signatures, the LF -> CRLF could fail under certain
-  circumstances.
+       * hdrline.c: Moved a break statement where it belongs.
 
-- [tlr] Some long -> unsigned long changes in the pgp code
-  which are more of an aesthetical nature.
+       * mx.c: Fix an imap-related typo.
 
-- [tlr] The default of the $pgp_strict_enc variable has
-  been changed to "set".
+       * handler.c: Don't generate non-terminated last lines when quoting
+       8bit-"encoded" text-plain body parts.
 
-- [tlr] pgp-Notes.txt has been somewhat extended.
+       * Makefile.in: Don't use GNU make specific features.
 
-Changes since 0.89.1
---------------------
+Sun Jun 21 07:13:03 1998  Thomas Roessler  <roessler@guug.de>
 
-- [patch-0.89i.me.pointer.1] fix to use `unsigned long' instead of `void *'
-  for arguments where the data may be either an integer or a pointer.  this
-  was needed for 64bit systems where `sizeof(void*)!=sizeof(int)'
+       * doc/mutt.man, doc/Makefile.in, reldate.h, configure.in, configure, Changes, ChangeLog:
+       Bumping the release to 0.92.12i.
 
-- [patch-0.89i.me.pattern_hook.4] the pattern matching language can now be
-  used in send-hook, save-hook and fcc-hook instead of a single regular
-  expression
+Sat Jun 20 06:12:38 1998  Thomas Roessler  <roessler@guug.de>
 
-- [patch-0.89.bl.alter_weed.1] improves the mutlipart/alternative handler to
-  use auto_view, and adds viewing of MIME headers for attachments with
-  'display-headers'
+       * doc/manual.txt: *** empty log message ***
 
-- [patch-0.89.1.sec.expires_hdr.1] added support for the Expires: field.
-  auto-deletion of expiried messages is controlled with $expires
+       * handler.c: Fixing the quoted-printable decoder.
 
-- [patch-0.89.1i.co.mailx.1] added feedback for the `~r' command in mailx
-  mode
+       * handler.c, copy.c: Make mutt handle messages containing null bytes.
 
-- [patch-0.89.r.buf.1] buffer for backtic expansion of `mailboxes' was not
-  long enough
+       * doc/manual.sgml: documenting alias-path
 
-- [patch-0.89.1i.de.mail_followup_to-leak.1] fixed memory leak in freeing
-  the mail-followup-to: field from the ENVELOPE struct
+Fri Jun 19 12:52:16 1998  Thomas Roessler  <roessler@guug.de>
 
-- [patch-0.89.1i.de.list-reply-leak.1] fixed memory leak in the list-reply
-  function
+       * sendlib.c, send.c, protos.h, postpone.c, pattern.c, menu.c, main.c, headers.c, functions.h, curs_main.c, compose.c, OPS:
+       Removing the Attach-Menu feature for the next release
+       version.
 
-- [patch-0.89.1i.de.send-menu-leak.1] fixed memory leak when attaching files
-  to messages
+Thu Jun 18 20:37:59 1998  Thomas Roessler  <roessler@guug.de>
 
-- [patch-0.89.1i.de.remove_user.1] fixed bug in removing the user's address
-  from the list if it is the only recipient
+       * protos.h, lib.c, alias.c:
+       Bradon long's alias_path patch, for the sake of Elm
+       compatibility.
 
-- [patch-0.89.1i.de.pattern-regexp-leak.1] fixed memory leak with regular
-  expression compiled by mutt_pattern_comp() were never free()d
+Tue Jun 16 20:59:20 1998  Thomas Roessler  <roessler@guug.de>
 
-- [patch-0.89.1i.de.beep_new.1] adds the $beep_new variable to control
-  whether or not mutt will beep when new mail arrives
+       * mx.c: Avoid pointless error messages from mx_get_magic() when
+       called from an mx_open_mailbox_append() on a non-existing
+       mailbox.
 
-- [patch-0.89i.de.fcc-save-hook.1] adds new command `fcc-save-hook' which
-  creates a hook for use with either fcc-hook or save-hook
+       * doc/manual.txt, doc/Makefile.in, configure.in, configure, Makefile.in:
+       Have "make install" install manual.txt as well.
 
-- [patch-0.89.1i.de.buffy_sanity.1] fixes a problem with the buffy code
+       * doc/Attic/makefile, doc/Makefile.in:
+       Putting Makefile under autoconf control.
 
-- restored blank line between the "----- Forwarded message from..." line and
-  the text of the message
+       * main.c: Switch the error reporting address from mutt-users to
+       mutt-dev.
 
-- [patch-0.89.1i.de.tag-subthread.1] adds the `tag-subthread' command to the
-  pager
+       * reldate.h, configure.in, configure, Changes, ChangeLog:
+       Bump the version to 0.92.11i.
 
-PGP related changes since 0.89.1i
----------------------------------
+       * imap.h: Check in a proper version of imap.h.
 
-- [patch-0.89i.dme.attach-key.1], [patch-0.89i.dme.extract-key.1] Fixes to
-  the PGP 5 invocation code.
+       * color.c: Fix the "unknown color" bug reported by Vikas.
 
-- [patch-0.89.1i.tlr.pgp_extract.2] Fixes various problems with the PGP
-  code and attachment menu, in particular with respect to extracting keys.
+       * mx.c: Remove a spurious #include "imap.h" from mx.c.
 
-Changes since 0.90
---------------------
+       * doc/style-guide: Add a note about the global Muttrc to style-guide.
 
-- [patch-0.90.me.sort.2] $sort_aux is now used for all primary sorting
-  methods
+       * configure.in, Muttrc.in, configure, Attic/Muttrc, Makefile.in:
+       The global Muttrc contains a list of default settings
+       which can be used as a starting-point for the user's own
+       configuration.
 
-- [patch-0.90i.me.pattern.1] extended date matching language (~d) to accept
-  relative dates offset from the current date
+       * pgppubring.c, pgp.h, gnupgparse.c:
+       Removing some duplicate code from gnupgparse.c and
+       pgppubring.c.
 
-- [patch-0.90.me.thread_hash.3] modified threading algorithm to use hash
-  tables instead of a linear search
+       * pgpinvoke.c, gnupgparse.c:
+       Include part of Werner Koch's latest GPG patches.
 
-- [patch-0.90i.de.difftime.1] remove use of difftime() since it is not
-  portable
+       * Changes: *** empty log message ***
 
-- [patch-0.89.1i.de-bj.buffy_sanity.1-2] cleanup of the buffy check routine
-
-- [patch-0.90.me.addr_pattern.1] fixed some problems with the address
-  matching routines which caused problems for the send-hook and fcc-hook
-  commands
-
-- the size of the temp buffer used to expand regexps into patterns in
-  mutt_check_simple() was too short (SHORT_STRING) to handle the
-  patterns for send-hook, save-hook and fcc-hook, so it was increased to
-  LONG_STRING (1024) bytes
-
-- [patch-0.90.me.safe_path.1] fixed segfault when trying to save a message
-  with no recipients
-
-- [patch-0.89i.de.index-percentage.1] adds `%P' to $status_format to display
-  the percentage of the menu already seen (similar to the way the pager
-  works)
-
-- [patch-0.89.1i.bj.pager-redraw-clenaup.1] fixed some redraw problems in
-  the pager with $pager_index_lines set
-
-- [patch-0.89.1i.fp.filter.1] screen was not updated when filtering an
-  attachment an the the cte changed
-
-PGP related changes since 0.90i
--------------------------------
-
-- [patch-0.90i.tlr.pgp_attach_keys.1] Fixes a core dump on
-  the compose menu when attaching PGP public keys.
-
-- [patch-0.90i.tlr.pgp_encrflags.1] There were several
-  points in the code where a message's pgp flag was
-  evaluated the wrong way (namely, ...->pgp == PGPENCRYPT
-  instead of ... & PGPENCR).
-
-Changes since 0.90.1
---------------------
-
-- [patch-0.90.1i.tlr.hdrignore.1] fixed bug with weeding headers with the
-  CH_MIME bit set in mutt_copy_hdr()
-
-- [patch-0.90.1i.de.buffy-cleanup.1] cleaned up buffy to remove some
-  duplicated code and share some common global information
-
-- [patch-0.90.1i.arl.fcc-save.1] fixed some typos in the manual wrt to the
-  fcc-save-hook command
-
-- expansion of environment variables in mutt_extract_token() did not accept
-  underscore (_) as a valid value in variable names
-
-- fixed possible segfault in mutt_extract_token() if the result of a backtic
-  expansion was longer than the buffer used to store the expanded version of
-  the string
-
-- expansion of backtics is now option and controlled by whether or not the
-  `expn' argument in non-NULL.  this is needed by eat_regexp() where we
-  don't want backtic expansion
-
-- the ->personal member of the address was not matched in match_adrlist()
-
-- [patch-0.90.1.me.hash.1] fixed bug in hash_delete_hash() where the wrong
-  entry could be deleted when the key matched, but had a different data
-  pointer even if the data pointer was specified in the call 
-
-- changed default expansion for save-hook to '~f %s' and fcc/send-hook to
-  '~t %s | ~c %s'
-
-- the current search pattern was not invalidated if $simple_search changed
-  while in the middle of a search
-
-- [patch-0.90.1i.dme.nit-to_chars.1] fixed bug in docs wrt to $to_chars
-
-- added documentation for the `pattern_hook' patch
-
-- [patch-0.90.1.me.sort_to.1] adds support for sorting by the to: field with
-  `set sort=to'
-
-Changes since 0.90.2
---------------------
-
-- [patch-0.90.2i.de.toggle-quoted-redraw.1] fixed redraw problem with the
-  toggle-quoted function
-
-- [patch-0.90.2.de.buffy_check.1] fixed problem with -Z option
-
-- [patch-0.90.2.de.buffy_times.1] fixed problem of buffy reporting new mail
-  when saving messags from within mutt
-
-- [patch-0.90.1i.bj.in-reply-to-decode.1] fix to rfc2047 decode the
-  in-reply-to field before extracting the message-id
-
-- [patch-0.90.2.me.resort.1] fix to resort mailbox with $sort_aux or
-  $strict_threads changes
-
-- [patch-0.90.2.de.pretty_size.1] fixed rounding error which could cause the
-  display to be more than 4 chars
-
-- [patch-0.90.2.me.score.3] adds scoring support
-
-- [patch-0.90.2i.jg.pipe_from.1] the `From ' line was missing when piping a
-  message
-
-- [patch-0.89.1i.bj.skip_quoted.1] adds a `skip-quoted' (default: S)
-  function to the pager
-
-- tag-prefix was broken in the generic menu code when $auto_tag was unset
-
-- fixed bug in mutt_extract_token() wrt expanding backtics (``)
-
-- [patch-90.2i.tlr.addrbook.1] fixes address book so that select-entry
-  returns the current or tagged messages and exits
-
-- ESCDELAY default for slang is used again instead of setting it to 300ms
-
-- added `~R' to match references in the mutt_pattern_comp()
-
-PGP related changes since 0.90.2i
----------------------------------
-
-- [patch-0.90.2i.tlr.pgp-disptrust.1]  The trust status of
-  a key-user id relation is always displayed on the key
-  selection menu.
-
-- [patch-0.90.2i.tlr.pgp-subkeys.1] Subkeys are always
-  referred to using the principal key's numerical user ID.
-  This seems to be necessary to make PGP 5.0 extract them
-  properly.
-
-- The bit count for DSA keys is now displayed correctly.
-
-- A new option pgp_language (default: "en") is introduced.
-  This can be used to achieve an effect similar to the
-  alt_pgp patch.  See doc/pgp-Notes.txt for details.  A
-  big Thank You to Roland Rosenfeld for this idea!
-
-Changes since 0.90.3
---------------------
-
-- [patch-0.90.3.me.sort.1] fixed several bug relating to sorting by to or
-  score
-
-- %s in $status_format no longer includes $sort_aux, use %S to get the
-  $sort_aux value if desired (default value for $status_format now uses
-  (%s/%S) to mimic the old behavior)
-
-- [patch-0.90.3i.tlr.addrbook.1] fixed bug selecting the first alias in the
-  address book display
-
-- fixed bug in create-alias where mutt would dump core on a message with a
-  malformed address
-
-- parse_date() now always returns -1 on error
-
-- mailbox was not rethreaded when $sort_re changes
-
-- [patch-0.90.3.de.I_DECL.1] changes a few remaining variables in init.h to
-  the new I_DECL format
-
-- since most of the pattern matching commands were `envelope' types, changed
-  the semantics so that header and body matching are only done if the
-  M_FULL_MSG flag is set with mutt_pattern_comp()
-
-- backslash quoting did not work for the folder-hook and send-hook commands
-
-- use mutt_mktime() instead of mktime() in is_from()
-
-- [patch-0.90.3i.bj.skip-quoted.2] fixed bug in the skip-quoted function
-
-- [patch-0.90.3i.me.attach_pager.1] allows use of save/pipe/next/prev while
-  viewing attachments from the attach or compose menus
-
-- mutt_gen_msgid() changed to use getpid() so that unique id's are created
-  when mutt is invoked quickly in batch mode
-
-- Mutt now reports an error if the file specified by the `-F' command line
-  option does not exist
-
-- [jkj@sco.com] adds the $meta_key boolean option to case 8bit input to be
-  delivered as ESC + the char with the hi bit stripped
-
-- [patch-0.90.3i.me.editor_ext.1] improved line editor to be able to handle
-  unprintable control chars and to be able to bind the completion character
-
-- [patch-0.90.2i.bj.copy_hdr.2] rewrite of mutt_copy_hdr() to do reordering
-  in a single pass and to correctly unwrap fields for rfc2047 decoding
-
-- moved mutt_copy_hdr() to copy.c, and mutt_print_message() to commands.c
-  and eliminated print.c
-
-- `mutt -v' now displays the release date along with the version number.
-  the release date is also displayed with the `display-version' function
-
-
-PGP related changes since 0.90.3i
----------------------------------
-
-- [patch-0.90.3i.tlr.pgpkeyssort.1] If two keys have the
-  same User ID (i.e., mail address), use the numerical key
-  ID as the second sorting criteria for the key selection
-  menu.
-
-- [patch-0.90.3i.doc_pgp.1] Documentation for the PGP
-  support.  (By Roland Rosenfeld
-  <roland@spinnaker.rhein.de>).
-
-Changes since 0.90.4
---------------------
-
-- [patch-0.90.4i.bj.show_version.1] reduce code size required to print
-  compile time options
-
-- fix so that specifying more than two -v's on the command line always
-  prints the copyright statement instead of ignoring them
-
-- [patch-0.90.4.me.veryclean.1] adds a `veryclean' target to the Makefile to
-  remove files created by `configure'
-
-- the `inv' prefix now works for quadoptions
-
-- [patch-0.90.4.me.editor.1] adds `quote-char' function, and displays
-  control chars with the `markers' color, fixes bug in `buffy-cycle'
-
-- [patch-0.90.4i.me.unscore.1] adds the `unscore' command
-
-- [patch-0.89.1i.bj.tag-save.1] fixed bug in tag-save command
-
-- [patch-0.90.4i.me.help.1] added mutt_compile_help() to generate help
-  strings from `struct mapping_t'
-
-- [patch-0.90.4i.bj.hdr_fmt_recv.1] adds the %(fmt) to $hdr_format to
-  display the received time of a message
-
-- [patch-0.90.4i.bj.compose-disp-hdrs.3] fixes bug wrt to header weeding
-  with display-headers in the compose menu
-
-- [patch-0.90.4i.bjdeme.time.1] fixed calculation of local timezone and
-  added speedup when parsing mbox/mmdf mailbox and calculating the received
-  time from the `From ' line
-
-- added `flag' argument to mutt_pattern_exec() so that the
-  M_MATCH_FULL_ADDRESS option could be passed so that searching will match
-  the real name while the *-hook commands will not
-
-
-PGP related changes since 0.90.3i
----------------------------------
-
-- [patch-0.90.3i.tlr.pgpkeyssort.1] If two keys have the
-  same User ID (i.e., mail address), use the numerical key
-  ID as the second sorting criteria for the key selection
-  menu.
-
-- [patch-0.90.3i.doc_pgp.1] Documentation for the PGP
-  support.  (By Roland Rosenfeld
-  <roland@spinnaker.rhein.de>).
-Changes since 0.90.5
---------------------
-
-- [patch-0.90.5i.me.new_addr.1] replaces rfc822 address parser and related
-  data structures
-
-- [patch-0.90.5.bj.parse-speedup.new_addr-2] rewrite of
-  mutt_read_rfc822_line() and mutt_read_rfc822_header() to be more efficient
-
-- [patch-0.90.5i.me.hash_ext.1] added support for unique keys in the hash
-  table, and optional argument to the destroy functions to free the
-  associated data
-
-- [patch-0.90.5i.me.alias_sort.1] the sorting method and alias menu format
-  are now configurable via $alias_sort and $alias_format, respectively
-
-- [tlr] mx_open_mailbox() did not correctly free the created CONTEXT struct
-  upon failure
-
-- created function mutt_version() to display Mutt's version number
-
-- [patch-0.90.5i.rc.exactcompile.1] fixed warning about unused function when
-  compiling with `#undef EXACT_ADDRESS' in rfc822.c
-
-- [patch-0.90.5.sec.expires_new.1] adds ~S and ~E to match superceded and
-  expired messages
-
-- [patch-0.90.5.me.decode_followup.1] addresses in mail-followup-to: were
-  not rfc2047 decoded
-
-- [patch-0.90.5.bj.manual-nits.1] adds missing docs relating $status_format 
-
-Changes since 0.90.6
---------------------
-
-- [patch-0.90.6.me.unwrap_line.1] fixed bug in read_rfc822_line() wrt to
-  unwrapping folded lines
-
-- [patch-0.90.6.co.exactadd.1] fixed botched #ifdef in rfc822.c when
-  compiling with EXACT_ADDRESS
-
-- [patch-0.90.6i.jg.supersedes.2] changed `supercedes' to `supersedes' as
-  described in the current mailext I-D
-
-- added blurb on `--enable-exact-address' to the INSTALL file
-
-- fixed bug where messages with invalid dates showed up as being sent on Dec
-  31, 1969
-
-- added '-e' command line option to specify a config command to be run
-  _after_ parsing of initialization files
-  (eg.  mutt -e 'set edit_hdrs' mutt-dev)
-
-- added `edit-from' function to the `compose' menu (the From: field is now
-  also displayed)
-
-- added real bounds checking to rfc2047_encode_string() and friends
-
-- [tlr] fixed several bugs in the rfc2047 `Q' encoding (tabs were not
-  encoded, chars with hex value less than 0x10 were not padded with 0, =? in
-  a string was not encoded)
-
-- [patch-0.90.6.bugfix.locktimeout.1] added optional timeout to the locking
-  code so that the check for new mail will not to acquire a lock wait while
-  large mail is being delivered
-
-- [fvl] mutt_get_name() would segfault if a NULL address was passed in
-
-- [patch-0.90.6i.de.old-unread.1] adds %o and %u to $status_format to allow
-  display the number of `old' and `unread' messages
-
-- [patch-0.90.6.co.fwd.1] adds a blank line before the `---End of forwarded
-  message' line
-
-- the confirmation prompt for bounce-message will now only display the
-  address without the personal name to conserve space
-
-- [vl] arg to isspace() was not cast to `unsigned char' in rfc822.c
-
-- updated the pattern matching functions to add the following operators:
-       ~p              matches personal mail (finds $alternates in to: or cc:)
-       ~l              matches mail addressed to `lists'
-       ~L<pattern>     finds <pattern> in to:, cc:, from: or sender:
-       ~C<pattern>     finds <pattern> in to: or cc:
-
-
-PGP related changes since 0.90.6
---------------------------------
-
-- [patch-0.90.5i.rs.pgp_hdr.1] Preserve a message's PGP
-  settings when postponing
-
-Changes since 0.90.7
---------------------
-
-- included state.h, list.h, send.h in mutt.h and removed the others from the
-  distribution
-
-- [patch-0.90.7.me.default_from.1]
-
-- [patch-0.90.7i.de.limit.1] full name in addresses was not matched for `limit'
-
-- [patch-0.90.6.bugfix.locktimeout.1-2] changed `timeout' to `retry' in the
-  locking code since the former was misleading
-
-- [patch-0.90.7i.jg.help_line.1] offset of attachment was not calculated
-  correctly in the compose menu, cause the help line to be overwritten
-
-- fixed memory leak in rfc822_parse_address() when a parse error occurs (the
-  previously parsed address list was not returned and not freed)
-
-- [patch-0.90.7.me.vsnprintf.1] fixed bug where existence of snprintf()
-  assumed the existence of vsnprintf()
-
-- create-alias suggested the full email address as the default alias name
-  instead of just the mailbox portion
-
-- documented the `score' and `unscore' commands, and added %N to the
-  $hdr_format description
-
-- [patch-0.90.7i.bj.fgets_nit.1] size of buffer passed to fgets() was
-  incorrect
-
-- [patch-0.90.7i.bj.read_line.1] create common function mutt_read_line() for
-  reading lines which may contain a backslash on the end to wrap to the next
-  line
-
-- [patch-0.90.7i.bj.source_rc.1] makes source_rc() use the new
-  mutt_read_line() function
-
-- [patch-0.90.7.bugfix.buffycheck.mtsirkin.1] fixed another problem with
-  buffy
-
-- [patch-0.90.7.me.group_addr.1] fixed segfault when $use_domain is set and
-  you try to send to a group mailbox address
-
-- you can now use `mono <object> normal' to set to normal attribute
-
-- [patch-0.90.7i.de.hook.2] adds the $default_hook variable to control the
-  expansion of `simple' patterns in the send-hook, fcc-hook and save-hook
-  commands
-
-- it was not possible to use the $hdr_format sequences in $indent_str when
-  the switch to the new mutt_copy_message() and mutt_copy_hdr()
-
-- new common function km_get_table() which retrives the mapping of function
-  names based upon the MENU_* value
-
-- [patch-0.90.7i.bj.mailcap_parse.1] rewrote the mailcap parsing routines to
-  fix some bugs and be more efficient
-
-- [mac@eecg.utoronto.ca] added the `search-opposite' to search for the
-  current pattern in the opposite direction from the last search
-
-
-Changes since 0.90.8
---------------------
-
-- [patch-0.90.8.bj.display_loop.1] toggle of header weeding in the attach
-  and compose menus did not work
-
-- [patch-0.90.8.bj.manual_nit.1] documentation for displaying recieve date
-  in $hdr_format was missing
-
-- [patch-0.90.8.bj.pager_compile_help.1] pager did not use new function
-  mutt_compile_help()
-
-- [patch-0.90.8.bj.rename_file.1] changes mutt_rename_file() return codes
-  to be consistent with rename()
-
-- [patch-0.90.8.me.search.1] was not possible to bind the search functions
-  in the pager
-
-- [patch-0.90.8.me.time.1] fixed bug with the `~d >N' pattern
-
-- [patch-0.90.8.bj.reading_attachments.1] switching between viewing
-  attachments without returing to the attach menu was broken
-
-- [patch-0.90.8.bj.SKIPWS.1] removed unnecessary check for \0 in the
-  SKIPWS() macro
-
-- dest->fp was used directly in mx_open_new_message() where it should have
-  used msg->fp
-
-- `shell-escape' was moved to the generic keymap so that all menus can make
-  use of the function
-
-- added documentation on the `search-opposite' function
-
-- [patch-0.90.8i.tlr.rfc1524_fclose.1] fixed bug where fclose() could be
-  called with a NULL argument
-
-
-PGP related changes since 0.90.7
---------------------------------
-
-- [patch-0.90.7i.bj.pgp_hdr.1] Fixes some nits in
-  conection with the pgp_hdr patch.
-
-- [patch-0.90.7i.rs.pgp_hdr_doc.1] Adds documentation for
-  the pgp_hdr patche's effects.
-
-- [patch-0.90.7i.tlr.pgp_keysel.1] Fixes uniqueness
-  problems with the pgp key selection code.
-
-- [patch-0.90.8i.rr.pgp_get_table.1] The help function
-  wouldn't work on the PGP key selection menu.
-
-- [patch-0.90.8i.tlr.pgp_asymm.1] This patch replaces the
-  pgp_version variable by three variables:
-  pgp_receive_version, pgp_send_version, pgp_key_version.
-
-- [patch-0.90.8i.tlr.pgp_micalg.1] This patch enables the
-  user to generate correct "micalg" parameters when
-  composing PGP/MIME signed messages.
-
-Changes since 0.90.9
---------------------
-
-- [patch-0.90.9.me.personal_hook.1] fixed bug where ~P in send-hook patterns
-  did not work
-
-- [patch-0.90.9i.tlr.mutt_add_list.1] mutt_add_list() could create memory
-  which was unitialized to 0
-
-- [patch-0.90.9.me.group_alias.1] fixed bug where group address names were
-  expanded if a matching alias was found
-
-- definition of SKIPWS() in rfc822.c changed to match that in protos.h
-
-- [patch-0.90.9.josh.write_percent.1] the %-done is now shown when writing
-  out mbox/mmdf mailboxes just as is done for reading
-
-- body of message was not quoted with $indent_str if $forw_quote was set,
-  but $forw_decode is unset
-
-- changed initial value of $default_hook to "~f %s !~P | (~P ~C %s)"
-
-
-PGP related changes since 0.90.9i
----------------------------------
-
-- [patch-0.90.9i.tlr.pgppath.1] Properly check whether
-  PGPV2PATH and PGPV3PATH are defined in init.c.
-
-- [patch-0.90.9i.rr.pgp_key_version.1] Fixes a typo in the
-  pgp_key_version entry in init.h.
-
-- configure.in has been fixed so that _PGPPATH is not
-  defined unless at least one version of PGP exists on the
-  system.
-
-- A +nobatchinvalidkeys=off parameter has been added to
-  the pgpe invocation in pgpinvoke.c.
-Changes since 0.90.10
----------------------
-
-- added check for empty string arguments to the bind and macro commands
-
-- moved bit fields in CONTEXT and BODY structs to the end of the struct def
-  since there were not enough bits to fit into a 32-bit word
-
-- split include_message() into include_forward() and include_reply() since
-  little code was shared for the two cases
-
-- $forw_decode no longer controls weeding of the header when replying and
-  $headers is set
-
-- added doc blurb for $mime_fwd on the effects of decoding when this
-  variable is unset
-
-- [patch-0.90.10.me.unread.1] fixed error in calculation of unread messages
-  when the `new' bit is cleared from a message
-
-- fixed y2k problem in ~d pattern
-
-- an error was reported in the ~d pattern if using the open-ended form (eg.
-  1/1/98-) and any more text followed the pattern
-
-
-PGP related changes since 0.90.10i
-----------------------------------
-
-- mutt -v now correctly displays the various PGPPATH
-  variables.
-Changes since 0.90.11
----------------------
-
-- [patch-0.89.1i.bj.enriched.1] fixed buffer overflow in the text/enriched
-  handler
-
-- [patch-0.90.10.bl.sort_alias.1] adds the `unsorted' method for $sort_alias
-
-- [patch-0.90.10i.co.reply_regexp.1] changed initial value for $reply_regexp
-  to catch the `Re[2]:' style
-
-- changed check for new mail in MH-style mailboxes to consider messages new
-  if mtime >= atime
-
-- forwarded messages with $mime_fwd set are no longer forced to 7-bits when
-  not using PGP
-
-- updated the NEWS file with comments from the dev list
-
-- [patch-0.90.11i.de.stdin.2] fixed bugs with using stdin for -i or -H
-  command line arguments
-
-- [patch-0.90.11i.de.safe_fopen.1] changed many instances of fopen() to
-  safe_fopen() to avoid tempfile race conditions
-
-- the generic menu code did not print "Tag-" when using tag-prefix
-
-- [0.90.11-vikas.doc_nit] fixed bug with use of &gt; in the description of
-  $status_format
-
-- [patch-0.90.11i.ds.man_tilde_nit.1] fixed use of ~ where &tilde; should
-  have been used in manual
-
-- [patch-0.90.11i.rr.date_received.1] the parser table for ~r in the pattern
-  language used eat_regexp() instead of eat_date()
-
-- [patch-0.90.11i.me.attach_reply] fixes reply/forward of (tagged)
-  attachments from the attach menu
-
-- [patch-0.90.11.bj.make_string.1] fixes display of control chars and other
-  non-printable chars in the $*_format variables
-
-- [patch-0.90.11i.tlr.cdisp.2] fixes message_to_7bit() to not destroy the
-  existing content-disposition `filename' information
-
-- fixed bug in rfc822 parser where quoted-pair was not accepted in the
-  `mailbox' or `domain' tokens
-
-
-PGP related changes since 0.90.11i
-----------------------------------
-
-- [patch-0.90.11i.roro.doc.1.gz] Added some more PGP
-  documentation.  Spelling and grammar corrections from
-  native speakers are welcome!
-Changes since 0.90.12
----------------------
-
-- [patch-0.90.11i.me.boundary.1] mutt_write_mime_body() did not use
-  mutt_get_parameter() to fetch the MIME boundary
-
-- [patch-0.90.12i.tlr.recall.1] fixed segfault when attempting to recall
-  postponed messages
-
-- [patch-0.90.12i.rr.hdrline.1] fixed misapplied patch for the make_string
-  support
-
-- fixed error message on nonexistant file specified with -i or -H
-
-- [patch-0.90.12.me.safe_fopen.1] safe_fopen should not be used when it is
-  desirable for the specified file to be overwritten
-
-
-PGP related changes since 0.90.12i
-----------------------------------
-
-- [patch-0.90.12i.maj.pgp_extract_keys_nit.1] Correct the
-  behaviour when typing C-K in an empty folder.
-Changes since 0.90.13
----------------------
-
-- [patch-0.90.13i.de.enter_fname.1] buffy-cycle should act like complete
-  when in the save/copy message prompts
-
-- [patch-0.90.13i.rr.normalize_time.1] mutt_normalize_time() didn't handle
-  the case where a date rolled over to the previous year when selecting by
-  number of months in the past
-
-Changes since 0.91
-------------------
-
-- fixed bug in rfc822_parse_adrlist() where it would segfault on a bad address
-  which contained only a comment
-
-- [patch-0.90.12i.tlr.recall.1] fixed segfault when attempting to recall a
-  postponed message which was a reply to another message
-
-- [patch-0.91.me.exit_main.1] fixes collision in function name for "exit" in
-  the "generic" and "index" keymaps
-
-- corrected documentation on $hdrs which erroneously stated that user defined
-  headers are never included in batch mode sending
-
-Changes since 0.91.1
---------------------
-
-- [patch-0.91i.me.dyn_str.2] changes global string variables to `char *'
-  instead of fixed size arrays, and moves defaults for variables to the
-  MuttVars[] array
-
-- [patch-0.91.me.format_string.1] creates common function
-  mutt_FormatString() for handling %-substituted strings in a generic manner
-
-- [patch-0.91.vikas.limit_size.4] adds %L to $hdr_format to display the
-  total size of all visible messages when limited
-
-- [patch-0.91.me.followup.1] Adds boolean $followup_to to control
-  generatation of the Mail-Followup-To field.  Also allows user to edit this
-  field and not have it overwritten.
-
-- [patch-0.91i.me.sendmail.1] Removes $sendmail_bounce.  Mutt now passes all
-  recipients on the command line for normal sending.
-
-- [patch-0.90.10i.bj.current_time.1] adds sequence %<fmt> to $hdr_format to
-  display the current time using strftime(fmt)
-
-- [patch-0.90.10.bl.alternative_order.1] allows user specification of the
-  order in which to choose types from multipart/alternative messages
-
-- [my_hdr-subject-patch2] allows specification of a default subject (if none is
-  given using the `my_hdr' command
-
-- [patch-0.91i.as.revname.1] makes $reverse_name look at from: if the message
-  you are replying to is from you
-
-- added new operator ~B to pattern matching language which matches a regexp
-  anywhere in a message (more efficient than ~h %s | ~b %s).
-
-- changed the `source' command to use mutt_open_read() instead of fopen() so
-  that you can read from the output of a script (eg. "source
-  ~/bin/mutt_commands|").
-
-- fixed typos in the description of `forget-passphrase' in the manual
-
-- the -e option was not document in either the man page nor the manual
-
-- [patch-0.91.bl.composetyped.1] adds support for creating non-text body
-  parts from within the compose menu
-
-- $reverse_name is now handled before send-hook so that user's can match on
-  the from field with ~f
-
-- [patch-0.91i.de.threadlimit.1] allows drawing of thread trees while in
-  limited display
-
-- [mutt-0.89i-quadopt_mimefwd.patch] turns $mime_fwd into a quad-option
-
-- [patch-0.91i.jmy.folder_format.1] the display of the `browser' menu is now
-  configurable via the $folder_format variable
-
-- [patch-0.91i.jmy.pattern-size.1] adds ~z operator to the pattern matching
-  function to match by size
-
-- rfc822.c now uses some functions from mutt proper (safe_strdup and
-  mutt_substrdup) instead of attempting to be a self-contained library
-
-
-PGP related changes since 0.91.1
---------------------------------
-
-- [patch-0.91.1i.tlr.pgp_obsolete_vars.1] Removes the
-  obsolete pgp_v3_* variables.
-Changes since 0.92
-------------------
-
-- [patch-0.91.me.reuse_hook.1] the result portion of those hooks which can
-  have only a single matching pattern (ie. send-hook) were not updated if the
-  same pattern was specified with a different result.
-
-- [patch-0.92.me.empty_pop_str.1] fixes core when fetching POP3 mail if any
-  of the $pop_* string variables were empty
-
-- [patch-0.92.me.empty_route.1]
-
-- [patch-0.92.me.regexp_case.1] REG_ICASE was not set for regexp variable
-  defaults in mutt_restore_default()
-
-- [patch-0.92.de.threadlimitfix.1] fixes small bug in the threadlimit code
-  which could cause extra work to be done when not needed
-
-- [patch-0.92.me.format_pad.1] fixed segfault when the value of
-  $status_format is wider than the screen
-
-- [patch-0.92.me.draft_path.1] the paths for neither -i nor -H were being
-  expanded before use
-
-- [patch-0.92.vikas.nits]
-  1. %M in $status_format was getting truncated after 3 digits because of a
-     tiny mistake in mu
-  2. The ~z pattern matching has a small nit at the boundaries where
-     ~z<1024 matches Content-length: 1024 as well. I just changed the inclusive
-     ranges ( <= and >= ) to exclusive ranges ( < and > ) in pattern.c
-  3. Added a line about the new %L format specifier for $status_format
-
-
-PGP related changes since 0.92
-------------------------------
-
-- No more (char *) deferences of (char **) in pgp_invoke.c.
-Changes since 0.92.1
---------------------
-
-- [0.92.1.me.format_pad.1] fixed another problem with the result of
-  subtracting two size_t's and the result being negative
-
-- [0.92.1.me.batch_copy.1] $copy was ignored when sending mail in batch mode
-
-- [patch-0.92.1.josh.sort_re-tilde.1] reset default values of $sort_re and
-  $tilde to their 0.91.1 values.
-
-- [patch-0.92.me.func_macro.1] changes function key names to use <> around
-  then (eg.  <PageUp>) and allows them to be used in macros as well
-  (eg.  macro index Y *<PageUp>)
-
-- [patch-0.92.1i.rr.reset.2] adds the `reset' command and the `&' prefix to
-  `set' to allow resetting variables to the default value
-
-- changed the %g (group) and %u (userid) sequences of $folder_format to
-  print the gid and uid, respectively, if they can't be resolved to names,
-  instead of diplaying "(null)"
-
-- [patch-0.92.1i.me.sendmail_wait.2] adds $sendmail_wait which specifies the
-  number of seconds to wait for sendmail to finish before background it
-
-- [patch-0.92.1.co.bounce.2] fixes problem with the bounce-message
-  confirmation prompt
-
-- [patch-0.92.1.bl.attach_del.2] adds the ability to delete attachments
-
-- [patch-0.92.1i.jg.default_opts.2] changed var defaults to match what is in
-  the manual
-
-- [patch-0.92.1i.rr.no_signature.1] fixed segfault with
-       set signature=''
-  when composing mail
-
-- [patch-0.92.1i.rr.manual_nits.1] fixed some spelling errors in the manual
-
-- [mutt-0.91.1a.patch (partial)] if KEY_RESIZE is defined, mutt_getch() will
-  ignore it (generated by ncurses 4.2 on SIGWINCH)
-
-- [patch-0.92.1.bl.query.1] adds support for querying an external database
-  for email addresses
-
-
-PGP related changes since 0.92.1i
----------------------------------
-
-- [patch-0.92.1i.wn.verify_sig-pgp_timeout.1] Make the
-  verify_sig and pgp_timeout defaults consistent between
-  init.h and the manual.
-
-- [patch-0.92.1i.tlr.pgp_keysel.1] Fix a segmentation
-  fault in the key selection code.
-
-- [patch-0.92.1i.tlr.pgpsign.1] The PGP signing code works
-  again.
-
-- Changed $verify_sig to $pgp_verify_sig.
-Changes since 0.92.2
---------------------
-
-- [patch-0.92.2i.tlr.sendlib_args.1] fixes segfault when sending mail
-
-- [patch-0.92.2.me.reverse_name.1] fixed problem with $reverse_name altering
-  the HEADER struct for the message being replied to.
-
-- [patch-0.92.2.sort_flag.1] fixed problem with `score' command not updating
-  the score when $sort or $sort_aux was not `score'
-
-- [patch-0.92.2i.me.sendmail.1] adds debugging info to the send_msg()
-  command
-
-- [patch-0.92.2i.dme.generic-op_jump.1] fixed missing binding for 3-9 to
-  `jump' in the generic keymap
-
-- [patch-0.92.2.me.sort_alias.1] fixed problems with $sort_alias not working
-
-- [patch-0.92.2i.me.msg_search.1] fixed bugs in the ~h, ~B and ~b search
-  patterns
-
-- [patch-0.92.2i.me.postpone.1] x-mutt-references was not removed when
-  recalling a postponed reply when no mailbox is open
-
-- included <unistd.h> for def of SEEK_SET in copy.c (SunOS 4.1.4)
-
-- [patch.sendlib.2] fixes signal handling in send_msg(), and fixes leftover
-  temporary files after sending the message
-
-- [patch-0.91.1i.aw.purgeprompt.1] the prompt for $delete now shows how many
-  messages will be purged
-
-- [patch-0.92.1i.jg.empty_to.1] makes the string used for the group mailbox
-  name when there are no to: or cc: recipients configurable via the
-  $empty_to variable
-
-- moved mutt_signal_init() before initscr() in start_curses() so that
-  ncurses 4.2 will not attempt to install its on SIGWINCH handler
-
-
-PGP related changes since 0.92.2i
----------------------------------
-
-- White space problems around "#ifdef _PGPPATH" should be
-  fixed now.
-
-- The .spec file for RedHat is gone.
-Changes since 0.92.3
---------------------
-
-- alarm() was not actually set to put sendmail in the background when
-  $sendmail_wait > 0
-
-- [patch-0.92.3.de.threadlimitfix.1]
-
-- [patch-0.92.3.josh.delete_format.1] changes default for $delete_format
-
-- [patch-0.92.3.me.var_syn.1] renames some variables and creats a synonym
-  data type
-
-- [patch-0.92.3.vikas.sort_alias] fixed bug with `set sort_alias=unsorted'
-
-- [patch-0.92.3i.de.hashtable-leak.1] fixed memory leak when destroying
-  hash tables
-
-- [de] fixed memory leak in init.c where the value of $alias_file was not
-  free()d before assigning the default from the default muttrc to use
-
-- [patch-0.92.3i.tlr.keymaps.1] fixed missing keybindings for the `jump'
-  command
-
-- fixed typo "Purpge" in mx_close_mailbox()
-
-- [patch-0.91.1.ldm.ignore_list_reply_to] fixed bug with handling of
-  $ignore_list_reply_to
-
-- fixed signal initialization to call before initscr() for ncurses and after
-  initscr() for slang
-
-- [patch-0.92.3.vikas.alias_search] makes searching in the alias menu
-  WYSIWYG
-
-- fixed memory leak in parse_route_addr() when the route-addr portion of an
-  address was unable to be parsed
-
-- [patch-0.92.3i.tlr.query_real.1]
-
-- [patch-0.92.3.color_index.7] adds the ability to color lines in the index
-  using the searching language
-
-
-PGP related changes since 0.92.3i
----------------------------------
-
-- [patch-0.92.3i.tlr.keymaps.1] Add some lost keymap
-  bindings for the generic menu.
-
-- [patch-0.92.3i.tlr.pgp_default_version.1] The default
-  value of $pgp_default_version is now set correctly.
-
-- [patch-0.92.3.bl.pgp_attach_del.1] Handle PGP/MIME
-  messages correctly when deleting attachments.
-
-- [patch-0.92.3i.rr.postpone_pgp.1] Corrects some bugs
-  with respect to postponing PGP signed messages.
-Changes since 0.92.4
---------------------
-
-- [patch-0.92.4.josh.empty_querycmd.2] fixed segfault on $query_command
-  being set to ''
-
-- [recv.diff] the warning from filter-attachment was not cleared when you
-  answer no or abort
-
-- [patch-0.92.4i.rr.mime_forward_decode.1] splits $forward_decode into
-  $forward_decode and $mime_forward_decode
-
-- [patch-0.92.1.optional_list.2] makes the %L in $header_format an optional
-  string using the %?L?...? syntax
-
-- [patch-0.92.4.me.savehook.1] makes it possible to use ~b and ~h in
-  save-hook commands
-
-- [patch-0.92.4i.me.token.2] upgrades the muttrc parser to use dynamic
-  buffer allocation, and allows multiple commands on a single line separated
-  by semicolons
-
-- the bcc: field is again output to the $sendmail program, and is assumed
-  that the MTA will take care of removing it
-
-- fixed memory leak in parse_route_addr()
-
-
-PGP related changes since 0.92.3i
----------------------------------
-
-- [patch-0.92.3i.tlr.keymaps.1] Add some lost keymap
-  bindings for the generic menu.
-
-- [patch-0.92.3i.tlr.pgp_default_version.1] The default
-  value of $pgp_default_version is now set correctly.
-
-- [patch-0.92.3.bl.pgp_attach_del.1] Handle PGP/MIME
-  messages correctly when deleting attachments.
-
-- [patch-0.92.3i.rr.postpone_pgp.1] Corrects some bugs
-  with respect to postponing PGP signed messages.
-Changes since 0.92.5
---------------------
-
-- [patch-0.92.4i.de.parse_date.1] better recovery from badly formatted
-  timezones
-
-- [patch-0.92.5.de.Muttrc-memleak.1] fixed memory leak when using the -F
-  command line option
-
-- [patch-0.92.5i.bj.pgp_bitfield.1]
-
-- [patch-0.92.5i.jg.empty_to_doc.1] adds documentation for the $empty_to
-  variable
-
-- [patch-0.92.5i.rr.ask_quit.1] new variable $quit which controls the prompt
-  for exiting mutt
-
-- [patch-0.92.5.vikas.color_index.7-10] fixed bugs in the `uncolor' command
-
-- fixed coredump if $to_chars is set to ''
-
-- [patch-0.92.5.vikas.wrap_search] new variable $wrap_search which controls
-  whether or not searches wrap around the first or last message
-
-- [patch-0.92.4i.dj.addr_hook_patterns.3] the mailbox specified in a
-  save-hook is now %-expanded using $header_format
-
-- the default save mailbox no longer looks at defined `lists'.  to get the
-  old behavior, use
-       save-hook ~l %B
-
-- optional strings in format strings have been extended to allow for an
-  `else' clause.  the new syntax is:
-       %?<testchar>?<if-string>&<else-string>?
-  or if no `else' clause is desired (backwards compatibility):
-       %?<testchar>?<if-string>?
-
-- [patch-0.92.5.bj.interrupt_search.1] allows interruption of `search' using
-  the shell's interupt (SIGINT) character
-
-- [patch-0.92.5i.jg.attach_split_sep.1] removed useless code and docs
-  relating to $attach_split and $attach_sep
-
-- [patch-0.92.5.vikas.toggle_write] if the mailbox is read-only and the
-  user attempts to sync, a more informative error message is now displayed
-
-
-Changes since 0.92.6
---------------------
-
-- [patch-0.92.6.vikas.limit_new.3] adds support for new mail delivery while
-  a limit is in effect
-
-- [patch-0.92.6.vikas.wrap_search.2] adds docs for $wrap_search
-
-- [patch-0.92.6i.de.quit.1] changes the default for $quit to `yes'
-
-- [patch-0.92.6.me.rfc822.1] fixed buffer overrun error in
-  rfc822_write_address_real()
-
-- [mutt-0.92.6i-mhsupport.patch]
-
-- [patch-0.92.6i.de.reopen_unread.1]
-
-- consolidated common code for editing address lists in edit_envelope()
-
-- changed parse_alias() to use mutt_parse_adrlist() instead of
-  rfc822_parse_adrlist() so that you can have simple aliases like:
-       alias group bob joe
-  with no commas (mailx compatibility)
-
-Changes since 0.92.7
---------------------
-
-- [patch-0.92.7.handler.empty_cc_bcc.1] fixed bug in edit_envelope() which
-  caused the message to be aborted if the cc or bcc field was empty
-
-- buffer used to store the error message in mutt_pattern_comp() called
-  sizeof() on the wrong variable
-
-- renamed $header_format to $index_format ($hdr_format is still accepted)
-
-- [patch-0.92.7.vikas.postpone.1] fixed typo for binding the `postpone'
-  menu, and changes the menu to use $index_format for display of postponed
-  messages
-
-- mutt_error() is now a function pointer which either has the value of
-  mutt_curses_error() or mutt_nocurses_error() which simplifies the muttrc
-  parsing code
-
-- "source '~/bin/myscript|'" was fixed so that it works correctly
-
-- [patch-0.92.7.me.mh_sync.1] fixed bug where syncing mh mailboxes silently
-  failed
-
-- [patch-0.92.7.me.pattern.1] fixes bug with mismatched backtics in the
-  pattern language
-
-- mutt_default_from() no longer sets the "real name" portion of the return
-  address so that it can be delayed until after execution of send-hook
-  commands
-
-
-PGP-related changes since 0.92.6i
----------------------------------
-
-- [patch-0.92.6i.tlr.pgp_longids.1] Correct the
-  calculation of 64 bit "v4" key IDs.
-
-Changes since 0.92.8
---------------------
-
-- [patch-0.90.12i.jmydaes.command-complete.1] Command completion
-
-- [patch-0.92.8.mtsirkin.attach-viewer.1] When viewing
-  attachments, fall back to the attachment's file name if
-  no description is available.
-
-- [patch-0.92.8i.ds.attachmsg.1] Attach messages from the compose menu.
-
-- [patch-0.92.8i.tlr.make_string_context.1] Fix a
-  segmentation fault when invoking mutt -p from the
-  command line.
-
-- [patch-0.92.8i.tlr.mh_sequences.1] Don't generate
-  .mh_sequences files for maildir folders.
-
-- fix a NULL pointer deference in hdrline.c
-
-- [patch-0.92.8i.jmy.hook-bugfix.1] Fix a segmentation
-  fault in the send-hook code.
-
-- [patch-0.92.8i.tlr.addrbook.1] Untag all aliases before
-  entering the address-book menu.
-
-- Enforce a non-NULL QueryCmd in the beginning of
-  mutt_query_complete() and mutt_query_menu().
-
-- Make all query.c functions except mutt_query_complete()
-  and mutt_query_menu() static.
-
-- The latest IMAP patch from Andy Sloane has been added.
-
-PGP related Changes since 0.92.8i
----------------------------------
-
-- [patch-0.92.8i.maj.MIC_alg.1] Properly initializes a
-  variable in the PGP part of the Compose menu.
-
-- [patch-0.92.8i.tlr.pgpkey_dflt.1] Avoid possible
-  segmentation faults when determining the default value
-  of the PGP key selection prompt.
-
-- [patch-0.92.8i.wk.opgp_5bytelength.1] Recognize
-  OpenPGP's public key algorithm #20 (i.e., ElGamal for
-  Signing and Encrypting).
-
-- Moved doc/pgp-Notes.txt to doc/PGP-Notes.txt, and
-  updated that part of the documentation.
-
-
-Changes since 0.92.9i
----------------------
-
-Tue Jun 16 00:22:28 1998  Thomas Roessler  <roessler@guug.de>
+       * configure.in, configure, Changes, ChangeLog: Preparing 0.92.10i.
 
        * doc/PGP-Notes.txt: Including Roland's new procmail recipe.
 
@@ -1811,14 +904,3 @@ Mon Jun 15 15:19:49 1998  Thomas Roessler  <roessler@guug.de>
 
        * mx.c, main.c, mailbox.h, imap.c, commands.c: Brandon's IMAP patch.
 
-Mon Jun  8 20:05:54 1998  Thomas Roessler  <roessler@guug.de>
-
-       * recvattach.c, pgppubring.c, pgpkey.c,
-       pgpinvoke.c, pgp.h, pgp.c, main.c, init.h,
-       gnupgparse.c, init.c, configure.in, configure,
-       config.h.in, compose.c, acconfig.h, Makefile.in:
-       GPG support, first take.
-
-       * hdrline.c: Fixing the %a format.
-
-       * hdrline.c: Fixing a segmentation fault in the hdr_line code.
diff --git a/Changes b/Changes
deleted file mode 100644 (file)
index 5e668d2..0000000
--- a/Changes
+++ /dev/null
@@ -1,25 +0,0 @@
-Changes since 0.92.10i
-----------------------
-
-Tue Jun 16 15:15:00 1998  Thomas Roessler  <roessler@guug.de>
-
-       * imap.h: Check in a proper version of imap.h.
-
-       * color.c: Fix the "unknown color" bug reported by Vikas.
-
-       * mx.c: Remove a spurious #include "imap.h" from mx.c.
-
-       * doc/style-guide: Add a note about the global Muttrc to style-guide.
-
-       * configure.in, Muttrc.in, configure, Attic/Muttrc, Makefile.in:
-       The global Muttrc contains a list of default settings
-       which can be used as a starting-point for the user's own
-       configuration.
-
-       * pgppubring.c, pgp.h, gnupgparse.c:
-       Removing some duplicate code from gnupgparse.c and
-       pgppubring.c.
-
-       * pgpinvoke.c, gnupgparse.c:
-       Include part of Werner Koch's latest GPG patches.
-
diff --git a/INSTALL b/INSTALL
index edef9e84071f163283c1c91b32cabb406d62de66..34f7fce7a5962ed45be30f3e50b50de1cec3c4de 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -18,6 +18,7 @@ systems:
        MkLinux
        NetBSD
        QNX
+       SCO Unix 3.2v4/5
        Solaris
        SunOS
        Ultrix
@@ -37,11 +38,12 @@ systems:
 Installation
 ============
 
-Installing Mutt is rather painless through the use of the GNU autoconf
-package.  Simply untar the Mutt distribution, and run the ``configure''
-script.  In most cases, it will automatically determine everything it needs
-to know in order to compile.  However, there are a few options to
-``configure'' to help it out, or change the default behavior:
+Installing Mutt is rather painless through the use of the GNU
+autoconf package.  Simply untar the Mutt distribution, and run the
+``configure'' script.  In most cases, it will automatically determine
+everything it needs to know in order to compile.  However, there are
+a few options to ``configure'' to help it out, or change the default
+behavior:
 
 --prefix=DIR
        install Mutt in DIR instead of /usr/local
@@ -71,22 +73,19 @@ to know in order to compile.  However, there are a few options to
 --enable-pop
        enable POP3 support
 
---enable-hidden-host
-       local hostname is not part of the FQDN.
-
 --with-rx
        use GNU rx instead of local regexp routines.  Many systems don't
        have the POSIX compliant regcomp/regexec/regfree routines, so this
        provides a way to support them.
 
 --enable-flock
-       use flock() to lock files
+       use flock() to lock files.  
 
 --disable-fcntl
        by default, Mutt uses fcntl() to lock files.  Over NFS this can
        result in poor performance on read/write.  Note that using this
-       option could be dangerous if dotlocking is also disabled
-
+       option could be dangerous if dotlocking is also disabled.
+       
 --enable-nfs-fix
        some implementations of NFS do not always write the
        atime/mtime of small files.  This means that Mutt's ``mailboxes''
@@ -114,12 +113,17 @@ to know in order to compile.  However, there are a few options to
        when you press '!'.  Only use this option to solve the above problem,
        and only specify one of the above shells as its argument.
 
+       (If you encounter this problem with your platform's native
+       Bourne shell, please send a short report to mutt-dev@cs.hmc.edu,
+       so a short note on this topic can be added to the Platform notes
+       section below.)
+
 --enable-exact-address
        By default, Mutt will rewrite all addresses in the form
                Personal Name <user@host.domain>
        regardless of the input.  By enabling this option, Mutt will write
        addresses in the same form they are parsed.  NOTE: this requires
-       significantly more memory
+       significantly more memory.
 
 Once ``configure'' has completed, simply type ``make install.''
 
@@ -129,9 +133,18 @@ A_NORMAL or KEY_MIN, then you probably don't have a SysV compliant curses
 library.  You should install either ncurses or S-Lang (see above), and then
 run the ``configure'' script again.
 
+
 Platform Notes
 ==============
 
+All platforms
+
+       There is a bug in most (if not all) S-Lang versions which
+       prevents the Meta key from working with mutt.  A patch can be
+       found in the file patch.slang-1.2.2.keypad.1 in this mutt
+       distribution.
+
+
 Solaris 2.4
 
        The system regcomp() and regexec() routines are very badly broken.
@@ -142,3 +155,34 @@ Solaris 2.4
        Color does not work right with Solaris curses.  You will have to
        compile with either ncurses or slang to get working color support.
 
+
+Linux
+
+       On recent Linux systems, flock() and fcntl() locks don't mix.  If
+       you use the --enable-flock switch on such systems, be sure to
+       give the --disable-fcntl argument as well.
+
+       The Linux libc 5.4.45 disables locale support in programs running
+       setgid mail.  You'll need to use the configure switch
+       "--enable-locales-fix".  If you're using a non-iso-8859 font, you
+       lose.  This is not an issue on glibc (libc 6) based systems.
+
+
+Digital Unix (OSF/1)
+
+       Don't try "--with-rx", because you won't be able to match
+       anything (using system's regex functions seems to work fine
+       though).
+
+       Also, the system curses library is said to be badly broken.  Use
+       GNU ncurses or SLang instead.
+
+
+FreeBSD 3.0
+
+       /bin/sh is broken on this platform.  You need the
+       "--with-exec-shell" configuration switch here; ksh
+       and bash are reported to be fine.
+
+       This may also be an issue with earlier FreeBSD
+       versions.
index d02a7ca5bb77941cb8609fd16ad2f7a3adaf5e1a..e28b5d539a50850d65c26192a5d80a605ebffaf5 100644 (file)
@@ -32,21 +32,22 @@ VPATH=@srcdir@
 
 INSTALL=@INSTALL@
 CC=@CC@
-XCPPFLAGS=-I. @CPPFLAGS@
-CFLAGS=@CFLAGS@ -DSHAREDIR=\"$(sharedir)\" $(XCPPFLAGS)
+XCPPFLAGS=-I. @CPPFLAGS@ -DSHAREDIR=\"$(sharedir)\" -DDOTLOCK=\"$(bindir)/mutt.dotlock\"
+CFLAGS=@CFLAGS@  $(XCPPFLAGS)
 LDFLAGS=@LDFLAGS@
 LIBS=@LIBS@
 OPS=@OPS@
 OBJS=  addrbook.o alias.o attach.o browser.o buffy.o color.o \
         commands.o complete.o compose.o copy.o curs_lib.o curs_main.o date.o \
        edit.o enter.o flags.o init.o filter.o from.o getdomain.o \
-       handler.o hash.o hdrline.o headers.o help.o hook.o keymap.o lib.o \
+       handler.o hash.o hdrline.o headers.o help.o     \
+       history.o hook.o keymap.o lib.o \
        main.o mbox.o menu.o mh.o mx.o pager.o parse.o pattern.o \
        postpone.o query.o recvattach.o rfc822.o \
        rfc1524.o rfc2047.o score.o send.o sendlib.o signal.o sort.o \
        status.o system.o thread.o @LIBOBJS@
 
-CLEANFILES=mutt *.o core
+CLEANFILES=dotlock mutt *.o core
 VERYCLEANFILES=$(CLEANFILES) Makefile config.cache config.log \
        config.status config.h Muttrc
 DISTCLEANFILES=$(VERYCLEANFILES) tags keymap_defs.h *.rej *.orig *~ Makefile.bak
@@ -56,19 +57,22 @@ NONEXPORT=pgp.c pgp.h pgpinvoke.c pgpkey.c pgppubring.c sha.h sha1dgst.c \
        gnupgparse.c sha_locl.h OPS.PGP doc/pgp-Notes.txt doc/language.txt \
        doc/language50.txt
 
-all: mutt
+all: mutt @DOTLOCK_TARGET@
 
 mutt: keymap_defs.h $(OBJS) $(REGEX)
        $(CC) -o mutt $(OBJS) $(REGEX) $(LDFLAGS) $(LIBS)
 
+dotlock: dotlock.o @SNPRINTFOBJS@
+       $(CC) -o dotlock dotlock.o @SNPRINTFOBJS@
+
 keymap_defs.h: Makefile $(OPS)
        rm -f keymap_defs.h
        $(srcdir)/gen_defs $(OPS) > keymap_defs.h
 
-install: mutt install.doc
+install: mutt install.doc @DOTLOCK_INSTALL_TARGET@
        $(srcdir)/mkinstalldirs $(bindir)
        -mv -f $(bindir)/mutt $(bindir)/mutt.old
-       $(INSTALL) @MUTT_GROUP@ -m @MUTT_PERMISSION@ mutt $(bindir)
+       $(INSTALL) -m 755 mutt $(bindir)
        -if [ ! -f $(sharedir)/Muttrc ]; then \
                $(srcdir)/mkinstalldirs $(sharedir); \
                $(INSTALL) -m 644 $(srcdir)/Muttrc $(sharedir); \
@@ -77,14 +81,19 @@ install: mutt install.doc
                $(INSTALL) -m 644 $(srcdir)/mime.types $(sharedir); \
        fi
 
+install.dotlock: dotlock
+       $(srcdir)/mkinstalldirs $(bindir)
+       -mv -f $(bindir)/mutt.dotlock $(bindir)/mutt.dotlock.old
+       $(INSTALL) @DOTLOCK_GROUP@ -m @DOTLOCK_PERMISSION@ dotlock $(bindir)/mutt.dotlock
+
 install.doc: 
-       make -C  $(srcdir)/doc/ install
+       ( cd $(srcdir)/doc &&  make install )
 
 uninstall: uninstall.doc
-       rm -f $(bindir)/mutt $(sharedir)/Muttrc
+       rm -f $(bindir)/mutt $(sharedir)/Muttrc $(bindir)/mutt.dotlock
 
 uninstall.doc:
-       make -C $(srcdir)/doc/ uninstall
+       ( cd $(srcdir)/doc/ && make uninstall )
 
 $(srcdir)/configure: $(srcdir)/configure.in
        autoconf
index c524dc32d71667d6b7d9792e00b6f5ad4c07f21d..4d00cd1d60ba13fa516b8555d42adeb62cc30d78 100644 (file)
--- a/Muttrc.in
+++ b/Muttrc.in
@@ -8,11 +8,11 @@ ignore "from " received content- mime-version status x-status message-id
 ignore sender references return-path lines
 
 # imitate the old search-body function
-macro index \eb '/~b '
+macro index \eb '/~b ' 'search in message bodies'
 
 # simluate the old url menu
-macro index \cb |urlview\n
-macro pager \cb |urlview\n
+macro index \cb |urlview\n 'call urlview to extract URLs out of a message'
+macro pager \cb |urlview\n 'call urlview to extract URLs out of a message'
 
 # If Mutt is unable to determine your sites domain name correctly, you can
 # set the default here.
@@ -55,7 +55,6 @@ macro pager \cb |urlview\n
 # set dsn_return=""
 # unset edit_headers
 # set editor=""
-# set empty_to="undisclosed-recipients"
 # set escape="~"
 # unset fast_reply
 # unset fcc_attach
diff --git a/NEWS b/NEWS
index bab7ea60604f8a3126ec9686991de4af24649c0f..ff4cb3a70b848d60ac1126732b425587af08b70d 100644 (file)
--- a/NEWS
+++ b/NEWS
-Announcing Mutt 0.91
-====================
+Major changes since 0.91.1
+--------------------------
 
-NOTE: PLEASE read the following list of changes carefully, especially the
-first couple entries related to changes in variables/commands and see the
-manual before posting questions.  Taking a little time to read this notice
-will significantly reduce the amount of confusion as to why some things
-might seem broken at first.
-
-Major changes since 0.89.1:
-
-- The matching for the send-hook, save-hook and fcc-hook commands has been
-  extended so that it understands Mutt's matching language (used for
-  searching and limits).  You may still use a "simple" regular expression,
-  but Mutt will expand that with the value of $default_hook (similar to
-  $simple_search).  Additionally, all hooks are now executed in the order
-  they appear in your .muttrc instead of first doing `to', then `cc'.
-
-- new config command `score' which allows you to assign a numerical value to
-  a message based upon header information (similar to scoring in slrn).  the
-  score can be displed in $hdr_format with %N, you can sort by `score' and
-  you can match messages with a certain score (or range) with the `~n'
-  operator
-
-- new variable $beep_new which causes Mutt to beep when new mail is
-  delivered to a mailbox specified by the `mailboxes' command
-
-- new sort method `to' for sorting by who messages are addressed to
-
-- new variable $meta_key which causes Mutt to interpet keystrokes with the
-  hi bit set as ESC plus the key with the hi bit stripped (eg.  ALT-x will
-  get interpetted as "\ex")
-
-- new variable $sort_alias which controls the order the aliases appear in
-  the menu (may be either "alias" or "address")
-
-- new variable $alias_format to control the way the aliases are displayed in
-  the alias menu
+- additional format for $hdr_format
+       %L      displays the total size of all visible messages in a
+               limited view
+       %<fmt>  displays current time using strftime(fmt)
 
 - additional operators to the pattern matching lanauge:
-       ~S              superseded messages
-       ~E              expired messages
-       ~p              personal mail (finds $alternates in to: or cc:)
-       ~P              mail from you (finds $alternates in from: or sender:)
-       ~l              list mail (finds `lists' in to: or cc:)
-       ~L<pattern>     finds <pattern> in to:, cc:, from: or sender:
-       ~C<pattern>     finds <pattern> in to: or cc:
-
-- additional formats for $hdr_format
-       %N      displays the message score
-       %(fmt)  displayes the message's received time using strftime()
-
-- additional formats for $status_format
-       %P      percentage of menu seen
-       %S      current value of $sort_aux (%s no longer displays $sort_aux)
-       %o      number of old messages
-       %u      number of unread messages
-
-- new configure option `--enable-exact-address' which causes Mutt to rewrite
-  addresses in the same format they were parsed instead of rewriting them in
-  the form `Name <user@host>'
-
-- new command line argument `-e' which allows you to specify configuration
-  commands to be executed *after* your .muttrc is parsed
-  (eg.  mutt -e 'set edit_hdrs' mutt-dev)
-
-- you can now use `mono <object> normal' to set to normal attribute
-
-- new function `search-opposite' which searches for the current search
-  pattern in the opposition direction from the previous search
-
-Mutt's primary distribution point is ftp://ftp.cs.hmc.edu/pub/me/mutt.
-See the Mutt Home Page (http://www.cs.hmc.edu/~me/mutt/) for mirror sites.
-
-Bug reports should be sent to the Mutt User's Mailing List
-<mutt-users@cs.hmc.edu>.
-
-Michael Elkins <me@cs.hmc.edu>
-April 10, 1998
+       ~B<pattern>     finds pattern anywhere in the message (more
+                       efficient than ~h %s | ~b %s
+       ~z<size>        finds messages of size <size>
+                       E.g. 
+                        ~z<10k #finds messages smaller than 10KB
+                        ~z>10k #finds messages larger than 10KB
+                        ~z10k  #finds messages exactly 10KB in length
+                        
+
+- the $hdr_format variable is renamed to $index_format
+  $hdr_format is still accepted for backwards compatibility
+
+- new variable $folder_format to display entries in the 'browser' menu.
+
+- new variable $followup_to to control generation of Mail-Followup-To
+  field. You can edit this field and Mutt will not overwrite it.
+
+- new variable $sendmail_wait
+
+  Specifies the number of seconds to wait for the ``sendmail'' process
+  to finish before giving up and putting delivery in the background.
+
+  Mutt interprets the value of this variable as follows:
+
+  >0      number of seconds to wait for sendmail to finish before continuing
+  0       wait forever for sendmail to finish
+  <0      always put sendmail in the background without waiting
+
+  Note that if you specify a value other than 0, the output of the child
+  process will be put in a temporary file.  If there is some error, you
+  will be informed as to where to find the output.
+
+- Variable $sendmail_bounce has been removed. Mutt now passes all
+  recipients on the command line for normal sending. 
+
+- new variable $query_command
+  Adds support for querying an external database for email addresses.
+
+- The $forward_decode variable has been removed. This has been split into 2
+  variables
+
+  $forward_decode - used when $mime_fwd is not set
+  $mime_forward_decode - used when $mime_fwd is set
+
+- new variable $wrap_search. This controls whether searches wrap around the
+  end of the mailbox.
+  
+  When set, searches will wrap around the first (or last) message. When
+  unset, searches will not wrap
+
+
+- New command 'reset' to reset variables to their default compile-time
+  definitions. When used with special keyword 'all', all variables are
+  reset to their default values. When used with the 'set' command and the
+  variable name prefixed with '&', this has the same behaviour as the
+  'reset' command.
+
+  Eg. 
+   reset move
+   reset all
+   set &move
+   set &all
+
+- Function key names used in muttrc need to be enclosed in <>. 
+  Function keys can be used in macros also.
+  
+  Eg. 
+   macro index Y *<PageUp>
+   bind index <down> next-entry
+
+- You can now delete a message's attachments by pressing 'd' (delete-entry)
+  on the attachment in the attachment menu.
+  
+- You can now color index menu entries using the pattern matching language.
+  The 'uncolor' command resets the entry to its default color. The '*'
+  token can be used to reset all index entries to their default colors.
+  
+  Eg.
+    color index blue white ~fvikas
+    color index red white ~z>100k
+    uncolor index ~fvikas
+    uncolor index *
+    
+- mailboxes specified in save-hooks can be %-expanded using $header_format
+
+- the default save mailbox no longer looks at defined `lists'. To get the
+  old behaviour, use
+    save-hook ~l %B
+
+- optional strings in format strings have been extended to allow for an
+  `else' clause.  the new syntax is:
+        %?<testchar>?<if-string>&<else-string>?
+  or if no `else' clause is desired (backwards compatibility):
+        %?<testchar>?<if-string>?
+
+- If new mail is delivered to a folder when Mutt is displaying a limited
+  view of the folder, it is added to the limited view only if it satisfies
+  the current limit criteria.
+
+- the <Tab> key on the command-line now completes commands and variable
+  names. The longest non-ambiguous part is put on the command-line.
+  Entering additional text and using <Tab> will perform completion again.
diff --git a/OPS b/OPS
index 049e89228ef947fe3b09dad1992e3313b74cb190..39282f6ded8364390612f3655a0c8dc52c6f367c 100644 (file)
--- a/OPS
+++ b/OPS
@@ -4,9 +4,11 @@ OP_ATTACH_VIEW_TEXT "view attachment as text"
 OP_BOTTOM_PAGE "move to the bottom of the page"
 OP_BOUNCE_MESSAGE "remail a message to another user"
 OP_BROWSER_NEW_FILE "select a new file in this directory"
+OP_BROWSER_VIEW_FILE "view file"
 OP_CHANGE_DIRECTORY "change directories"
 OP_CHECK_NEW "check mailboxes for new mail"
 OP_COMPOSE_ATTACH_FILE "attach a file(s) to this message"
+OP_COMPOSE_ATTACH_MESSAGE "attach message(s) to this message"
 OP_COMPOSE_EDIT_BCC "edit the BCC list"
 OP_COMPOSE_EDIT_CC "edit the CC list"
 OP_COMPOSE_EDIT_DESCRIPTION "edit attachment description"
@@ -27,6 +29,7 @@ OP_COMPOSE_POSTPONE_MESSAGE "save this message to send later"
 OP_COMPOSE_RENAME_FILE "rename/move an attached file"
 OP_COMPOSE_SEND_MESSAGE "send the message"
 OP_COMPOSE_TOGGLE_UNLINK "toggle whether to delete file after sending it"
+OP_COMPOSE_UPDATE_ENCODING "update an attachment's encoding info"
 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"
@@ -132,6 +135,7 @@ OP_TAG_SUBTHREAD "tag the current subthread"
 OP_TAG_THREAD "tag the current thread"
 OP_TOGGLE_NEW "toggle a message's 'new' flag"
 OP_TOGGLE_WRITE "toggle whether the mailbox will be rewritten"
+OP_TOGGLE_MAILBOXES "toggle wether to browse mailboxes or all files"
 OP_TOP_PAGE "move to the top of the page"
 OP_UNDELETE "undelete the current entry"
 OP_UNDELETE_THREAD "undelete all messages in thread"
diff --git a/README b/README
index 90c2a9691c348135cb74423f44370f95530c4612..4f9995cf918b1c6bca4006e4d3c9acf7def1c1ee 100644 (file)
--- a/README
+++ b/README
@@ -1,18 +1,38 @@
-README for mutt-0.90i
-=======================
+README for mutt-0.93i
+=====================
 
-Installation instructructions are detailed in ``INSTALL''.
+Installation instructions are detailed in ``INSTALL''.
 
-The user manual is in doc/manual.txt.
+The user manual is in doc/manual.txt.  A list of major
+changes since the last public version can be found under
+NEWS.
 
 PGP users please read doc/PGP-Notes.txt before proceeding.
 
-For more information, see the Mutt home page,
-http://www.cs.hmc.edu/~me/mutt/index.html.
+For more information, see the Mutt home page:
 
-The primary distribution point for Mutt is
-ftp://ftp.cs.hmc.edu/pub/me/mutt.  See the home page for
-mirror sites.
+ http://www.cs.hmc.edu/~me/mutt/index.html
 
-Michael Elkins <me@cs.hmc.edu>, January 22, 1998
-Thomas Roessler <roessler@guug.de>, February 3, 1998
+The primary distribution points for Mutt are:
+
+ ftp://riemann.iam.uni-bonn.de/pub/mutt/
+ ftp://ftp.guug.de/pub/mutt
+
+Mirror sites for the pgp-enabled version of mutt can be
+found at the following places:
+
+ ftp://ftp.gbnet.net/pub/mutt-international/
+ ftp://ftp.fu-berlin.de/pub/unix/mail/mutt/
+ ftp://pgp.rasip.fer.hr/pub/mutt/international/
+ ftp://ftp.gwdg.de/pub/unix/mail/mutt
+ ftp://ftp.iks-jena.de/pub/mitarb/lutz/crypt/software/pgp/mutt
+ ftp://ftp.lip6.fr/pub/unix/mail/mutt
+ ftp://ftp.arch.pwr.wroc.pl/pub/mutt/
+ ftp://ftp.uib.no/pub/mutt
+
+Mirror sites for the pgp-disabled version:
+
+ ftp://ftp.ewd.3com.com/pub/mutt/
+  
+
+Thomas Roessler <roessler@guug.de>, July 10, 1998
diff --git a/TODO b/TODO
index 8b4c410db9073f6252dfad7b36a1ce4cddebf6a7..11b0c84be4d1c7b2c5a06d4dde1caf208ed4678a 100644 (file)
--- a/TODO
+++ b/TODO
-- Other than multipart/mixed and PGP/MIME, Mutt should allow the user to
-  specify what to do with other types of multipart messages (i.e., so a user
-  can deal with S/MIME messages reasonably)
+This list tries to cover the open problems we have with
+mutt.  It's compiled from the old BUGS and TODO files in
+the distribution, from recent mutt-dev postings, and from
+other messages relating to problems and/or wishes with
+mutt.
+
+I'm listing the problems in approximate order of priority.
+
+- Fix the "unexpected EXPUNGE" IMAP bug.
+
+- Ask IMAP servers for hierarchy separators. (-> Brandon's
+  note from Aug 18)
+
+- Apply proper quoting when sending imap "ASTRING"s.  (->
+  John Prevost wrote something on this on Aug 19).
+
+  
+- When using EXACT_ADDRESS, the following memory leak may
+  occur (insure++ output):
+
+| [rfc822.c:400] **LEAK_ASSIGN**
+| >>         last->val = mutt_substrdup (begin, s);
+| 
+|   Memory leaked due to pointer reassignment: (void *) malloc(siz)
+| 
+|   Lost block : 0x082e7da0 thru 0x082e7db6 (23 bytes)
+|                (void *) malloc(siz), allocated at:
+|                      safe_malloc()  lib.c, 283
+|                   mutt_substrdup()  lib.c, 861
+|             rfc822_parse_adrlist()  rfc822.c, 377
+|          mutt_read_rfc822_header()  parse.c, 1112
+|               mbox_parse_mailbox()  mbox.c, 272
+|                mbox_open_mailbox()  mbox.c, 390
+|                  mx_open_mailbox()  mx.c, 598
+|                  mutt_index_menu()  curs_main.c, 874
+| 
+|   Stack trace where the error occurred:
+|             rfc822_parse_adrlist()  rfc822.c, 400
+|          mutt_read_rfc822_header()  parse.c, 1112
+|               mbox_parse_mailbox()  mbox.c, 272
+|                mbox_open_mailbox()  mbox.c, 390
+|                  mx_open_mailbox()  mx.c, 598
+|                  mutt_index_menu()  curs_main.c, 874
+|                             main()  main.c, 635
+| 
+| ************************** INSURE SUMMARY ************************* v4.1 **
+| *   Program      : mutt                                                   *
+| *   Arguments    :                                                        *
+| *   Directory    : /home/olga/Mail                                        *
+| *   Compiled on  : Aug 18, 1998  19:52:01                                 *
+| *   Run on       : Aug 18, 1998  19:57:08                                 *
+| *   Elapsed time : 00:04:26                                               *
+| *   Malloc HWM   : 855,258 bytes (835K)                                   *
+| ***************************************************************************
+| 
+| PROBLEM SUMMARY - by type
+| ===============
+| 
+|           Problem                Reported      Suppressed
+|           -------------------------------------------------
+|           LEAK_ASSIGN                  1                1
+|           RETURN_FAILURE               0               70
+|           USER_ERROR                   0               24
+|           -------------------------------------------------
+|           TOTAL                        1               95
+|           -------------------------------------------------
+| 
+| PROBLEM SUMMARY - by location
+| ===============
+| 
+| LEAK_ASSIGN: Memory leaked due to pointer reassignment, 1 unique occurrence
+|          2 at rfc822.c, 400
+| 
+  
+- In the "attachment" menu, assume this:
+
+       1 [text/plain, 7bit, 1.1K]           <no description>
+       2 [message/rfc822, 7bit, 6.1K]       A test message
+       3 [text/plain, 7bit, 0.1K]           |-><no description>
+       4 [message/rfc822, base64, 2.5K]     |-><no description>
+       5 [message/rfc822, base64, 2.7K]     `-><no description>
+
+  (please note the "message/rfc822" attachments encoded as
+  Base64; that's illegal, but Sun's Mailtool sends that
+  kind of messages); then go to, say, attachment "4",
+  delete it, and go to the main menu; you won't be able to
+  quit the mailbox (ok, 'x' works, but 'q' doesn't).
+
+  The problem here lies in the fact that mutt uses mailbox
+  handling functions to access message/rfc822 type
+  attachments.  We'd need to perform an additional
+  decoding step before using these functions to fix this
+  bug.
+
+  Please note that mutt's just assuming RFC-compliant mail
+  here.  Fixing this stuff may become a PITA.
+
+
+
+- mailbox resync code for mh and maildir mailboxes.  This
+  will most probably help to fix the following problems:
+
+  In maildir folders, the cursor will jump to an
+  unpredictible message when new mail arrives.
+
+  When accessing maildir folders with two mutts in
+  parallel, messages which have been marked read (and thus
+  moved to the cur/ subdirectory) by one of the mutts
+  can't be read from the other one.
+
+
+- Re-visit nametemplate support.  Currently, we use
+  symbolic links in our temporary directory for this.
+
+
+- BODY struct should probably have a pointer to its
+  corresponding HEADER struct.  this is needed for
+  mh/maildir mailboxes so the correct pathname can be
+  found.  Or perhaps all we need is a .hdr member of the
+  STATE struct so that all of the MIME handlers can look
+  up the corresponding HEADERs if need be?
 
 - option to not include attachments in replies
 
 - handle message/external-body in some fashion
 
 - handle message/partial reconstruction
-
-- not possible to view the header of a single part message which contains
-  something that requires a mailcap entry to view
-
-- need to clean up the error recovery when running out of space when syncing
-  a mbox/mmdf mailbox
-
-- BODY struct should probably have a pointer to its corresponding HEADER
-  struct.  this is needed for mh/maildir mailboxes so the correct pathname
-  can be found.  Or perhaps all we need is a .hdr member of the STATE struct
-  so that all of the MIME handlers can look up the corresponding HEADERs if
-  need be?
-
-- mailbox resync code for mh and maildir mailboxes
-
-- fold long user-defined header fields
-
-- history classes
-
-- document honored environment variables
-
-- add -v flag to pass to sendmail...
-
-- ordered tag
-
-- rfc822 parser needs to do something with the @host1@host2: portion of the
-  route-addr
-
-- command completion for `enter-command'
-
-- new forward command to include first attachment in the editor and attach
-  other attachments to the message
-
-- adjust the names of *adr() and *adrlist() and calling routines for
-  consistency
-
-- mbox-hook entries should override $move?
-
-- add a preserved flag to messages
-
+  
+- not possible to view the header of a single part message
+  which contains something that requires a mailcap entry to
+  view
+  
index 1e79d39a7ccdef5bc3924f00fb286a566fa75b29..ab805047cec4693e7d5c141623a148bdee27c924 100644 (file)
@@ -48,9 +48,6 @@
 /* Where new mail is spooled */
 #undef MAILPATH
 
-/* Should I just use the domain name? (--enable-hidden-host) */
-#undef HIDDEN_HOST
-
 /* Does your system have the srand48() suite? */
 #undef HAVE_SRAND48
 
 
 /* Does your system have the vsnprintf() call? */
 #undef HAVE_VSNPRINTF
+
+/* Does your system have the fchdir() call? */
+#undef HAVE_FCHDIR
index e14ca9b1d7f5f6076887892c0e498671ab5c3472..9334796b55b7a1bed39d5163087b167f1d6fb743 100644 (file)
@@ -18,6 +18,7 @@
 
 #include "mutt.h"
 #include "mutt_menu.h"
+#include "mapping.h"
 #include "sort.h"
 
 #include <string.h>
diff --git a/alias.c b/alias.c
index d927fbc5778435000c5086d6f76d3b361e7c475b..84dcc04cd9818021090bada1015de34f5c167574 100644 (file)
--- a/alias.c
+++ b/alias.c
@@ -18,6 +18,7 @@
 
 #include "mutt.h"
 #include "mutt_regex.h"
+#include "mutt_curses.h"
 
 #include <pwd.h>
 #include <string.h>
@@ -37,7 +38,8 @@ static ADDRESS *mutt_expand_aliases_r (ADDRESS *a, LIST **expn)
   ADDRESS *head = NULL, *last = NULL, *t, *w;
   LIST *u;
   char i;
-
+  const char *fqdn;
+  
   while (a)
   {
     if (!a->group && !a->personal && a->mailbox && strchr (a->mailbox, '@') == NULL)
@@ -90,8 +92,7 @@ static ADDRESS *mutt_expand_aliases_r (ADDRESS *a, LIST **expn)
            *p = 0;
          a->personal = safe_strdup (buffer);
 #ifdef EXACT_ADDRESS
-         free (a->val);
-         a->val = NULL;
+         FREE (&a->val);
 #endif
        }
       }
@@ -108,10 +109,10 @@ static ADDRESS *mutt_expand_aliases_r (ADDRESS *a, LIST **expn)
     last->next = NULL;
   }
 
-  if (option (OPTUSEDOMAIN) && Fqdn[0] != '@')
+  if (option (OPTUSEDOMAIN) && (fqdn = mutt_fqdn(1)))
   {
     /* now qualify all local addresses */
-    rfc822_qualify (head, Fqdn);
+    rfc822_qualify (head, fqdn);
   }
 
   return (head);
@@ -205,13 +206,19 @@ void mutt_create_alias (ENVELOPE *cur, ADDRESS *iadr)
   else
     buf[0] = 0;
 
-  if (mutt_get_field ("Address: ", buf, sizeof (buf), 0) != 0 || !buf[0])
+  do
   {
-    mutt_free_alias (&new);
-    return;
+    if (mutt_get_field ("Address: ", buf, sizeof (buf), 0) != 0 || !buf[0])
+    {
+      mutt_free_alias (&new);
+      return;
+    }
+    
+    if((new->addr = rfc822_parse_adrlist (new->addr, buf)) == NULL)
+      BEEP ();
   }
-  new->addr = rfc822_parse_adrlist (new->addr, buf);
-
+  while(new->addr == NULL);
+  
   if (adr && adr->personal && !mutt_is_mail_list (adr))
     strfcpy (buf, adr->personal, sizeof (buf));
   else
@@ -366,28 +373,39 @@ int mutt_alias_complete (char *s, size_t buflen)
   return 1;
 }
 
-/* returns TRUE if the given address belongs to the user. */
-int mutt_addr_is_user (ADDRESS *addr)
+static int string_is_address(const char *str, const char *u, const char *d)
 {
   char buf[LONG_STRING];
+  
+  snprintf(buf, sizeof(buf), "%s@%s", NONULL(u), NONULL(d));
+  if (strcasecmp(str, buf) == 0)
+    return 1;
+  
+  return 0;
+}
 
+/* returns TRUE if the given address belongs to the user. */
+int mutt_addr_is_user (ADDRESS *addr)
+{
   /* NULL address is assumed to be the user. */
   if (!addr)
     return 1;
   if (!addr->mailbox)
     return 0;
-  if (strcasecmp (addr->mailbox, Username) == 0)
+
+  if (strcasecmp (addr->mailbox, NONULL(Username)) == 0)
     return 1;
-  snprintf (buf, sizeof (buf), "%s@%s", Username, Hostname);
-  if (strcasecmp (addr->mailbox, buf) == 0)
+  if(string_is_address(addr->mailbox, Username, Hostname))
     return 1;
-  snprintf (buf, sizeof (buf), "%s@%s", Username, Fqdn);
-  if (strcasecmp (addr->mailbox, buf) == 0)
+  if(string_is_address(addr->mailbox, Username, mutt_fqdn(0)))
+    return 1;
+  if(string_is_address(addr->mailbox, Username, mutt_fqdn(1)))
     return 1;
 
   if (Alternates.pattern &&
       regexec (Alternates.rx, addr->mailbox, 0, NULL, 0) == 0)
     return 1;
+  
   return 0;
 }
 
index 4345d093c248d7cfb2ff3af0582519393325b1fb..d0a887e1dda3542818eef1a6335c7cfae2c3337e 100644 (file)
--- a/attach.c
+++ b/attach.c
 #include "rfc1524.h"
 #include "mime.h"
 #include "pager.h"
+#include "mailbox.h"
+#include "copy.h"
+#include "mx.h"
+
+#ifdef _PGPPATH
+#include "pgp.h"
+#endif
 
 #include <ctype.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <sys/wait.h>
 #include <sys/stat.h>
+#include <fcntl.h>
 #include <string.h>
 #include <errno.h>
 
@@ -37,14 +45,16 @@ int mutt_compose_attachment (BODY *a)
 {
   char type[STRING];
   char command[STRING];
+  char newfile[_POSIX_PATH_MAX] = "";
   rfc1524_entry *entry = rfc1524_new_entry ();
-
-  snprintf (type, sizeof (type), "%s/%s", TYPE (a->type), a->subtype);
+  short unlink_newfile = 0;
+  int rc = 0;
+  
+  snprintf (type, sizeof (type), "%s/%s", TYPE (a), a->subtype);
   if (rfc1524_mailcap_lookup (a, type, entry, M_COMPOSE))
   {
     if (entry->composecommand || entry->composetypecommand)
     {
-      char newfile[_POSIX_PATH_MAX] = "";
 
       if (entry->composetypecommand)
        strfcpy (command, entry->composetypecommand, sizeof (command));
@@ -55,19 +65,17 @@ int mutt_compose_attachment (BODY *a)
       {
        dprint(1, (debugfile, "oldfile: %s\t newfile: %s\n",
                                  a->filename, newfile));
-       if (!mutt_rename_file (a->filename, newfile))
+       if (symlink (a->filename, newfile) == -1)
        {
          if (!mutt_yesorno ("Can't match nametemplate, continue?", 1))
-           return 0;
-       }
-       else
-       {
-         safe_free ((void **) &a->filename);
-         a->filename = safe_strdup (newfile);
+           goto bailout;
        }
+       unlink_newfile = 1;
       }
-
-      if (rfc1524_expand_command (a, a->filename, type,
+      else
+       strfcpy(newfile, a->filename, sizeof(newfile));
+      
+      if (rfc1524_expand_command (a, newfile, type,
                                      command, sizeof (command)))
       {
        /* For now, editing requires a file, no piping */
@@ -86,7 +94,7 @@ int mutt_compose_attachment (BODY *a)
          if ((fp = safe_fopen (a->filename, "r")) == NULL)
          {
            mutt_perror ("Failure to open file to parse headers.");
-           return 0;
+           goto bailout;
          }
 
          b = mutt_read_mime_header (fp, 0);
@@ -117,7 +125,7 @@ int mutt_compose_attachment (BODY *a)
            if ((tfp = safe_fopen (tempfile, "w")) == NULL)
            {
              mutt_perror ("Failure to open file to strip headers.");
-             return 0;
+             goto bailout;
            }
            mutt_copy_stream (fp, tfp);
            fclose (fp);
@@ -138,8 +146,15 @@ int mutt_compose_attachment (BODY *a)
     return 1;
   }
 
+  rc = 1;
+  
+  bailout:
+  
+  if(unlink_newfile)
+    unlink(newfile);
+
   rfc1524_free_entry (&entry);
-  return 1;
+  return rc;
 }
 
 /* 
@@ -151,18 +166,20 @@ int mutt_compose_attachment (BODY *a)
  * Returns 1 if editor found, 0 if not (useful to tell calling menu to
  * redraw)
  */
-int mutt_edit_attachment (BODY *a, int opt)
+int mutt_edit_attachment (BODY *a)
 {
   char type[STRING];
   char command[STRING];
+  char newfile[_POSIX_PATH_MAX] = "";
   rfc1524_entry *entry = rfc1524_new_entry ();
-
-  snprintf (type, sizeof (type), "%s/%s", TYPE (a->type), a->subtype);
+  short unlink_newfile = 0;
+  int rc = 0;
+  
+  snprintf (type, sizeof (type), "%s/%s", TYPE (a), a->subtype);
   if (rfc1524_mailcap_lookup (a, type, entry, M_EDIT))
   {
     if (entry->editcommand)
     {
-      char newfile[_POSIX_PATH_MAX] = "";
 
       strfcpy (command, entry->editcommand, sizeof (command));
       if (rfc1524_expand_filename (entry->nametemplate,
@@ -170,19 +187,17 @@ int mutt_edit_attachment (BODY *a, int opt)
       {
        dprint(1, (debugfile, "oldfile: %s\t newfile: %s\n",
                                  a->filename, newfile));
-       if (mutt_rename_file (a->filename, newfile))
+       if (symlink (a->filename, newfile) == -1)
        {
          if (!mutt_yesorno ("Can't match nametemplate, continue?", 1))
-           return 0;
-       }
-       else
-       {
-         safe_free ((void **) &a->filename);
-         a->filename = safe_strdup (newfile);
+           goto bailout;
        }
+       unlink_newfile = 1;
       }
+      else
+       strfcpy(newfile, a->filename, sizeof(newfile));
 
-      if (rfc1524_expand_command (a, a->filename, type,
+      if (rfc1524_expand_command (a, newfile, type,
                                      command, sizeof (command)))
       {
        /* For now, editing requires a file, no piping */
@@ -198,8 +213,8 @@ int mutt_edit_attachment (BODY *a, int opt)
   else if (a->type == TYPETEXT)
   {
     /* On text, default to editor */
-    mutt_edit_file (strcmp ("builtin", Editor) == 0 ? Visual : Editor, 
-                   a->filename);
+    mutt_edit_file ((!Editor || strcmp ("builtin", Editor) == 0) ? 
+                   NONULL(Visual) : NONULL(Editor), newfile);
   }
   else
   {
@@ -208,8 +223,15 @@ int mutt_edit_attachment (BODY *a, int opt)
     return 0;
   }
 
+  rc = 1;
+  
+  bailout:
+  
+  if(unlink_newfile)
+    unlink(newfile);
+  
   rfc1524_free_entry (&entry);
-  return 1;
+  return rc;
 }
 
 int mutt_is_autoview (char *type)
@@ -242,15 +264,19 @@ int mutt_view_attachment (FILE *fp, BODY *a, int flag)
   char type[STRING];
   char command[STRING];
   char descrip[STRING];
+  char *fname;
   rfc1524_entry *entry = NULL;
   int rc = -1;
-
-  is_message = (a->type == TYPEMESSAGE && a->subtype &&
-                 (!strcasecmp (a->subtype,"rfc822") ||
-                  !strcasecmp (a->subtype, "news")));
+  int unlink_tempfile = 0;
+  
+  is_message = mutt_is_message_type(a->type, a->subtype);
+#ifdef _PGPPATH
+  if (is_message && (a->hdr->pgp & PGPENCRYPT) && !pgp_valid_passphrase())
+    return (rc);
+#endif /* _PGPPATH */
   use_mailcap = (flag == M_MAILCAP ||
                (flag == M_REGULAR && mutt_needs_mailcap (a)));
-  snprintf (type, sizeof (type), "%s/%s", TYPE (a->type), a->subtype);
+  snprintf (type, sizeof (type), "%s/%s", TYPE (a), a->subtype);
   
   if (use_mailcap)
   {
@@ -279,13 +305,21 @@ int mutt_view_attachment (FILE *fp, BODY *a, int flag)
     }
     strfcpy (command, entry->command, sizeof (command));
     
-    if (rfc1524_expand_filename (entry->nametemplate, a->filename,
+    if (fp)
+    {
+      fname = safe_strdup (a->filename);
+      mutt_sanitize_filename (fname);
+    }
+    else
+      fname = a->filename;
+
+    if (rfc1524_expand_filename (entry->nametemplate, fname,
                                 tempfile, sizeof (tempfile)))
     {
       if (fp == NULL)
       {
        /* send case: the file is already there */
-       if (mutt_rename_file (a->filename, tempfile))
+       if (symlink (a->filename, tempfile) == -1)
        {
          if (mutt_yesorno ("Can't match nametemplate, continue?", 1) == M_YES)
            strfcpy (tempfile, a->filename, sizeof (tempfile));
@@ -293,19 +327,17 @@ int mutt_view_attachment (FILE *fp, BODY *a, int flag)
            goto return_error;
        }
        else
-       {
-         safe_free ((void **) &a->filename);
-         a->filename = safe_strdup (tempfile);
-       }
+         unlink_tempfile = 1;
       }
     }
     else if (fp == NULL) /* send case */
       strfcpy (tempfile, a->filename, sizeof (tempfile));
-
+    
     if (fp)
     {
       /* recv case: we need to save the attachment to a file */
-      if (mutt_save_attachment (fp, a, tempfile, 0) == -1)
+      FREE (&fname);
+      if (mutt_save_attachment (fp, a, tempfile, 0, NULL) == -1)
        goto return_error;
     }
 
@@ -320,7 +352,7 @@ int mutt_view_attachment (FILE *fp, BODY *a, int flag)
     {
       /* recv case */
       strfcpy (pagerfile, a->filename, sizeof (pagerfile));
-      mutt_adv_mktemp (pagerfile);
+      mutt_adv_mktemp (pagerfile, sizeof(pagerfile));
     }
     else
       mutt_mktemp (pagerfile);
@@ -402,7 +434,7 @@ int mutt_view_attachment (FILE *fp, BODY *a, int flag)
     if (flag == M_AS_TEXT)
     {
       /* just let me see the raw data */
-      if (mutt_save_attachment (fp, a, pagerfile, 0))
+      if (mutt_save_attachment (fp, a, pagerfile, 0, NULL))
        goto return_error;
     }
     else
@@ -448,6 +480,9 @@ int mutt_view_attachment (FILE *fp, BODY *a, int flag)
     rfc1524_free_entry (&entry);
   if (fp && tempfile[0])
     mutt_unlink (tempfile);
+  else if (unlink_tempfile)
+    unlink(tempfile);
+
   if (pagerfile[0])
     mutt_unlink (pagerfile);
 
@@ -457,15 +492,13 @@ int mutt_view_attachment (FILE *fp, BODY *a, int flag)
 /* returns 1 on success, 0 on error */
 int mutt_pipe_attachment (FILE *fp, BODY *b, const char *path, char *outfile)
 {
-  STATE o;
   pid_t thepid;
-
-  memset (&o, 0, sizeof (STATE));
+  int out = -1;
 
   if (outfile && *outfile)
-    if ((o.fpout = safe_fopen (outfile, "w")) == NULL)
+    if ((out = safe_open (outfile, O_CREAT | O_EXCL | O_WRONLY)) < 0)
     {
-      mutt_perror ("fopen");
+      mutt_perror ("open");
       return 0;
     }
 
@@ -480,7 +513,7 @@ int mutt_pipe_attachment (FILE *fp, BODY *b, const char *path, char *outfile)
     memset (&s, 0, sizeof (STATE));
 
     if (outfile && *outfile)
-      thepid = mutt_create_filter (path, &s.fpout, &o.fpin, NULL);
+      thepid = mutt_create_filter_fd (path, &s.fpout, NULL, NULL, -1, out, -1);
     else
       thepid = mutt_create_filter (path, &s.fpout, NULL, NULL);
 
@@ -497,12 +530,16 @@ int mutt_pipe_attachment (FILE *fp, BODY *b, const char *path, char *outfile)
     if ((ifp = fopen (b->filename, "r")) == NULL)
     {
       mutt_perror ("fopen");
-      fclose (o.fpout);
+      if (outfile && *outfile)
+      {
+       close (out);
+       unlink (outfile);
+      }
       return 0;
     }
 
     if (outfile && *outfile)
-      thepid = mutt_create_filter (path, &ofp, &o.fpin, NULL);
+      thepid = mutt_create_filter_fd (path, &ofp, NULL, NULL, -1, out, -1);
     else
       thepid = mutt_create_filter (path, &ofp, NULL, NULL);
 
@@ -512,11 +549,7 @@ int mutt_pipe_attachment (FILE *fp, BODY *b, const char *path, char *outfile)
   }
 
   if (outfile && *outfile)
-  {
-    mutt_copy_stream (o.fpin, o.fpout);
-    fclose (o.fpin);
-    fclose (o.fpout);
-  }
+    close (out);
 
   if (mutt_wait_filter (thepid) != 0 || option (OPTWAITKEY))
     mutt_any_key_to_continue (NULL);
@@ -524,31 +557,76 @@ int mutt_pipe_attachment (FILE *fp, BODY *b, const char *path, char *outfile)
 }
 
 /* returns 0 on success, -1 on error */
-int mutt_save_attachment (FILE *fp, BODY *m, char *path, int flags)
+int mutt_save_attachment (FILE *fp, BODY *m, char *path, int flags, HEADER *hdr)
 {
   if (fp)
   {
-    /* In recv mode, extract from folder and decode */
+    
+    /* recv mode */
 
-    STATE s;
-  
-    memset (&s, 0, sizeof (s));
-    if (flags == M_SAVE_APPEND)
-      s.fpout = safe_fopen (path, "a");
-    else
-      s.fpout = fopen (path, "w");
-    if (s.fpout == NULL)
+    if(hdr &&
+       m->hdr &&
+       m->encoding != ENCBASE64 &&
+       m->encoding != ENCQUOTEDPRINTABLE &&
+       mutt_is_message_type(m->type, m->subtype))
     {
-      mutt_perror ("fopen");
-      return (-1);
+      /* message type attachments are written to mail folders. */
+
+      char buf[HUGE_STRING];
+      HEADER *hn;
+      CONTEXT ctx;
+      MESSAGE *msg;
+      int chflags = 0;
+      int r = -1;
+      
+      hn = m->hdr;
+      hn->msgno = hdr->msgno; /* required for MH/maildir */
+      hn->read = 1;
+
+      fseek (fp, m->offset, 0);
+      if (fgets (buf, sizeof (buf), fp) == NULL)
+       return -1;
+      if (mx_open_mailbox(path, M_APPEND | M_QUIET, &ctx) == NULL)
+       return -1;
+      if ((msg = mx_open_new_message (&ctx, hn, is_from (buf, NULL, 0) ? 0 : M_ADD_FROM)) == NULL)
+      {
+       mx_close_mailbox(&ctx);
+       return -1;
+      }
+      if (ctx.magic == M_MBOX || ctx.magic == M_MMDF)
+       chflags = CH_FROM;
+      chflags |= (ctx.magic == M_MAILDIR ? CH_NOSTATUS : CH_UPDATE);
+      if ((r = _mutt_copy_message (msg->fp, fp, hn, hn->content, 0, chflags)) == 0)
+       mutt_message("Attachment saved.");
+       
+      mx_close_message (&msg);
+      mx_close_mailbox(&ctx);
+      return r;
     }
-    fseek ((s.fpin = fp), m->offset, 0);
-    mutt_decode_attachment (m, &s);
-
-    if (fclose (s.fpout) != 0)
+    else
     {
-      mutt_perror ("fclose");
-      return (-1);
+      /* In recv mode, extract from folder and decode */
+      
+      STATE s;
+      
+      memset (&s, 0, sizeof (s));
+      if (flags == M_SAVE_APPEND)
+       s.fpout = safe_fopen (path, "a");
+      else
+       s.fpout = fopen (path, "w");
+      if (s.fpout == NULL)
+      {
+       mutt_perror ("fopen");
+       return (-1);
+      }
+      fseek ((s.fpin = fp), m->offset, 0);
+      mutt_decode_attachment (m, &s);
+      
+      if (fclose (s.fpout) != 0)
+      {
+       mutt_perror ("fclose");
+       return (-1);
+      }
     }
   }
   else
@@ -590,6 +668,8 @@ int mutt_decode_save_attachment (FILE *fp, BODY *m, char *path,
 {
   STATE s;
   unsigned int saved_encoding = 0;
+  BODY *saved_parts = NULL;
+  HEADER *saved_hdr = NULL;
 
   memset (&s, 0, sizeof (s));
   s.flags = displaying ? M_DISPLAY : 0;
@@ -627,10 +707,12 @@ int mutt_decode_save_attachment (FILE *fp, BODY *m, char *path,
     m->length = st.st_size;
     m->encoding = ENC8BIT;
     m->offset = 0;
-    if (m->type == TYPEMESSAGE && m->subtype &&
-                 (!strcasecmp (m->subtype,"rfc822") ||
-                  !strcasecmp (m->subtype, "news")))
+    if (mutt_is_message_type(m->type, m->subtype))
+    {
+      saved_parts = m->parts;
+      saved_hdr = m->hdr;
       m->parts = mutt_parse_messageRFC822 (s.fpin, m);
+    }
   }
   else
     s.fpin = fp;
@@ -642,8 +724,12 @@ int mutt_decode_save_attachment (FILE *fp, BODY *m, char *path,
   {
     m->length = 0;
     m->encoding = saved_encoding;
-    if (m->parts)
-      mutt_free_body (&m->parts);
+    if (saved_parts)
+    {
+      mutt_free_header (&m->hdr);
+      m->parts = saved_parts;
+      m->hdr = saved_hdr;
+    }
     fclose (s.fpin);
   }
 
@@ -663,8 +749,9 @@ int mutt_print_attachment (FILE *fp, BODY *a)
   char type[STRING];
   pid_t thepid;
   FILE *ifp, *fpout;
-
-  snprintf (type, sizeof (type), "%s/%s", TYPE (a->type), a->subtype);
+  short unlink_newfile = 0;
+  
+  snprintf (type, sizeof (type), "%s/%s", TYPE (a), a->subtype);
 
   if (rfc1524_mailcap_lookup (a, type, NULL, M_PRINT)) 
   {
@@ -679,9 +766,7 @@ int mutt_print_attachment (FILE *fp, BODY *a)
     {
       if (!fp)
       {
-       /* only attempt file move in send mode */
-
-       if (mutt_rename_file (a->filename, newfile))
+       if (symlink(a->filename, newfile) == -1)
        {
          if (mutt_yesorno ("Can't match nametemplate, continue?", 1) != M_YES)
          {
@@ -691,16 +776,13 @@ int mutt_print_attachment (FILE *fp, BODY *a)
          strfcpy (newfile, a->filename, sizeof (newfile));
        }
        else
-       {
-         safe_free ((void **)&a->filename);
-         a->filename = safe_strdup (newfile);
-       }
+         unlink_newfile = 1;
       }
     }
 
     /* in recv mode, save file to newfile first */
     if (fp)
-      mutt_save_attachment (fp, a, newfile, 0);
+      mutt_save_attachment (fp, a, newfile, 0, NULL);
 
     strfcpy (command, entry->printcommand, sizeof (command));
     piped = rfc1524_expand_command (a, newfile, type, command, sizeof (command));
@@ -732,6 +814,8 @@ int mutt_print_attachment (FILE *fp, BODY *a)
 
     if (fp)
       mutt_unlink (newfile);
+    else if (unlink_newfile)
+      unlink(newfile);
 
     rfc1524_free_entry (&entry);
     return (1);
@@ -739,7 +823,9 @@ int mutt_print_attachment (FILE *fp, BODY *a)
 
   if (!strcasecmp ("text/plain", a->subtype) ||
       !strcasecmp ("application/postscript", a->subtype))
-    return (mutt_pipe_attachment (fp, a, PrintCmd, NULL));
+  {
+    return (mutt_pipe_attachment (fp, a, NONULL(PrintCmd), NULL));
+  }
   else if (mutt_can_decode (a))
   {
     /* decode and print */
@@ -752,7 +838,7 @@ int mutt_print_attachment (FILE *fp, BODY *a)
       if ((ifp = fopen (newfile, "r")) != NULL)
       {
        endwin ();
-       thepid = mutt_create_filter (PrintCmd, &fpout, NULL, NULL);
+       thepid = mutt_create_filter (NONULL(PrintCmd), &fpout, NULL, NULL);
        mutt_copy_stream (ifp, fpout);
        fclose (ifp);
        fclose (fpout);
index 46e374dcee7fbe497bfce29f370e057163794966..32e9d0d510eea7ceb47b016af6ba0a46ca8bafa3 100644 (file)
--- a/attach.h
+++ b/attach.h
@@ -20,7 +20,7 @@
 
 int mutt_tag_attach (MUTTMENU *menu, int n);
 
-void mutt_save_attachment_list (FILE *fp, int tag, BODY *top);
+void mutt_save_attachment_list (FILE *fp, int tag, BODY *top, HEADER *hdr);
 void mutt_pipe_attachment_list (FILE *fp, int tag, BODY *top, int filter);
 void mutt_print_attachment_list (FILE *fp, int tag, BODY *top);
 void mutt_attach_display_loop (MUTTMENU *menu, int op, FILE *fp, ATTACHPTR **idx);
diff --git a/bind.c b/bind.c
deleted file mode 100644 (file)
index a327bf7..0000000
--- a/bind.c
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Copyright (C) 1996-8 Michael R. Elkins <me@cs.hmc.edu>
- *
- *     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.
- */
-
-#include "mutt.h"
-#include "mutt_curses.h"
-#include "keymap.h"
-#include "mapping.h"
-
-#include <string.h>
-
-static struct mapping_t Menus[] = {
- { "alias",    MENU_ALIAS },
- { "attach",   MENU_ATTACH },
- { "browser",  MENU_FOLDER },
- { "compose",  MENU_COMPOSE },
- { "editor",   MENU_EDITOR },
- { "generic",  MENU_GENERIC },
- { "index",    MENU_MAIN },
- { "pager",    MENU_PAGER },
-
-
-
-#ifdef _PGPPATH
- { "pgp",      MENU_PGP },
-#endif /* _PGPPATH */
-
-
-
- { NULL,       0 }
-};
-
-#define mutt_check_menu(s) mutt_getvaluebyname(s, Menus)
-
-/* expects to see: <menu-string> <key-string> */
-static const char *parse_keymap (int *menu,
-                                char *key,
-                                size_t keylen,
-                                const char *s,
-                                char *err,
-                                size_t errlen)
-{
-  char buf[SHORT_STRING];
-  char expn[SHORT_STRING];
-
-  /* menu name */
-  s = mutt_extract_token (buf, sizeof (buf), s, expn, sizeof (expn), 0);
-
-  if (s)
-  {
-    if ((*menu = mutt_check_menu (buf)) == -1)
-    {
-      snprintf (err, errlen, "%s: no such menu", s);
-      return (NULL);
-    }
-
-    /* key sequence */
-    s = mutt_extract_token (key, keylen, s, expn, sizeof (expn), 0);
-
-    if (s)
-      return s;
-  }
-
-  strfcpy (err, "too few arguments", errlen);
-  return (NULL);
-}
-
-static int
-try_bind (char *key, int menu, char *func, struct binding_t *bindings)
-{
-  int i;
-  
-  for (i = 0; bindings[i].name; i++)
-    if (strcmp (func, bindings[i].name) == 0)
-    {
-      km_bindkey (key, menu, bindings[i].op, NULL);
-      return (0);
-    }
-  return (-1);
-}
-
-/* bind menu-name '<key_sequence>' function-name */
-int mutt_parse_bind (const char *s, unsigned long data, char *err, size_t errlen)
-{
-  struct binding_t *bindings = NULL;
-  char buf[SHORT_STRING];
-  char key[SHORT_STRING];
-  char expn[SHORT_STRING];
-  int menu;
-
-  if ((s = parse_keymap (&menu, key, sizeof (key), s, err, errlen)) == NULL)
-    return (-1);
-
-  switch (menu)
-  {
-    case MENU_MAIN:
-      bindings = OpMain;
-      break;
-    case MENU_GENERIC:
-      bindings = OpGeneric;
-      break;
-    case MENU_COMPOSE:
-      bindings = OpCompose;
-      break;
-    case MENU_PAGER:
-      bindings = OpPager;
-      break;
-    case MENU_POST:
-      bindings = OpPost;
-      break;
-    case MENU_FOLDER:
-      bindings = OpBrowser;
-      break;
-    case MENU_ATTACH:
-      bindings = OpAttach;
-      break;
-    case MENU_EDITOR:
-      bindings = OpEditor;
-      break;
-    case MENU_ALIAS:
-      bindings = OpAlias;
-      break;
-
-
-
-#ifdef _PGPPATH
-    case MENU_PGP:
-      bindings = OpPgp;
-      break;
-#endif /* _PGPPATH */
-
-
-
-  }
-
-  /* function to execute */
-  s = mutt_extract_token (buf, sizeof (buf), s, expn, sizeof (expn), 0);
-  if (s)
-  {
-    strfcpy (err, "too many arguments", errlen);
-    return (-1);
-  }
-
-  if (strcasecmp ("noop", buf) == 0)
-  {
-    km_bindkey (key, menu, OP_NULL, NULL);
-    return 0;
-  }
-
-  if (menu != MENU_PAGER && menu != MENU_EDITOR && menu != MENU_GENERIC)
-  {
-    /* First check the "generic" list of commands.  */
-    if (try_bind (key, menu, buf, OpGeneric) == 0)
-      return 0;
-  }
-
-  /* Now check the menu-specific list of commands (if they exist).  */
-  if (bindings && try_bind (key, menu, buf, bindings) == 0)
-    return 0;
-
-  snprintf (err, errlen, "%s: no such function in map", buf);
-  return (-1);
-}
-
-/* macro <menu> <key> <macro> */
-int mutt_parse_macro (const char *s, unsigned long data, char *err, size_t errlen)
-{
-  int menu;
-  char key[SHORT_STRING];
-  char buf[SHORT_STRING];
-  char expn[SHORT_STRING];
-
-  if ((s = parse_keymap (&menu, key, sizeof (key), s, err, errlen)) == NULL)
-    return (-1);
-
-  s = mutt_extract_token (buf, sizeof (buf), s, expn, sizeof (expn), M_CONDENSE);
-  if (s)
-  {
-    strfcpy (err, "too many arguments", errlen);
-    return (-1);
-  }
-
-  km_bindkey (key, menu, OP_MACRO, buf);
-
-  return 0;
-}
index b66982cf5d6a86306aca32104f9265714a37763b..a90d517355baf714a64f0c97e1b2fd79995ae47d 100644 (file)
--- a/browser.c
+++ b/browser.c
 #include "mutt_curses.h"
 #include "mutt_menu.h"
 #include "buffy.h"
+#include "mapping.h"
 #include "sort.h"
 #include "mailbox.h"
 
 #include <stdlib.h>
 #include <dirent.h>
 #include <string.h>
+#include <ctype.h>
 #include <unistd.h>
 #include <sys/stat.h>
 #include <pwd.h>
@@ -149,79 +151,135 @@ folder_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 fn[SHORT_STRING], tmp[SHORT_STRING], permission[10];
+  char fn[SHORT_STRING], tmp[SHORT_STRING], permission[11];
   char date[16], *t_fmt;
   time_t tnow;
   FOLDER *folder = (FOLDER *) data;
   struct passwd *pw;
   struct group *gr;
+
   switch (op)
   {
     case 'd':
-      tnow = time (NULL);
-      t_fmt = tnow - folder->f->st_mtime < 31536000 ? "%b %d %H:%M" : "%b %d  %Y";
-      strftime (date, sizeof (date), t_fmt, localtime (&folder->f->st_mtime));
-      snprintf (tmp, sizeof (tmp), "%%%ss", fmt);
-      snprintf (dest, destlen, tmp, date);
+      if (folder->f != NULL)
+      {
+       tnow = time (NULL);
+       t_fmt = tnow - folder->f->st_mtime < 31536000 ? "%b %d %H:%M" : "%b %d  %Y";
+       strftime (date, sizeof (date), t_fmt, localtime (&folder->f->st_mtime));
+       snprintf (tmp, sizeof (tmp), "%%%ss", fmt);
+       snprintf (dest, destlen, tmp, date);
+      }
+      else
+      {
+       snprintf (tmp, sizeof (tmp), "%%%ss", fmt);
+       snprintf (dest, destlen, tmp, "");
+      }
       break;
     case 'f':
       strncpy (fn, folder->name, sizeof(fn) - 1);
-      strcat (fn, S_ISLNK (folder->f->st_mode) ? "@" : 
-             (S_ISDIR (folder->f->st_mode) ? "/" : 
-              ((folder->f->st_mode & S_IXUSR) != 0 ? "*" : "")));
+      if (folder->f != NULL)
+      {
+       strcat (fn, S_ISLNK (folder->f->st_mode) ? "@" : 
+               (S_ISDIR (folder->f->st_mode) ? "/" : 
+                ((folder->f->st_mode & S_IXUSR) != 0 ? "*" : "")));
+      }
       snprintf (tmp, sizeof (tmp), "%%%ss", fmt);
       snprintf (dest, destlen, tmp, fn);
       break;
     case 'F':
-      sprintf (permission, "%c%c%c%c%c%c%c%c%c%c",
-              S_ISDIR(folder->f->st_mode) ? 'd' : (S_ISLNK(folder->f->st_mode) ? 'l' : '-'),
-              (folder->f->st_mode & S_IRUSR) != 0 ? 'r': '-',
-              (folder->f->st_mode & S_IWUSR) != 0 ? 'w' : '-',
-              (folder->f->st_mode & S_ISUID) != 0 ? 's' : (folder->f->st_mode & S_IXUSR) != 0 ? 'x': '-',
-              (folder->f->st_mode & S_IRGRP) != 0 ? 'r' : '-',
-              (folder->f->st_mode & S_IWGRP) != 0 ? 'w' : '-',
-              (folder->f->st_mode & S_ISGID) != 0 ? 's' : (folder->f->st_mode & S_IXGRP) != 0 ? 'x': '-',
-              (folder->f->st_mode & S_IROTH) != 0 ? 'r' : '-',
-              (folder->f->st_mode & S_IWOTH) != 0 ? 'w' : '-',
-              (folder->f->st_mode & S_ISVTX) != 0 ? 't' : (folder->f->st_mode & S_IXOTH) != 0 ? 'x': '-');
-      snprintf (tmp, sizeof (tmp), "%%%ss", fmt);
-      snprintf (dest, destlen, tmp, permission);
+      if (folder->f != NULL)
+      {
+       sprintf (permission, "%c%c%c%c%c%c%c%c%c%c",
+                S_ISDIR(folder->f->st_mode) ? 'd' : (S_ISLNK(folder->f->st_mode) ? 'l' : '-'),
+                (folder->f->st_mode & S_IRUSR) != 0 ? 'r': '-',
+                (folder->f->st_mode & S_IWUSR) != 0 ? 'w' : '-',
+                (folder->f->st_mode & S_ISUID) != 0 ? 's' : (folder->f->st_mode & S_IXUSR) != 0 ? 'x': '-',
+                (folder->f->st_mode & S_IRGRP) != 0 ? 'r' : '-',
+                (folder->f->st_mode & S_IWGRP) != 0 ? 'w' : '-',
+                (folder->f->st_mode & S_ISGID) != 0 ? 's' : (folder->f->st_mode & S_IXGRP) != 0 ? 'x': '-',
+                (folder->f->st_mode & S_IROTH) != 0 ? 'r' : '-',
+                (folder->f->st_mode & S_IWOTH) != 0 ? 'w' : '-',
+                (folder->f->st_mode & S_ISVTX) != 0 ? 't' : (folder->f->st_mode & S_IXOTH) != 0 ? 'x': '-');
+       snprintf (tmp, sizeof (tmp), "%%%ss", fmt);
+       snprintf (dest, destlen, tmp, permission);
+      }
+      else
+      {
+#ifdef USE_IMAP
+       if (strchr(folder->name, '{'))
+       {
+         snprintf (tmp, sizeof (tmp), "%%%ss", fmt);
+         snprintf (dest, destlen, tmp, "IMAP");
+       }                                        
+#endif
+      }
       break;
     case 'g':
-      if ((gr = getgrgid (folder->f->st_gid)))
+      if (folder->f != NULL)
       {
-       snprintf (tmp, sizeof (tmp), "%%%ss", fmt);
-       snprintf (dest, destlen, tmp, gr->gr_name);
+       if ((gr = getgrgid (folder->f->st_gid)))
+       {
+         snprintf (tmp, sizeof (tmp), "%%%ss", fmt);
+         snprintf (dest, destlen, tmp, gr->gr_name);
+       }
+       else
+       {
+         snprintf (tmp, sizeof (tmp), "%%%sld", fmt);
+         snprintf (dest, destlen, tmp, folder->f->st_gid);
+       }
       }
       else
       {
-       snprintf (tmp, sizeof (tmp), "%%%sld", fmt);
-       snprintf (dest, destlen, tmp, folder->f->st_gid);
+       snprintf (tmp, sizeof (tmp), "%%%ss", fmt);
+       snprintf (dest, destlen, tmp, "");
       }
       break;
     case 'l':
-      snprintf (tmp, sizeof (tmp), "%%%sd", fmt);
-      snprintf (dest, destlen, tmp, folder->f->st_nlink);
+      if (folder->f != NULL)
+      {
+       snprintf (tmp, sizeof (tmp), "%%%sd", fmt);
+       snprintf (dest, destlen, tmp, folder->f->st_nlink);
+      }
+      else
+      {
+       snprintf (tmp, sizeof (tmp), "%%%ss", fmt);
+       snprintf (dest, destlen, tmp, "");
+      }
       break;
     case 'N':
       snprintf (tmp, sizeof (tmp), "%%%sc", fmt);
       snprintf (dest, destlen, tmp, folder->new ? 'N' : ' ');
       break;
     case 's':
-      snprintf (tmp, sizeof (tmp), "%%%sld", fmt);
-      snprintf (dest, destlen, tmp, (long) folder->f->st_size);
+      if (folder->f != NULL)
+      {
+       snprintf (tmp, sizeof (tmp), "%%%sld", fmt);
+       snprintf (dest, destlen, tmp, (long) folder->f->st_size);
+      }
+      else
+      {
+       snprintf (tmp, sizeof (tmp), "%%%ss", fmt);
+       snprintf (dest, destlen, tmp, "");
+      }
       break;
     case 'u':
-      if ((pw = getpwuid (folder->f->st_uid)))
+      if (folder->f != NULL)
       {
-       snprintf (tmp, sizeof (tmp), "%%%ss", fmt);
-       snprintf (dest, destlen, tmp, pw->pw_name);
+       if ((pw = getpwuid (folder->f->st_uid)))
+       {
+         snprintf (tmp, sizeof (tmp), "%%%ss", fmt);
+         snprintf (dest, destlen, tmp, pw->pw_name);
+       }
+       else
+       {
+         snprintf (tmp, sizeof (tmp), "%%%sld", fmt);
+         snprintf (dest, destlen, tmp, folder->f->st_uid);
+       }
       }
       else
       {
-       snprintf (tmp, sizeof (tmp), "%%%sld", fmt);
-       snprintf (dest, destlen, tmp, folder->f->st_uid);
+       snprintf (tmp, sizeof (tmp), "%%%ss", fmt);
+       snprintf (dest, destlen, tmp, "");
       }
       break;
   }
@@ -237,7 +295,7 @@ static void add_folder (MUTTMENU *m, struct browser_state *state,
   folder.name = name;
   folder.f = s;
   folder.new = new;
-  mutt_FormatString (buffer, sizeof (buffer), FolderFormat, folder_format_str,
+  mutt_FormatString (buffer, sizeof (buffer), NONULL(FolderFormat), folder_format_str,
                     (unsigned long) &folder, 0);
 
   if (state->entrylen == state->entrymax)
@@ -249,9 +307,12 @@ static void add_folder (MUTTMENU *m, struct browser_state *state,
       m->data = state->entry;
   }
 
+  if (s != NULL)
+  {
   (state->entry)[state->entrylen].mode = s->st_mode;
   (state->entry)[state->entrylen].mtime = s->st_mtime;
   (state->entry)[state->entrylen].size = s->st_size;
+  }
   (state->entry)[state->entrylen].name = safe_strdup (name);
   (state->entry)[state->entrylen].desc = safe_strdup (buffer);
 
@@ -305,7 +366,7 @@ static int examine_directory (MUTTMENU *menu, struct browser_state *state,
     
     if (prefix && *prefix && strncmp (prefix, de->d_name, strlen (prefix)) != 0)
       continue;
-    if (regexec (Mask.rx, de->d_name, 0, NULL, 0) != 0)
+    if (!((regexec (Mask.rx, de->d_name, 0, NULL, 0) == 0) ^ Mask.not))
       continue;
 
     snprintf (buffer, sizeof (buffer), "%s/%s", d, de->d_name);
@@ -317,7 +378,7 @@ static int examine_directory (MUTTMENU *menu, struct browser_state *state,
       continue;
     
     tmp = Incoming;
-    while (tmp && strcmp (buffer, tmp->path))
+    while (tmp && strcmp (buffer, NONULL(tmp->path)))
       tmp = tmp->next;
     add_folder (menu, state, de->d_name, &s, (tmp) ? tmp->new : 0);
   }
@@ -340,6 +401,13 @@ static int examine_mailboxes (MUTTMENU *menu, struct browser_state *state)
 
   do
   {
+#ifdef USE_IMAP
+    if (tmp->path[0] == '{')
+    {
+      add_folder (menu, state, tmp->path, NULL, tmp->new);
+      continue;
+    }
+#endif
     if (lstat (tmp->path, &s) == -1)
       continue;
 
@@ -347,7 +415,7 @@ static int examine_mailboxes (MUTTMENU *menu, struct browser_state *state)
        (! S_ISLNK (s.st_mode)))
       continue;
     
-    strfcpy (buffer, tmp->path, sizeof (buffer));
+    strfcpy (buffer, NONULL(tmp->path), sizeof (buffer));
     mutt_pretty_mailbox (buffer);
 
     add_folder (menu, state, buffer, &s, tmp->new);
@@ -372,9 +440,13 @@ static void init_menu (struct browser_state *state, MUTTMENU *menu, char *title,
 {
   char path[_POSIX_PATH_MAX];
 
-  menu->current = 0;
-  menu->top = 0;
   menu->max = state->entrylen;
+
+  if(menu->current >= menu->max)
+    menu->current = menu->max - 1;
+  if (menu->current < 0)
+    menu->current = 0;
+
   if (buffy)
     snprintf (title, titlelen, "Mailboxes [%d]", mutt_buffy_check (0));
   else
@@ -389,7 +461,7 @@ static void init_menu (struct browser_state *state, MUTTMENU *menu, char *title,
 
 void mutt_select_file (char *f, size_t flen, int buffy)
 {
-  char buf[STRING];
+  char buf[_POSIX_PATH_MAX];
   char prefix[_POSIX_PATH_MAX] = "";
   char helpstr[SHORT_STRING];
   char title[STRING];
@@ -434,7 +506,7 @@ void mutt_select_file (char *f, size_t flen, int buffy)
     killPrefix = 1;
   }
   else if (!LastDir[0])
-    strfcpy (LastDir, Maildir, sizeof (LastDir));
+    strfcpy (LastDir, NONULL(Maildir), sizeof (LastDir));
 
   *f = 0;
 
@@ -531,10 +603,12 @@ void mutt_select_file (char *f, size_t flen, int buffy)
              strfcpy (LastDir, OldLastDir, sizeof (LastDir));
              if (examine_directory (menu, &state, LastDir, prefix) == -1)
              {
-               strfcpy (LastDir, Homedir, sizeof (LastDir));
+               strfcpy (LastDir, NONULL(Homedir), sizeof (LastDir));
                return;
              }
            }
+           menu->current = 0; 
+           menu->top = 0; 
            init_menu (&state, menu, title, sizeof (title), buffy);
            break;
          }
@@ -559,6 +633,12 @@ void mutt_select_file (char *f, size_t flen, int buffy)
       case OP_CHANGE_DIRECTORY:
 
        strfcpy (buf, LastDir, sizeof (buf));
+       {/* add '/' at the end of the directory name */
+       int len=strlen(LastDir);
+       if (sizeof (buf) > len)
+         buf[len]='/';
+       }
+
        if (mutt_get_field ("Chdir to: ", buf, sizeof (buf), M_FILE) == 0 &&
            buf[0])
        {
@@ -571,7 +651,11 @@ void mutt_select_file (char *f, size_t flen, int buffy)
              strfcpy (LastDir, buf, sizeof (LastDir));
              destroy_state (&state);
              if (examine_directory (menu, &state, LastDir, prefix) == 0)
+             {
+               menu->current = 0; 
+               menu->top = 0; 
                init_menu (&state, menu, title, sizeof (title), buffy);
+             }
              else
              {
                mutt_error ("Error scanning directory.");
@@ -595,14 +679,22 @@ void mutt_select_file (char *f, size_t flen, int buffy)
        if (mutt_get_field ("File Mask: ", buf, sizeof (buf), 0) == 0)
        {
          regex_t *rx = (regex_t *) safe_malloc (sizeof (regex_t));
-         int err;
+         char *s = buf;
+         int not = 0, err;
 
          buffy = 0;
          /* assume that the user wants to see everything */
          if (!buf[0])
            strfcpy (buf, ".", sizeof (buf));
+         SKIPWS (s);
+         if (*s == '!')
+         {
+           s++;
+           SKIPWS (s);
+           not = 1;
+         }
 
-         if ((err = REGCOMP (rx, buf, REG_NOSUB | mutt_which_case (buf))) != 0)
+         if ((err = REGCOMP (rx, s, REG_NOSUB)) != 0)
          {
            regerror (err, rx, buf, sizeof (buf));
            regfree (rx);
@@ -616,6 +708,7 @@ void mutt_select_file (char *f, size_t flen, int buffy)
            safe_free ((void **) &Mask.rx);
            Mask.pattern = safe_strdup (buf);
            Mask.rx = rx;
+           Mask.not = not;
 
            destroy_state (&state);
            if (examine_directory (menu, &state, LastDir, NULL) == 0)
@@ -627,6 +720,11 @@ void mutt_select_file (char *f, size_t flen, int buffy)
              return;
            }
            killPrefix = 0;
+           if (!state.entrylen)
+           {
+             mutt_error ("No files match the file mask");
+             break;
+           }
          }
        }
        MAYBE_REDRAW (menu->redraw);
@@ -680,9 +778,10 @@ void mutt_select_file (char *f, size_t flen, int buffy)
 
        break;
 
-      case OP_CHECK_NEW:
-
+      case OP_TOGGLE_MAILBOXES:
        buffy = 1 - buffy;
+
+      case OP_CHECK_NEW:
        destroy_state (&state);
        prefix[0] = 0;
        killPrefix = 0;
@@ -708,6 +807,38 @@ void mutt_select_file (char *f, size_t flen, int buffy)
        }
        MAYBE_REDRAW (menu->redraw);
        break;
+
+      case OP_BROWSER_VIEW_FILE:
+       if (!state.entrylen)
+       {
+         mutt_error ("No files match the file mask");
+         break;
+       }
+
+        if (S_ISDIR (state.entry[menu->current].mode) ||
+           (S_ISLNK (state.entry[menu->current].mode) &&
+           link_is_dir (state.entry[menu->current].name)))
+       {
+         mutt_error ("Can't view a directory");
+         break;
+       } 
+       else
+       {
+         BODY *b;
+         char buf[_POSIX_PATH_MAX];
+
+         snprintf (buf, sizeof (buf), "%s/%s", LastDir,
+                   state.entry[menu->current].name);
+         b = mutt_make_file_attach (buf);
+         if (b != NULL)
+         {
+           mutt_view_attachment (NULL, b, M_REGULAR);
+           mutt_free_body (&b);
+           menu->redraw = REDRAW_FULL;
+         }
+         else
+           mutt_error ("Error trying to view file");
+       }
     }
   }
   /* not reached */
diff --git a/buffy.c b/buffy.c
index 1fa1d7cfc1665a18e8017218f5796740e37059cc..98c1a0effed6ab9534596347be404f13c64c28ce 100644 (file)
--- a/buffy.c
+++ b/buffy.c
 #include "buffy.h"
 #include "mx.h"
 #include "mailbox.h"
+#ifdef USE_IMAP
+#include "imap.h"
+#endif
 
 #include <string.h>
 #include <sys/stat.h>
 #include <dirent.h>
 #include <utime.h>
 #include <ctype.h>
+#include <unistd.h>
 
 #include <stdio.h>
 
@@ -241,6 +245,13 @@ int mutt_buffy_check (int force)
   {
     tmp->new = 0;
 
+#ifdef USE_IMAP
+    if ((tmp->magic == M_IMAP) || mx_is_imap (tmp->path))
+    {
+      tmp->magic = M_IMAP;
+    }
+    else
+#endif
     if (stat (tmp->path, &sb) != 0 ||
        (!tmp->magic && (tmp->magic = mx_get_magic (tmp->path)) <= 0))
     {
@@ -315,6 +326,16 @@ int mutt_buffy_check (int force)
          tmp->magic = 0;
        }
        break;
+
+#ifdef USE_IMAP
+      case M_IMAP:
+       if (imap_buffy_check (tmp->path) > 0)
+       {
+         BuffyCount++;
+         tmp->new = 1;
+       }
+       break;
+#endif
       }
     }
 #ifdef BUFFY_SIZE
diff --git a/color.c b/color.c
index 66bcd8b315fe02214265bc2e6babab76a811f141..11872f0aa7a3ddf8463c3f681d0a6bd9950b24b7 100644 (file)
--- a/color.c
+++ b/color.c
@@ -94,6 +94,40 @@ static struct mapping_t Fields[] =
 
 #define COLOR_QUOTE_INIT       8
 
+static COLOR_LINE *mutt_new_color_line (void)
+{
+  COLOR_LINE *p = safe_calloc (1, sizeof (COLOR_LINE));
+
+  p->fg = p->bg = -1;
+  
+  return (p);
+}
+
+static void mutt_free_color_line(COLOR_LINE **l, 
+                                int free_colors)
+{
+  COLOR_LINE *tmp;
+  if(!l || !*l)
+    return;
+
+  tmp = *l;
+
+#ifdef HAVE_COLOR
+  if(free_colors && tmp->fg != -1 && tmp->bg != -1)
+    mutt_free_color(tmp->fg, tmp->bg);
+#endif
+
+  /* we should really introduce a container
+   * type for regular expressions.
+   */
+  
+  regfree(&tmp->rx);
+  mutt_pattern_free(&tmp->color_pattern);
+  safe_free((void **)&tmp->pattern);
+  safe_free((void **)l);
+}
+
 void ci_start_color (void)
 {
   memset (ColorDefs, A_NORMAL, sizeof (int) * MT_COLOR_MAX);
@@ -198,7 +232,7 @@ int mutt_alloc_color (int fg, int bg)
     bg = -1;
 #endif
 
-  init_pair (i, fg, bg);
+  init_pair(i, fg, bg);
 
   dprint(1,(debugfile,"mutt_alloc_color(): Color pairs used so far: %d\n",
                        UserColors));
@@ -247,87 +281,6 @@ void mutt_free_color (int fg, int bg)
 
 #endif /* HAVE_COLOR */
 
-static COLOR_LINE *mutt_new_color_line (void)
-{
-  COLOR_LINE *p = safe_calloc (1, sizeof (COLOR_LINE));
-
-  return (p);
-}
-
-static int add_pattern (COLOR_LINE **top, const char *s, int sensitive,
-                       int fg, int bg, int attr, BUFFER *err,
-                       /* is_index used to store compiled pattern
-                          only for `index' color object 
-                          when called from mutt_parse_color() */
-                       int is_index)
-{
-  COLOR_LINE *tmp = *top;
-
-  while (tmp)
-  {
-    if (sensitive)
-    {
-      if (strcmp (s, tmp->pattern) == 0)
-       break;
-    }
-    else
-    {
-      if (strcasecmp (s, tmp->pattern) == 0)
-       break;
-    }
-    tmp = tmp->next;
-  }
-
-  if (tmp)
-  {
-#ifdef HAVE_COLOR
-    if (fg != -1 && bg != -1)
-    {
-      if (tmp->fg != fg || tmp->bg != bg)
-      {
-       mutt_free_color (tmp->fg, tmp->bg);
-       tmp->fg = fg;
-       tmp->bg = bg;
-       attr |= mutt_alloc_color (fg, bg);
-      }
-      else
-       attr |= (tmp->pair & ~A_BOLD);
-    }
-#endif /* HAVE_COLOR */
-    tmp->pair = attr;
-  }
-  else
-  {
-    int r;
-    char buf[STRING];
-
-    tmp = mutt_new_color_line ();
-    if ((r = REGCOMP (&tmp->rx, s, (sensitive ? mutt_which_case (s) : REG_ICASE))) != 0)
-    {
-      regerror (r, &tmp->rx, err->data, err->dsize);
-      regfree (&tmp->rx);
-      safe_free ((void **) &tmp);
-      return (-1);
-    }
-    tmp->next = *top;
-    tmp->pattern = safe_strdup (s);
-#ifdef HAVE_COLOR
-    tmp->fg = fg;
-    tmp->bg = bg;
-    attr |= mutt_alloc_color (fg, bg);
-    if (is_index) 
-    {
-      strcpy(buf,tmp->pattern);
-      mutt_check_simple (buf, sizeof (buf), SimpleSearch);
-      tmp->color_pattern = mutt_pattern_comp (buf, M_FULL_MSG, err);
-    }
-#endif
-    tmp->pair = attr;
-    *top = tmp;
-  }
-
-  return 0;
-}
 
 #ifdef HAVE_COLOR
 
@@ -360,19 +313,40 @@ parse_color_name (const char *s, int *col, int *attr, int brite, BUFFER *err)
     return (-1);
   }
 
-#ifdef HAVE_USE_DEFAULT_COLORS
-  if (*col == COLOR_DEFAULT && use_default_colors () != OK)
-  {
-    strfcpy (err->data, "default colors not supported", err->dsize);
-    return (-1);
-  }
+  return 0;
+}
+
 #endif
 
-  return 0;
+
+/* usage: uncolor index pattern [pattern...]
+ *       unmono  index pattern [pattern...]
+ */
+
+static int 
+_mutt_parse_uncolor (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *err, 
+                        short parse_uncolor);
+
+
+#ifdef HAVE_COLOR
+
+int mutt_parse_uncolor (BUFFER *buf, BUFFER *s, unsigned long data,
+                       BUFFER *err)
+{
+  return _mutt_parse_uncolor(buf, s, data, err, 1);
 }
 
-/* usage: uncolor index pattern [pattern...] */
-int mutt_parse_uncolor (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *err)
+#endif
+
+int mutt_parse_unmono (BUFFER *buf, BUFFER *s, unsigned long data,
+                      BUFFER *err)
+{
+  return _mutt_parse_uncolor(buf, s, data, err, 0);
+}
+
+static int 
+_mutt_parse_uncolor (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *err, 
+                        short parse_uncolor)
 {
   int object = 0, do_cache = 0;
   COLOR_LINE *tmp, *last = NULL;
@@ -387,17 +361,33 @@ int mutt_parse_uncolor (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *err)
 
   if (strncmp (buf->data, "index", 5) != 0)
   {
-   strfcpy (err->data, "uncolor: command valid only for index object", err->dsize);
-   return (-1);
+    snprintf (err->data, err->dsize,
+             "%s: command valid only for index object", 
+             parse_uncolor ? "uncolor" : "unmono");
+    return (-1);
   }
-
+  
   if (!MoreArgs (s))
   {
-    strfcpy (err->data, "uncolor: too few arguments", err->dsize);
+    snprintf (err->data, err->dsize,
+             "%s: too few arguments", parse_uncolor ? "uncolor" : "unmono");
     return (-1);
   }
 
-  while (MoreArgs (s))
+  if(
+#ifdef HAVE_COLOR
+     (parse_uncolor && !has_colors())
+     || (!parse_uncolor && has_colors())
+#else
+     parse_uncolor
+#endif
+     )
+  {
+    return 0;
+  }
+     
+  
+  do
   {
     mutt_extract_token (buf, s, 0);
     if (!strcmp ("*", buf->data))
@@ -408,9 +398,7 @@ int mutt_parse_uncolor (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *err)
          do_cache = 1;
        last = tmp;
        tmp = tmp->next;
-       mutt_pattern_free (&last->color_pattern);
-       mutt_free_color(last->fg,last->bg);
-       safe_free ((void **) &last);
+       mutt_free_color_line(&last, parse_uncolor);
       }
       ColorIndexList = NULL;
     }
@@ -428,194 +416,187 @@ int mutt_parse_uncolor (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *err)
            last->next = tmp->next;
          else
            ColorIndexList = tmp->next;
-         mutt_pattern_free (&tmp->color_pattern);
-         mutt_free_color(tmp->fg,tmp->bg);
-         safe_free ((void **) &tmp);
+         mutt_free_color_line(&tmp, parse_uncolor);
          break;
        }
       }
     }
   }
-  
-  if (do_cache && !option (OPTNOCURSES) && has_colors ()) 
-  {
-   mutt_cache_index_colors (Context);
-   set_option (OPTFORCEREDRAWINDEX);
-  }
-
-  return (0);
-}
+  while (MoreArgs (s));
 
-/* usage: color <object> <fg> <bg> [ <regexp> ] */
-int mutt_parse_color (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *err)
-{
-  int object = 0, bold = 0, fg = 0, bg = 0, q_level = 0;
-  int r = 0;
-  char *eptr;
 
-  mutt_extract_token (buf, s, 0);
-  if (!strncmp (buf->data, "quoted", 6))
+  if (do_cache && !option (OPTNOCURSES))
   {
-    if (buf->data[6])
-    {
-      q_level = strtol (buf->data + 6, &eptr, 10);
-      if (*eptr || q_level < 0)
-      {
-       snprintf (err->data, err->dsize, "%s: no such object", buf->data);
-       return (-1);
-      }
-    }
-    object = MT_COLOR_QUOTED;
-  }
-  else if ((object = mutt_getvaluebyname (buf->data, Fields)) == -1)
-  {
-    snprintf (err->data, err->dsize, "%s: no such object", buf->data);
-    return (-1);
+    mutt_cache_index_colors (Context);
+    set_option (OPTFORCEREDRAWINDEX);
   }
+  return (0);
+}
 
-  /* first color */
-  if (! MoreArgs (s))
-  {
-    strfcpy (err->data, "color: too few arguments", err->dsize);
-    return (-1);
-  }
-  mutt_extract_token (buf, s, 0);
 
-  if (parse_color_name (buf->data, &fg, &bold, A_BOLD, err) != 0)
-    return (-1);
+static int 
+add_pattern (COLOR_LINE **top, const char *s, int sensitive,
+            int fg, int bg, int attr, BUFFER *err,
+            int is_index)
+{
 
-  /* second color */
-  if (! MoreArgs (s))
-  {
-    strfcpy (err->data, "color: too few arguments", err->dsize);
-    return (-1);
-  }
-  mutt_extract_token (buf, s, 0);
+  /* is_index used to store compiled pattern
+   * only for `index' color object 
+   * when called from mutt_parse_color() */
 
-  /* A_BLINK turns the background color brite on some terms */
-  if (parse_color_name (buf->data, &bg, &bold, A_BLINK, err) != 0)
-    return (-1);
+  COLOR_LINE *tmp = *top;
 
-  if (object == MT_COLOR_HEADER || object == MT_COLOR_BODY || object == MT_COLOR_INDEX)
+  while (tmp)
   {
-    if (! MoreArgs (s))
-    {
-      strfcpy (err->data, "color: too few arguments", err->dsize);
-      return (-1);
-    }
-
-    mutt_extract_token (buf, s, 0);
-    if (MoreArgs (s))
+    if (sensitive)
     {
-      strfcpy (err->data, "color: too many arguments", err->dsize);
-      return (-1);
+      if (strcmp (s, tmp->pattern) == 0)
+       break;
     }
-
-    /* don't parse curses command if we're not using the screen */
-    /* ignore color commands if we're running on a mono terminal */
-    if (option (OPTNOCURSES) || !has_colors ())
+    else
     {
-      return 0;
+      if (strcasecmp (s, tmp->pattern) == 0)
+       break;
     }
+    tmp = tmp->next;
+  }
 
-    if (object == MT_COLOR_HEADER)
-      r = add_pattern (&ColorHdrList, buf->data, 0, fg, bg, bold, err,0);
-    else if (object == MT_COLOR_BODY)
-      r = add_pattern (&ColorBodyList, buf->data, 1, fg, bg, bold, err, 0);
-    else if (object == MT_COLOR_INDEX)
+  if (tmp)
+  {
+#ifdef HAVE_COLOR
+    if (fg != -1 && bg != -1)
     {
-      pattern_t *pat;
-      char tempbuf[LONG_STRING];
-
-      strfcpy (tempbuf, buf->data, sizeof (tempbuf));
-      mutt_check_simple (tempbuf, sizeof (tempbuf), SimpleSearch);
-      if ((pat = mutt_pattern_comp (tempbuf, M_FULL_MSG, err)) == NULL)
+      if (tmp->fg != fg || tmp->bg != bg)
       {
-       mutt_pattern_free (&pat);
-       return (-1);
+       mutt_free_color (tmp->fg, tmp->bg);
+       tmp->fg = fg;
+       tmp->bg = bg;
+       attr |= mutt_alloc_color (fg, bg);
       }
-      r = add_pattern (&ColorIndexList, buf->data, 1, fg, bg, bold, err, 1);
-      mutt_cache_index_colors(Context);
-      set_option (OPTFORCEREDRAWINDEX);
+      else
+       attr |= (tmp->pair & ~A_BOLD);
     }
+#endif /* HAVE_COLOR */
+    tmp->pair = attr;
   }
   else
   {
-    /* don't parse curses command if we're not using the screen */
-    /* ignore color commands if we're running on a mono terminal */
-    if (option (OPTNOCURSES) || !has_colors ())
+    int r;
+    char buf[STRING];
+
+    tmp = mutt_new_color_line ();
+    if ((r = REGCOMP (&tmp->rx, s, (sensitive ? mutt_which_case (s) : REG_ICASE))) != 0)
     {
-      return 0;
+      regerror (r, &tmp->rx, err->data, err->dsize);
+      mutt_free_color_line(&tmp, 1);
+      return (-1);
     }
-
-    if (object == MT_COLOR_QUOTED)
+    tmp->next = *top;
+    tmp->pattern = safe_strdup (s);
+#ifdef HAVE_COLOR
+    if(fg != -1 && bg != -1)
     {
-      if (q_level >= ColorQuoteSize)
-      {
-       safe_realloc ((void **) &ColorQuote, (ColorQuoteSize += 2) * sizeof (int));
-       ColorQuote[ColorQuoteSize-2] = ColorDefs[MT_COLOR_QUOTED];
-       ColorQuote[ColorQuoteSize-1] = ColorDefs[MT_COLOR_QUOTED];
-      }
-      if (q_level >= ColorQuoteUsed)
-       ColorQuoteUsed = q_level + 1;
-      if (q_level == 0)
+      tmp->fg = fg;
+      tmp->bg = bg;
+      attr |= mutt_alloc_color (fg, bg);
+    }
+#endif
+    if (is_index) 
+    {
+      strfcpy(buf, tmp->pattern, sizeof(buf));
+      mutt_check_simple (buf, sizeof (buf), NONULL(SimpleSearch));
+      if((tmp->color_pattern = mutt_pattern_comp (buf, M_FULL_MSG, err)) == NULL)
       {
-       ColorDefs[MT_COLOR_QUOTED] = bold | mutt_alloc_color (fg, bg);
-
-       ColorQuote[0] = ColorDefs[MT_COLOR_QUOTED];
-       for (q_level = 1; q_level < ColorQuoteUsed; q_level++)
-       {
-         if (ColorQuote[q_level] == A_NORMAL)
-           ColorQuote[q_level] = ColorDefs[MT_COLOR_QUOTED];
-       }
+       mutt_free_color_line(&tmp, 1);
+       return -1;
       }
-      else
-       ColorQuote[q_level] = bold | mutt_alloc_color (fg, bg);
     }
-    else
-      ColorDefs[object] = bold | mutt_alloc_color (fg, bg);
+    tmp->pair = attr;
+    *top = tmp;
   }
 
-#ifdef HAVE_BKGDSET
-  if (object == MT_COLOR_NORMAL)
-    BKGDSET (MT_COLOR_NORMAL);
-#endif
-
-  return (r);
+  return 0;
 }
 
-#endif /* HAVE_COLOR */
-
-/*
- * command: mono <object> <attribute>
- *
- * set attribute for an object when using a terminal with no color support
- */
-int mutt_parse_mono (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *err)
+static int
+parse_object(BUFFER *buf, BUFFER *s, int *o, int *ql, BUFFER *err)
 {
-  int r = 0, object, q_level = 0, attr = A_NORMAL;
+  int q_level = 0;
   char *eptr;
-
-  mutt_extract_token (buf, s, 0);
-  if (strncmp (buf->data, "quoted", 6) == 0)
+  
+  if(!MoreArgs(s))
   {
-    if (buf->data[6])
+    strfcpy(err->data, "Missing arguments.", err->dsize);
+    return -1;
+  }
+  
+  mutt_extract_token(buf, s, 0);
+  if(!strncmp(buf->data, "quoted", 6))
+  {
+    if(buf->data[6])
     {
-      q_level = strtol (buf->data + 6, &eptr, 10);
-      if (*eptr || q_level < 0)
+      *ql = strtol(buf->data + 6, &eptr, 10);
+      if(*eptr || q_level < 0)
       {
-       snprintf (err->data, err->dsize, "%s: no such object", buf->data);
-       return (-1);
+       snprintf(err->data, err->dsize, "%s: no such object", buf->data);
+       return -1;
       }
     }
-    object = MT_COLOR_QUOTED;
+    else
+      *ql = 0;
+    
+    *o = MT_COLOR_QUOTED;
   }
-  else if ((object = mutt_getvaluebyname (buf->data, Fields)) == -1)
+  else if ((*o = mutt_getvaluebyname (buf->data, Fields)) == -1)
   {
     snprintf (err->data, err->dsize, "%s: no such object", buf->data);
     return (-1);
   }
 
+  return 0;
+}
+
+typedef int (*parser_callback_t)(BUFFER *, BUFFER *, int *, int *, int *, BUFFER *);
+
+#ifdef HAVE_COLOR
+
+static int
+parse_color_pair(BUFFER *buf, BUFFER *s, int *fg, int *bg, int *attr, BUFFER *err)
+{
+  if (! MoreArgs (s))
+  {
+    strfcpy (err->data, "color: too few arguments", err->dsize);
+    return (-1);
+  }
+
+  mutt_extract_token (buf, s, 0);
+
+  if (parse_color_name (buf->data, fg, attr, A_BOLD, err) != 0)
+    return (-1);
+
+  if (! MoreArgs (s))
+  {
+    strfcpy (err->data, "color: too few arguments", err->dsize);
+    return (-1);
+  }
+  
+  mutt_extract_token (buf, s, 0);
+
+  if (parse_color_name (buf->data, bg, attr, A_BLINK, err) != 0)
+    return (-1);
+  
+  return 0;
+}
+
+#endif
+
+static int
+parse_attr_spec(BUFFER *buf, BUFFER *s, int *fg, int *bg, int *attr, BUFFER *err)
+{
+  
+  if(fg) *fg = -1; 
+  if(bg) *bg = -1;
+
   if (! MoreArgs (s))
   {
     strfcpy (err->data, "mono: too few arguments", err->dsize);
@@ -625,108 +606,156 @@ int mutt_parse_mono (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *err)
   mutt_extract_token (buf, s, 0);
 
   if (strcasecmp ("bold", buf->data) == 0)
-    attr |= A_BOLD;
+    *attr |= A_BOLD;
   else if (strcasecmp ("underline", buf->data) == 0)
-    attr |= A_UNDERLINE;
+    *attr |= A_UNDERLINE;
   else if (strcasecmp ("none", buf->data) == 0)
-    attr = A_NORMAL;
+    *attr = A_NORMAL;
   else if (strcasecmp ("reverse", buf->data) == 0)
-    attr |= A_REVERSE;
+    *attr |= A_REVERSE;
   else if (strcasecmp ("standout", buf->data) == 0)
-    attr |= A_STANDOUT;
+    *attr |= A_STANDOUT;
   else if (strcasecmp ("normal", buf->data) == 0)
-    attr = A_NORMAL; /* needs use = instead of |= to clear other bits */
+    *attr = A_NORMAL; /* needs use = instead of |= to clear other bits */
   else
   {
     snprintf (err->data, err->dsize, "%s: no such attribute", buf->data);
     return (-1);
   }
+  
+  return 0;
+}
+
+static int fgbgattr_to_color(int fg, int bg, int attr)
+{
+#ifdef HAVE_COLOR
+  if(fg != -1 && bg != -1)
+    return attr | mutt_alloc_color(fg, bg);
+  else
+#endif
+    return attr;
+}
 
+/* usage: color <object> <fg> <bg> [ <regexp> ] 
+ *       mono  <object> <attr> [ <regexp> ]
+ */
+
+static int 
+_mutt_parse_color (BUFFER *buf, BUFFER *s, BUFFER *err, 
+                  parser_callback_t callback, short dry_run)
+{
+  int object = 0, attr = 0, fg = 0, bg = 0, q_level = 0;
+  int r = 0;
+
+  if(parse_object(buf, s, &object, &q_level, err) == -1)
+    return -1;
+
+  if(callback(buf, s, &fg, &bg, &attr, err) == -1)
+    return -1;
+
+  /* extract a regular expression if needed */
+  
   if (object == MT_COLOR_HEADER || object == MT_COLOR_BODY || object == MT_COLOR_INDEX)
   {
-    if (! MoreArgs (s))
+    if (!MoreArgs (s))
     {
-      snprintf (err->data, err->dsize, "mono: missing regexp");
+      strfcpy (err->data, "too few arguments", err->dsize);
       return (-1);
     }
 
     mutt_extract_token (buf, s, 0);
-    if (MoreArgs (s))
-    {
-      strfcpy (err->data, "mono: too many arguments", err->dsize);
-      return (-1);
-    }
+  }
+   
+  if (MoreArgs (s))
+  {
+    strfcpy (err->data, "too many arguments", err->dsize);
+    return (-1);
+  }
+  
+  /* dry run? */
+  
+  if(dry_run) return 0;
 
-    /* if we have color, ignore the mono commands */
-    if (option (OPTNOCURSES)
+  
 #ifdef HAVE_COLOR
-       || has_colors ()
+# ifdef HAVE_USE_DEFAULT_COLORS
+  if (has_colors() && use_default_colors () != OK 
+      && (fg == COLOR_DEFAULT || bg == COLOR_DEFAULT))
+  {
+    strfcpy (err->data, "default colors not supported", err->dsize);
+    return (-1);
+  }
+# endif /* HAVE_USE_DEFAULT_COLORS */
 #endif
-       )
+  
+  if (object == MT_COLOR_HEADER)
+    r = add_pattern (&ColorHdrList, buf->data, 0, fg, bg, attr, err,0);
+  else if (object == MT_COLOR_BODY)
+    r = add_pattern (&ColorBodyList, buf->data, 1, fg, bg, attr, err, 0);
+  else if (object == MT_COLOR_INDEX)
+  {
+    r = add_pattern (&ColorIndexList, buf->data, 1, fg, bg, attr, err, 1);
+    mutt_cache_index_colors(Context);
+    set_option (OPTFORCEREDRAWINDEX);
+  }
+  else if (object == MT_COLOR_QUOTED)
+  {
+    if (q_level >= ColorQuoteSize)
     {
-      return 0;
+      safe_realloc ((void **) &ColorQuote, (ColorQuoteSize += 2) * sizeof (int));
+      ColorQuote[ColorQuoteSize-2] = ColorDefs[MT_COLOR_QUOTED];
+      ColorQuote[ColorQuoteSize-1] = ColorDefs[MT_COLOR_QUOTED];
     }
-
-    if (object == MT_COLOR_HEADER)
-      r = add_pattern (&ColorHdrList, buf->data, 0, -1, -1, attr, err, 0);
-    else if (object == MT_COLOR_BODY)
-      r = add_pattern (&ColorBodyList, buf->data, 1, -1, -1, attr, err, 0);
-    else if (object == MT_COLOR_INDEX)
+    if (q_level >= ColorQuoteUsed)
+      ColorQuoteUsed = q_level + 1;
+    if (q_level == 0)
     {
-      pattern_t *pat;
-      char tempbuf[LONG_STRING];
-
-      strfcpy (tempbuf, buf->data, sizeof (tempbuf));
-      mutt_check_simple (tempbuf, sizeof (tempbuf), SimpleSearch);
-      if ((pat = mutt_pattern_comp (tempbuf, M_FULL_MSG, err)) == NULL)
+      ColorDefs[MT_COLOR_QUOTED] = fgbgattr_to_color(fg, bg, attr);
+      
+      ColorQuote[0] = ColorDefs[MT_COLOR_QUOTED];
+      for (q_level = 1; q_level < ColorQuoteUsed; q_level++)
       {
-       mutt_pattern_free (&pat);
-       return (-1);
+       if (ColorQuote[q_level] == A_NORMAL)
+         ColorQuote[q_level] = ColorDefs[MT_COLOR_QUOTED];
       }
-      r = add_pattern (&ColorIndexList, buf->data, 1, -1, -1, attr, err, 1);
-      mutt_cache_index_colors (Context);
-      set_option (OPTFORCEREDRAWINDEX);
     }
+    else
+      ColorQuote[q_level] = fgbgattr_to_color(fg, bg, attr);
   }
   else
-  {
-    /* if we have color, ignore the mono commands */
-    if (option (OPTNOCURSES)
+    ColorDefs[object] = fgbgattr_to_color(fg, bg, attr);
+
 #ifdef HAVE_COLOR
-       || has_colors ()
+# ifdef HAVE_BKGDSET
+  if (object == MT_COLOR_NORMAL && has_colors())
+    BKGDSET (MT_COLOR_NORMAL);
+# endif
 #endif
-       )
-    {
-      return 0;
-    }
 
-    if (object == MT_COLOR_QUOTED)
-    {
-      if (q_level >= ColorQuoteSize)
-      {
-       safe_realloc ((void **) &ColorQuote, (ColorQuoteSize += 2) * sizeof (int));
-       ColorQuote[ColorQuoteSize-2] = ColorDefs[MT_COLOR_QUOTED];
-       ColorQuote[ColorQuoteSize-1] = ColorDefs[MT_COLOR_QUOTED];
-      }
-      if (q_level >= ColorQuoteUsed)
-       ColorQuoteUsed = q_level + 1;
-      if (q_level == 0)
-      {
-       ColorDefs[MT_COLOR_QUOTED] = attr;
+  return (r);
+}
 
-       ColorQuote[0] = ColorDefs[MT_COLOR_QUOTED];
-       for (q_level = 1; q_level < ColorQuoteUsed; q_level++)
-       {
-         if (ColorQuote[q_level] == A_NORMAL)
-           ColorQuote[q_level] = ColorDefs[MT_COLOR_QUOTED];
-       }
-      }
-      else
-       ColorQuote[q_level] = attr;
-    }
-    else
-      ColorDefs[object] = attr;
-  }
+#ifdef HAVE_COLOR
 
-  return (r);
+int mutt_parse_color(BUFFER *buff, BUFFER *s, unsigned long data, BUFFER *err)
+{
+  int dry_run = 0;
+  
+  if(option(OPTNOCURSES) || !has_colors())
+    dry_run = 1;
+  
+  return _mutt_parse_color(buff, s, err, parse_color_pair, dry_run);
+}
+
+#endif
+
+int mutt_parse_mono(BUFFER *buff, BUFFER *s, unsigned long data, BUFFER *err)
+{
+  int dry_run = 0;
+  
+  if(option(OPTNOCURSES) || has_colors())
+    dry_run = 1;
+  
+  return _mutt_parse_color(buff, s, err, parse_attr_spec, dry_run);
 }
+
index 0144238f7ef7905d4e2044f7466e8a8405039245..2536a790cd45bbccefa3ae178051ba1bef7380e9 100644 (file)
@@ -103,14 +103,14 @@ static int is_mmnoask (const char *buf)
   return (0);
 }
 
-int mutt_display_message (HEADER *cur)
+int mutt_display_message (HEADER *cur, const char *attach_msg_status)
 {
   char tempfile[_POSIX_PATH_MAX], buf[LONG_STRING];
   int rc = 0, builtin = 0;
   int cmflags = M_CM_DECODE | M_CM_DISPLAY;
   FILE *fpout;
 
-  snprintf (buf, sizeof (buf), "%s/%s", TYPE (cur->content->type),
+  snprintf (buf, sizeof (buf), "%s/%s", TYPE (cur->content),
            cur->content->subtype);
 
   if (cur->mailcap && !mutt_is_autoview (buf))
@@ -176,11 +176,11 @@ int mutt_display_message (HEADER *cur)
     return (0);
   }
 
-  if (strcmp (Pager, "builtin") == 0)
+  if (!Pager || strcmp (Pager, "builtin") == 0)
     builtin = 1;
   else
   {
-    mutt_make_string (buf, sizeof (buf), PagerFmt, Context, cur);
+    mutt_make_string (buf, sizeof (buf), NONULL(PagerFmt), Context, cur);
     fputs (buf, fpout);
     fputs ("\n\n", fpout);
   }
@@ -208,12 +208,12 @@ int mutt_display_message (HEADER *cur)
     memset (&info, 0, sizeof (pager_t));
     info.hdr = cur;
     info.ctx = Context;
-    rc = mutt_pager (NULL, tempfile, 1, &info);
+    rc = mutt_pager (NULL, tempfile, 1, &info, attach_msg_status);
   }
   else
   {
     endwin ();
-    snprintf (buf, sizeof (buf), "%s %s", Pager, tempfile);
+    snprintf (buf, sizeof (buf), "%s %s", NONULL(Pager), tempfile);
     mutt_system (buf);
     unlink (tempfile);
     keypad (stdscr, TRUE);
@@ -455,13 +455,16 @@ void mutt_shell_escape (void)
   buf[0] = 0;
   if (mutt_get_field ("Shell command: ", buf, sizeof (buf), M_CMD) == 0)
   {
-    if (!buf[0])
+    if (!buf[0] && Shell)
       strfcpy (buf, Shell, sizeof (buf));
-    CLEARLINE (LINES-1);
-    endwin ();
-    fflush (stdout);
-    if (mutt_system (buf) != 0 || option (OPTWAITKEY))
-      mutt_any_key_to_continue (NULL);
+    if(buf[0])
+    {
+      CLEARLINE (LINES-1);
+      endwin ();
+      fflush (stdout);
+      if (mutt_system (buf) != 0 || option (OPTWAITKEY))
+       mutt_any_key_to_continue (NULL);
+    }
   }
 }
 
@@ -506,58 +509,6 @@ void mutt_display_address (ADDRESS *adr)
   mutt_message ("%s", buf);
 }
 
-/* returns 1 if OK to proceed, 0 to abort */
-static int save_confirm_func (const char *s, struct stat *st)
-{
-  char tmp[_POSIX_PATH_MAX];
-  int ret = 1;
-  int magic = 0;
-
-  magic = mx_get_magic (s);
-
-  if (stat (s, st) != -1)
-  {
-    if (magic == -1)
-    {
-      mutt_error ("%s is not a mailbox!", s);
-      return 0;
-    }
-
-    if (option (OPTCONFIRMAPPEND))
-    {
-      snprintf (tmp, sizeof (tmp), "Append messages to %s?", s);
-      if (mutt_yesorno (tmp, 1) < 1)
-       ret = 0;
-    }
-  }
-  else
-  {
-    if (magic != M_IMAP)
-    {
-      st->st_mtime = 0;
-      st->st_atime = 0;
-
-      if (errno == ENOENT)
-      {
-       if (option (OPTCONFIRMCREATE))
-       {
-         snprintf (tmp, sizeof (tmp), "Create %s?", s);
-         if (mutt_yesorno (tmp, 1) < 1)
-           ret = 0;
-       }
-      }
-      else
-      {
-       mutt_perror (s);
-       return 0;
-      }
-    }
-  }
-
-  CLEARLINE (LINES-1);
-  return (ret);
-}
-
 /* returns 0 if the copy/save was successful, or -1 on error/abort */
 int mutt_save_message (HEADER *h, int delete, int decode, int *redraw)
 {
@@ -627,7 +578,7 @@ int mutt_save_message (HEADER *h, int delete, int decode, int *redraw)
   mutt_expand_path (buf, sizeof (buf));
 
   /* check to make sure that this file is really the one the user wants */
-  if (!save_confirm_func (buf, &st))
+  if (!mutt_save_confirm (buf, &st))
   {
     CLEARLINE (LINES-1);
     return (-1);
@@ -640,7 +591,16 @@ int mutt_save_message (HEADER *h, int delete, int decode, int *redraw)
     if (h)
     {
       if (decode)
+      {
        mutt_parse_mime_message (Context, h);
+#ifdef _PGPPATH
+       if((h->pgp & PGPENCRYPT) && !pgp_valid_passphrase())
+       {
+         mx_close_mailbox (&ctx);
+         return (-1);
+       }
+#endif /* _PGPPATH */
+      }
       if (mutt_append_message (&ctx, Context, h, cmflags, chflags) == 0 && delete)
       {
        mutt_set_flag (Context, h, M_DELETE, 1);
@@ -655,7 +615,13 @@ int mutt_save_message (HEADER *h, int delete, int decode, int *redraw)
        {
          h = Context->hdrs[Context->v2r[i]];
          if (decode)
+         {
            mutt_parse_mime_message (Context, h);
+#ifdef _PGPPATH
+           if((h->pgp & PGPENCRYPT) && !pgp_valid_passphrase())
+             continue;
+#endif /* _PGPPATH */
+         }
          mutt_append_message (&ctx, Context, h, cmflags, chflags);
          if (delete)
          {
@@ -712,7 +678,7 @@ static void print_msg (FILE *fp, CONTEXT *ctx, HEADER *h)
 
 
   mutt_parse_mime_message (ctx, h);
-  mutt_copy_message (fp, ctx, h, M_CM_DECODE, CH_WEED | CH_DECODE);
+  mutt_copy_message (fp, ctx, h, M_CM_DECODE, CH_WEED | CH_DECODE | CH_REORDER);
 }
 
 void mutt_print_message (HEADER *h)
@@ -725,7 +691,7 @@ void mutt_print_message (HEADER *h)
                        h ? "Print message?" : "Print tagged messages?") != M_YES)
     return;
   endwin ();
-  if ((thepid = mutt_create_filter (PrintCmd, &fp, NULL, NULL)) == -1)
+  if ((thepid = mutt_create_filter (NONULL(PrintCmd), &fp, NULL, NULL)) == -1)
     return;
   if (h)
   {
index 5c2dfac5ce14d362fc0f784f86b228afedb660b5..5f9c0e38047152ba4561d58d9f5c5a9f8b3fc59e 100644 (file)
--- a/compose.c
+++ b/compose.c
@@ -23,6 +23,8 @@
 #include "mime.h"
 #include "attach.h"
 #include "mapping.h"
+#include "mailbox.h"
+#include "sort.h"
 
 #include <string.h>
 #include <sys/stat.h>
@@ -71,40 +73,9 @@ static struct mapping_t ComposeHelp[] = {
 
 void snd_entry (char *b, size_t blen, MUTTMENU *menu, int num)
 {
-  char t[SHORT_STRING], size[SHORT_STRING];
-  char tmp[_POSIX_PATH_MAX];
-  BODY *m;
-  ATTACHPTR **idx = (ATTACHPTR **) menu->data;
-  struct stat finfo;
-
-  m = idx[num]->content;
-
-  if (m->filename && m->filename[0])
-  {
-    if (stat (m->filename, &finfo) != -1)
-      mutt_pretty_size (size, sizeof (size), finfo.st_size);
-    else
-      strcpy (size, "0K");
-    strfcpy (tmp, m->filename, sizeof (tmp));
-  }
-  else
-  {
-    strcpy (size, "0K");
-    strcpy (tmp, "<no file>");
-  }
-  mutt_pretty_mailbox (tmp);
-
-  snprintf (t, sizeof (t), "[%.7s/%.10s, %.6s, %s]",
-           TYPE (m->type), m->subtype, ENCODING (m->encoding), size);
-
-  snprintf (b, blen, "%c%c%2d %-34.34s %s%s <%s>",
-           m->unlink ? '-' : ' ',
-           m->tagged ? '*' : ' ',
-           num + 1,
-           t,
-           idx[num]->tree ? idx[num]->tree : "",
-           tmp,
-           m->description ? m->description : "no description");
+    mutt_FormatString (b, blen, NONULL (AttachFormat), mutt_attach_fmt,
+           (unsigned long)(((ATTACHPTR **) menu->data)[num]),
+           M_FORMAT_STAT_FILE);
 }
 
 
@@ -172,7 +143,7 @@ static int pgp_send_menu (int bits)
       else
       {
        /* Copy the existing MIC algorithm into place */
-       strfcpy(input_micalg, PgpSignMicalg, sizeof(input_micalg));
+       strfcpy(input_micalg, NONULL(PgpSignMicalg), sizeof(input_micalg));
 
        if(mutt_get_field("MIC algorithm: ", input_micalg, sizeof(input_micalg), 0) == 0)
        {
@@ -210,7 +181,39 @@ static int pgp_send_menu (int bits)
 }
 #endif /* _PGPPATH */
 
+static int
+check_attachments(ATTACHPTR **idx, short idxlen)
+{
+  int i, r;
+  struct stat st;
+  char pretty[_POSIX_PATH_MAX], msg[_POSIX_PATH_MAX + SHORT_STRING];
+
+  for (i = 0; i < idxlen; i++)
+  {
+    strfcpy(pretty, idx[i]->content->filename, sizeof(pretty));
+    if(stat(idx[i]->content->filename, &st) != 0)
+    {
+      mutt_pretty_mailbox(pretty);
+      mutt_error("%s [#%d] no longer exists!",
+                pretty, i+1);
+      return -1;
+    }
+    
+    if(idx[i]->content->stamp < st.st_mtime)
+    {
+      mutt_pretty_mailbox(pretty);
+      snprintf(msg, sizeof(msg), "%s [#%d] modified. Update encoding?",
+              pretty, i+1);
+      
+      if((r = mutt_yesorno(msg, M_YES)) == M_YES)
+       mutt_update_encoding(idx[i]->content);
+      else if(r == -1)
+       return -1;
+    }
+  }
 
+  return 0;
+}
 
 static void draw_envelope (HEADER *msg, char *fcc)
 {
@@ -336,13 +339,13 @@ static int edit_address_list (int line, ENVELOPE *env)
   }
 
   rfc822_write_address (buf, sizeof (buf), *addr);
-  if (mutt_get_field (prompt, buf, sizeof (buf), M_ALIAS) != 0)
-    return 0;
-
-  rfc822_free_address (addr);
-  *addr = mutt_parse_adrlist (*addr, buf);
-  *addr = mutt_expand_aliases (*addr);
-
+  if (mutt_get_field (prompt, buf, sizeof (buf), M_ALIAS) == 0)
+  {
+    rfc822_free_address (addr);
+    *addr = mutt_parse_adrlist (*addr, buf);
+    *addr = mutt_expand_aliases (*addr);
+  }
+  
   if (option (OPTNEEDREDRAW))
   {
     unset_option (OPTNEEDREDRAW);
@@ -393,6 +396,18 @@ static int delete_attachment (MUTTMENU *menu, short *idxlen, int x)
   return (0);
 }
 
+static void update_idx (MUTTMENU *menu, ATTACHPTR **idx, short idxlen)
+{
+  idx[idxlen]->level = (idxlen > 0) ? idx[idxlen-1]->level : 0;
+  if (idxlen)
+    idx[idxlen - 1]->content->next = idx[idxlen]->content;
+  menu->current = idxlen++;
+  mutt_update_tree (idx, idxlen);
+  menu->max = idxlen;
+  return;
+}
+
+
 /* return values:
  *
  * 1   message should be postponed
@@ -411,11 +426,16 @@ int mutt_send_menu (HEADER *msg,   /* structure for new message */
   ATTACHPTR **idx = NULL;
   short idxlen = 0;
   short idxmax = 0;
-  int i;
+  int i, close = 0;
   int r = -1;          /* return value */
   int op = 0;
   int loop = 1;
   int fccSet = 0;      /* has the user edited the Fcc: field ? */
+  CONTEXT *ctx = NULL, *this = NULL;
+  /* Sort, SortAux could be changed in mutt_index_menu() */
+  int oldSort = Sort, oldSortAux = SortAux;
+  HEADER **hdrs = NULL;
+  struct stat st;
 
   idx = mutt_gen_attach_list (msg->content, idx, &idxlen, &idxmax, 0, 1);
 
@@ -482,7 +502,7 @@ int mutt_send_menu (HEADER *msg,   /* structure for new message */
        MAYBE_REDRAW (menu->redraw);
        break;
       case OP_COMPOSE_EDIT_MESSAGE:
-       if (strcmp ("builtin", Editor) != 0 && !option (OPTEDITHDRS))
+       if (Editor && (strcmp ("builtin", Editor) != 0) && !option (OPTEDITHDRS))
        {
          mutt_edit_file (Editor, msg->content->filename);
          mutt_update_encoding (msg->content);
@@ -494,7 +514,7 @@ int mutt_send_menu (HEADER *msg,   /* structure for new message */
        if (op == OP_COMPOSE_EDIT_HEADERS ||
            (op == OP_COMPOSE_EDIT_MESSAGE && option (OPTEDITHDRS)))
        {
-         mutt_edit_headers (strcmp ("builtin", Editor) == 0 ? Visual : Editor,
+         mutt_edit_headers ((!Editor || strcmp ("builtin", Editor) == 0) ? NONULL(Visual) : NONULL(Editor),
                             msg->content->filename, msg, fcc, fcclen);
        }
        else
@@ -514,6 +534,7 @@ int mutt_send_menu (HEADER *msg,   /* structure for new message */
            safe_free ((void **) &idx[i]);
          idxlen = 0;
          idx = mutt_gen_attach_list (msg->content, idx, &idxlen, &idxmax, 0, 1);
+         menu->data = idx;
          menu->max = idxlen;
        }
 
@@ -571,10 +592,33 @@ int mutt_send_menu (HEADER *msg,   /* structure for new message */
 
 
       case OP_COMPOSE_ATTACH_FILE:
+      case OP_COMPOSE_ATTACH_MESSAGE:
+
        fname[0] = 0;
-       if (mutt_enter_fname ("Attach file", fname, sizeof (fname),
-                             &menu->redraw, 0) == -1)
-         break;
+       {
+         char* prompt;
+         int flag;
+
+         if (op == OP_COMPOSE_ATTACH_FILE)
+         {
+           prompt = "Attach file";
+           flag = 0;
+         }
+         else
+         {
+           prompt = "Open mailbox to attach message from";
+           if (Context)
+           {
+             strfcpy (fname, NONULL (Context->path), sizeof (fname));
+             mutt_pretty_mailbox (fname);
+           }
+           flag = 1;
+         }
+
+         if (mutt_enter_fname (prompt, fname, sizeof (fname), &menu->redraw, flag) == -1)
+           break;
+       }
+
        if (!fname[0])
          continue;
        mutt_expand_path (fname, sizeof (fname));
@@ -586,29 +630,100 @@ int mutt_send_menu (HEADER *msg,   /* structure for new message */
          break;
        }
 
-       if (idxlen == idxmax)
+       if (op == OP_COMPOSE_ATTACH_MESSAGE)
        {
-         safe_realloc ((void **) &idx, sizeof (ATTACHPTR *) * (idxmax += 5));
-         menu->data = idx;
-       }
+         menu->redraw = REDRAW_FULL;
 
-       idx[idxlen] = (ATTACHPTR *) safe_calloc (1, sizeof (ATTACHPTR));
-       if ((idx[idxlen]->content = mutt_make_attach (fname)) != NULL)
-       {
-         idx[idxlen]->level = (idxlen > 0) ? idx[idxlen-1]->level : 0;
+         ctx = mx_open_mailbox (fname, M_READONLY, NULL);
+         if (ctx == NULL)
+         {
+           mutt_perror (fname);
+           break;
+         }
 
-         if (idxlen)
-           idx[idxlen - 1]->content->next = idx[idxlen]->content;
+         if (!ctx->msgcount)
+         {
+           mx_close_mailbox (ctx);
+           safe_free ((void **) &ctx);
+           mutt_error ("No messages in that folder.");
+           break;
+         }
+         
+         {
+           int i, j;
+           this = Context; /* remember current folder */
+           
+           Context = ctx;
+           close = mutt_index_menu (1);
+           /* allocate memory to store pointers to tagged headers */
+           hdrs = safe_calloc (Context->tagged, sizeof (HEADER *));
+           for (i=0, j=0; i < Context->vcount; i++)
+           {
+             HEADER *cur = Context->hdrs[Context->v2r[i]];
+             /* store the headers of the tagged messages */
+             if (cur->tagged) hdrs[j++] = cur;
+          }
+         }
+       }
+        {
+         int numtag = 0;
 
-         menu->current = idxlen++;
-         mutt_update_tree (idx, idxlen);
-         menu->max = idxlen;
-         menu->redraw |= REDRAW_INDEX | REDRAW_STATUS;
+         if (op == OP_COMPOSE_ATTACH_MESSAGE)
+           numtag = Context->tagged;
+         if (idxlen + numtag >= idxmax)
+       {
+           safe_realloc ((void **) &idx, sizeof (ATTACHPTR *) * (idxmax += 5 + numtag));
+         menu->data = idx;
        }
+       }
+
+       if (op == OP_COMPOSE_ATTACH_FILE)
+       {
+         idx[idxlen] = (ATTACHPTR *) safe_calloc (1, sizeof (ATTACHPTR));
+         idx[idxlen]->content = mutt_make_file_attach (fname);
+         if (idx[idxlen]->content != NULL)
+          update_idx (menu, idx, idxlen);
+         else
+         {
+          mutt_error ("Unable to attach!");
+          safe_free ((void **) &idx[idxlen]);
+         }
+        menu->redraw |= REDRAW_INDEX | REDRAW_STATUS;
+        idxlen++;
+         break;
+        }
        else
        {
-         mutt_error ("Unable to attach file!");
-         safe_free ((void **) &idx[idxlen]);
+        int i = 0;
+        /* Did we tag any messages? */
+        while (Context->tagged--)
+        {
+          idx[idxlen] = (ATTACHPTR *) safe_calloc (1, sizeof (ATTACHPTR));
+          idx[idxlen]->content = mutt_make_message_attach (Context, hdrs[i], 1);
+          i++;
+          if (idx[idxlen]->content != NULL)
+            update_idx (menu, idx, idxlen);
+          else
+          {
+            mutt_error ("Unable to attach!");
+            safe_free ((void **) &idx[idxlen]);
+          }
+          idxlen++;
+        }
+        menu->redraw |= REDRAW_FULL;
+
+         if (close == OP_QUIT) 
+          mx_close_mailbox (Context);
+        else
+          mx_fastclose_mailbox (Context);
+        safe_free ((void **) &Context);
+        FREE (&hdrs);
+        
+        /* go back to the folder we started from */
+        Context = this;
+        /* Restore old $sort and $sort_aux */
+        Sort = oldSort;
+        SortAux = oldSortAux;
        }
        break;
 
@@ -643,10 +758,16 @@ int mutt_send_menu (HEADER *msg,   /* structure for new message */
        }
        break;
 
+      case OP_COMPOSE_UPDATE_ENCODING:
+        CHECK_COUNT;
+        mutt_update_encoding(idx[menu->current]->content);
+        menu->redraw = REDRAW_CURRENT;
+        break;
+      
       case OP_COMPOSE_EDIT_TYPE:
        CHECK_COUNT;
        snprintf (buf, sizeof (buf), "%s/%s",
-                 TYPE (idx[menu->current]->content->type),
+                 TYPE (idx[menu->current]->content),
                  idx[menu->current]->content->subtype);
        if (mutt_get_field ("Content-Type: ", buf, sizeof (buf), 0) == 0 && buf[0])
        {
@@ -684,6 +805,13 @@ int mutt_send_menu (HEADER *msg,   /* structure for new message */
        break;
 
       case OP_COMPOSE_SEND_MESSAGE:
+      
+        if(check_attachments(idx, idxlen) != 0)
+        {
+         menu->redraw = REDRAW_FULL;
+         break;
+       }
+      
        if (!fccSet && *fcc)
        {
          if ((i = query_quadoption (OPT_COPY, "Save a copy of this message?"))
@@ -699,7 +827,7 @@ int mutt_send_menu (HEADER *msg,   /* structure for new message */
 
       case OP_COMPOSE_EDIT_FILE:
        CHECK_COUNT;
-       mutt_edit_file (strcmp ("builtin", Editor) == 0 ? Visual : Editor,
+       mutt_edit_file ((!Editor || strcmp ("builtin", Editor) == 0) ? NONULL(Visual) : NONULL(Editor),
                        idx[menu->current]->content->filename);
        mutt_update_encoding (idx[menu->current]->content);
        menu->redraw = REDRAW_CURRENT;
@@ -718,13 +846,23 @@ int mutt_send_menu (HEADER *msg,   /* structure for new message */
        if (mutt_get_field ("Rename to: ", fname, sizeof (fname), M_FILE) == 0
                                                                  && fname[0])
        {
-         mutt_expand_path (fname, sizeof (fname));
-         if (!mutt_rename_file (idx[menu->current]->content->filename, fname))
+         if(stat(idx[menu->current]->content->filename, &st) == -1)
          {
-           safe_free ((void **) &idx[menu->current]->content->filename);
-           idx[menu->current]->content->filename = safe_strdup (fname);
-           menu->redraw = REDRAW_CURRENT;
+           mutt_error("Can't stat: %s", fname);
+           break;
          }
+
+         mutt_expand_path (fname, sizeof (fname));
+         if(mutt_rename_file (idx[menu->current]->content->filename, fname))
+           break;
+         
+         safe_free ((void **) &idx[menu->current]->content->filename);
+         idx[menu->current]->content->filename = safe_strdup (fname);
+         menu->redraw = REDRAW_CURRENT;
+
+         if(idx[menu->current]->content->stamp >= st.st_mtime)
+           mutt_stamp_attachment(idx[menu->current]->content);
+         
        }
        break;
 
@@ -775,7 +913,7 @@ int mutt_send_menu (HEADER *msg,   /* structure for new message */
          }
          fclose (fp);
 
-         if ((idx[idxlen]->content = mutt_make_attach (fname)) == NULL)
+         if ((idx[idxlen]->content = mutt_make_file_attach (fname)) == NULL)
          {
            mutt_error ("What we have here is a failure to make an attachment");
            continue;
@@ -810,7 +948,7 @@ int mutt_send_menu (HEADER *msg,   /* structure for new message */
 
       case OP_COMPOSE_EDIT_MIME:
        CHECK_COUNT;
-       if (mutt_edit_attachment (idx[menu->current]->content, 0))
+       if (mutt_edit_attachment (idx[menu->current]->content))
        {
          mutt_update_encoding (idx[menu->current]->content);
          menu->redraw = REDRAW_FULL;
@@ -827,7 +965,7 @@ int mutt_send_menu (HEADER *msg,   /* structure for new message */
 
       case OP_SAVE:
        CHECK_COUNT;
-       mutt_save_attachment_list (NULL, menu->tagprefix, menu->tagprefix ? msg->content : idx[menu->current]->content);
+       mutt_save_attachment_list (NULL, menu->tagprefix, menu->tagprefix ?  msg->content : idx[menu->current]->content, NULL);
        break;
 
       case OP_PRINT:
@@ -839,8 +977,8 @@ int mutt_send_menu (HEADER *msg,   /* structure for new message */
       case OP_FILTER:
         CHECK_COUNT;
        mutt_pipe_attachment_list (NULL, menu->tagprefix, menu->tagprefix ? msg->content : idx[menu->current]->content, op == OP_FILTER);
-       if (op == OP_FILTER)
-         menu->redraw = REDRAW_CURRENT; /* cte might have changed */
+       if (op == OP_FILTER) /* cte might have changed */
+         menu->redraw = menu->tagprefix ? REDRAW_FULL : REDRAW_CURRENT; 
        break;
 
 
@@ -873,14 +1011,22 @@ int mutt_send_menu (HEADER *msg,   /* structure for new message */
        /* fall through to postpone! */
 
       case OP_COMPOSE_POSTPONE_MESSAGE:
+      
+        if(check_attachments(idx, idxlen) != 0)
+        {
+         menu->redraw = REDRAW_FULL;
+         break;
+       }
+      
        loop = 0;
        r = 1;
        break;
 
       case OP_COMPOSE_ISPELL:
        endwin ();
-       snprintf (buf, sizeof (buf), "%s -x %s", Ispell, msg->content->filename);
+       snprintf (buf, sizeof (buf), "%s -x %s", NONULL(Ispell), msg->content->filename);
        mutt_system (buf);
+        mutt_update_encoding(msg->content);
        break;
 
 
diff --git a/config.guess b/config.guess
new file mode 100755 (executable)
index 0000000..30230b3
--- /dev/null
@@ -0,0 +1,890 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright (C) 1992, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
+#
+# This file 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Written by Per Bothner <bothner@cygnus.com>.
+# The master version of this file is at the FSF in /home/gd/gnu/lib.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub.  If it succeeds, it prints the system name on stdout, and
+# exits with 0.  Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit system type (host/target name).
+#
+# Only a few systems have been added to this list; please add others
+# (but try to keep the structure clean).
+#
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 8/24/94.)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+       PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+trap 'rm -f dummy.c dummy.o dummy; exit 1' 1 2 15
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+    alpha:OSF1:*:*)
+       if test $UNAME_RELEASE = "V4.0"; then
+               UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+       fi
+       # A Vn.n version is a released version.
+       # A Tn.n version is a released field test version.
+       # A Xn.n version is an unreleased experimental baselevel.
+       # 1.2 uses "1.2" for uname -r.
+       cat <<EOF >dummy.s
+       .globl main
+       .ent main
+main:
+       .frame \$30,0,\$26,0
+       .prologue 0
+       .long 0x47e03d80 # implver $0
+       lda \$2,259
+       .long 0x47e20c21 # amask $2,$1
+       srl \$1,8,\$2
+       sll \$2,2,\$2
+       sll \$0,3,\$0
+       addl \$1,\$0,\$0
+       addl \$2,\$0,\$0
+       ret \$31,(\$26),1
+       .end main
+EOF
+       ${CC-cc} dummy.s -o dummy 2>/dev/null
+       if test "$?" = 0 ; then
+               ./dummy
+               case "$?" in
+                       7)
+                               UNAME_MACHINE="alpha"
+                               ;;
+                       15)
+                               UNAME_MACHINE="alphaev5"
+                               ;;
+                       14)
+                               UNAME_MACHINE="alphaev56"
+                               ;;
+                       10)
+                               UNAME_MACHINE="alphapca56"
+                               ;;
+                       16)
+                               UNAME_MACHINE="alphaev6"
+                               ;;
+               esac
+       fi
+       rm -f dummy.s dummy
+       echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr [[A-Z]] [[a-z]]`
+       exit 0 ;;
+    21064:Windows_NT:50:3)
+       echo alpha-dec-winnt3.5
+       exit 0 ;;
+    Amiga*:UNIX_System_V:4.0:*)
+       echo m68k-cbm-sysv4
+       exit 0;;
+    amiga:NetBSD:*:*)
+      echo m68k-cbm-netbsd${UNAME_RELEASE}
+      exit 0 ;;
+    amiga:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    arc64:OpenBSD:*:*)
+       echo mips64el-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    arc:OpenBSD:*:*)
+       echo mipsel-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    hkmips:OpenBSD:*:*)
+       echo mips-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    pmax:OpenBSD:*:*)
+       echo mipsel-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    sgi:OpenBSD:*:*)
+       echo mips-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    wgrisc:OpenBSD:*:*)
+       echo mipsel-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+       echo arm-acorn-riscix${UNAME_RELEASE}
+       exit 0;;
+    arm32:NetBSD:*:*)
+       echo arm-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+       exit 0 ;;
+    SR2?01:HI-UX/MPP:*:*)
+       echo hppa1.1-hitachi-hiuxmpp
+       exit 0;;
+    Pyramid*:OSx*:*:*|MIS*:OSx*:*:*)
+       # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+       if test "`(/bin/universe) 2>/dev/null`" = att ; then
+               echo pyramid-pyramid-sysv3
+       else
+               echo pyramid-pyramid-bsd
+       fi
+       exit 0 ;;
+    NILE:*:*:dcosx)
+       echo pyramid-pyramid-svr4
+       exit 0 ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+       echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    i86pc:SunOS:5.*:*)
+       echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    sun4*:SunOS:6*:*)
+       # According to config.sub, this is the proper way to canonicalize
+       # SunOS6.  Hard to guess exactly what SunOS6 will be like, but
+       # it's likely to be more like Solaris than SunOS4.
+       echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    sun4*:SunOS:*:*)
+       case "`/usr/bin/arch -k`" in
+           Series*|S4*)
+               UNAME_RELEASE=`uname -v`
+               ;;
+       esac
+       # Japanese Language versions have a version number like `4.1.3-JL'.
+       echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+       exit 0 ;;
+    sun3*:SunOS:*:*)
+       echo m68k-sun-sunos${UNAME_RELEASE}
+       exit 0 ;;
+    sun*:*:4.2BSD:*)
+       UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+       test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+       case "`/bin/arch`" in
+           sun3)
+               echo m68k-sun-sunos${UNAME_RELEASE}
+               ;;
+           sun4)
+               echo sparc-sun-sunos${UNAME_RELEASE}
+               ;;
+       esac
+       exit 0 ;;
+    aushp:SunOS:*:*)
+       echo sparc-auspex-sunos${UNAME_RELEASE}
+       exit 0 ;;
+    atari*:NetBSD:*:*)
+       echo m68k-atari-netbsd${UNAME_RELEASE}
+       exit 0 ;;
+    atari*:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    sun3*:NetBSD:*:*)
+       echo m68k-sun-netbsd${UNAME_RELEASE}
+       exit 0 ;;
+    sun3*:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mac68k:NetBSD:*:*)
+       echo m68k-apple-netbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mac68k:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mvme68k:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mvme88k:OpenBSD:*:*)
+       echo m88k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    powerpc:machten:*:*)
+       echo powerpc-apple-machten${UNAME_RELEASE}
+       exit 0 ;;
+    RISC*:Mach:*:*)
+       echo mips-dec-mach_bsd4.3
+       exit 0 ;;
+    RISC*:ULTRIX:*:*)
+       echo mips-dec-ultrix${UNAME_RELEASE}
+       exit 0 ;;
+    VAX*:ULTRIX*:*:*)
+       echo vax-dec-ultrix${UNAME_RELEASE}
+       exit 0 ;;
+    2020:CLIX:*:*)
+       echo clipper-intergraph-clix${UNAME_RELEASE}
+       exit 0 ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+       sed 's/^        //' << EOF >dummy.c
+       int main (argc, argv) int argc; char **argv; {
+       #if defined (host_mips) && defined (MIPSEB)
+       #if defined (SYSTYPE_SYSV)
+         printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+       #endif
+       #if defined (SYSTYPE_SVR4)
+         printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+       #endif
+       #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+         printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+       #endif
+       #endif
+         exit (-1);
+       }
+EOF
+       ${CC-cc} dummy.c -o dummy \
+         && ./dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
+         && rm dummy.c dummy && exit 0
+       rm -f dummy.c dummy
+       echo mips-mips-riscos${UNAME_RELEASE}
+       exit 0 ;;
+    Night_Hawk:Power_UNIX:*:*)
+       echo powerpc-harris-powerunix
+       exit 0 ;;
+    m88k:CX/UX:7*:*)
+       echo m88k-harris-cxux7
+       exit 0 ;;
+    m88k:*:4*:R4*)
+       echo m88k-motorola-sysv4
+       exit 0 ;;
+    m88k:*:3*:R3*)
+       echo m88k-motorola-sysv3
+       exit 0 ;;
+    AViiON:dgux:*:*)
+        # DG/UX returns AViiON for all architectures
+        UNAME_PROCESSOR=`/usr/bin/uname -p`
+        if [ $UNAME_PROCESSOR = mc88100 -o $UNAME_PROCESSOR = mc88110 ] ; then
+       if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \
+            -o ${TARGET_BINARY_INTERFACE}x = x ] ; then
+               echo m88k-dg-dgux${UNAME_RELEASE}
+       else
+               echo m88k-dg-dguxbcs${UNAME_RELEASE}
+       fi
+        else echo i586-dg-dgux${UNAME_RELEASE}
+        fi
+       exit 0 ;;
+    M88*:DolphinOS:*:*)        # DolphinOS (SVR3)
+       echo m88k-dolphin-sysv3
+       exit 0 ;;
+    M88*:*:R3*:*)
+       # Delta 88k system running SVR3
+       echo m88k-motorola-sysv3
+       exit 0 ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+       echo m88k-tektronix-sysv3
+       exit 0 ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+       echo m68k-tektronix-bsd
+       exit 0 ;;
+    *:IRIX*:*:*)
+       echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+       exit 0 ;;
+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+       echo romp-ibm-aix      # uname -m gives an 8 hex-code CPU id
+       exit 0 ;;              # Note that: echo "'`uname -s`'" gives 'AIX '
+    i?86:AIX:*:*)
+       echo i386-ibm-aix
+       exit 0 ;;
+    *:AIX:2:3)
+       if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+               sed 's/^                //' << EOF >dummy.c
+               #include <sys/systemcfg.h>
+
+               main()
+                       {
+                       if (!__power_pc())
+                               exit(1);
+                       puts("powerpc-ibm-aix3.2.5");
+                       exit(0);
+                       }
+EOF
+               ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0
+               rm -f dummy.c dummy
+               echo rs6000-ibm-aix3.2.5
+       elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+               echo rs6000-ibm-aix3.2.4
+       else
+               echo rs6000-ibm-aix3.2
+       fi
+       exit 0 ;;
+    *:AIX:*:4)
+       if /usr/sbin/lsattr -EHl proc0 | grep POWER >/dev/null 2>&1; then
+               IBM_ARCH=rs6000
+       else
+               IBM_ARCH=powerpc
+       fi
+       if [ -x /usr/bin/oslevel ] ; then
+               IBM_REV=`/usr/bin/oslevel`
+       else
+               IBM_REV=4.${UNAME_RELEASE}
+       fi
+       echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+       exit 0 ;;
+    *:AIX:*:*)
+       echo rs6000-ibm-aix
+       exit 0 ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+       echo romp-ibm-bsd4.4
+       exit 0 ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC NetBSD and
+       echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+       exit 0 ;;                           # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+       echo rs6000-bull-bosx
+       exit 0 ;;
+    DPX/2?00:B.O.S.:*:*)
+       echo m68k-bull-sysv3
+       exit 0 ;;
+    9000/[34]??:4.3bsd:1.*:*)
+       echo m68k-hp-bsd
+       exit 0 ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+       echo m68k-hp-bsd4.4
+       exit 0 ;;
+    9000/[3478]??:HP-UX:*:*)
+       case "${UNAME_MACHINE}" in
+           9000/31? )            HP_ARCH=m68000 ;;
+           9000/[34]?? )         HP_ARCH=m68k ;;
+           9000/7?? | 9000/8?[1679] ) HP_ARCH=hppa1.1 ;;
+           9000/8?? )            HP_ARCH=hppa1.0 ;;
+       esac
+       HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+       echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+       exit 0 ;;
+    3050*:HI-UX:*:*)
+       sed 's/^        //' << EOF >dummy.c
+       #include <unistd.h>
+       int
+       main ()
+       {
+         long cpu = sysconf (_SC_CPU_VERSION);
+         /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+            true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
+            results, however.  */
+         if (CPU_IS_PA_RISC (cpu))
+           {
+             switch (cpu)
+               {
+                 case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+                 case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+                 case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+                 default: puts ("hppa-hitachi-hiuxwe2"); break;
+               }
+           }
+         else if (CPU_IS_HP_MC68K (cpu))
+           puts ("m68k-hitachi-hiuxwe2");
+         else puts ("unknown-hitachi-hiuxwe2");
+         exit (0);
+       }
+EOF
+       ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0
+       rm -f dummy.c dummy
+       echo unknown-hitachi-hiuxwe2
+       exit 0 ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+       echo hppa1.1-hp-bsd
+       exit 0 ;;
+    9000/8??:4.3bsd:*:*)
+       echo hppa1.0-hp-bsd
+       exit 0 ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+       echo hppa1.1-hp-osf
+       exit 0 ;;
+    hp8??:OSF1:*:*)
+       echo hppa1.0-hp-osf
+       exit 0 ;;
+    i?86:OSF1:*:*)
+       if [ -x /usr/sbin/sysversion ] ; then
+           echo ${UNAME_MACHINE}-unknown-osf1mk
+       else
+           echo ${UNAME_MACHINE}-unknown-osf1
+       fi
+       exit 0 ;;
+    parisc*:Lites*:*:*)
+       echo hppa1.1-hp-lites
+       exit 0 ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+       echo c1-convex-bsd
+        exit 0 ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+       if getsysinfo -f scalar_acc
+       then echo c32-convex-bsd
+       else echo c2-convex-bsd
+       fi
+        exit 0 ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+       echo c34-convex-bsd
+        exit 0 ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+       echo c38-convex-bsd
+        exit 0 ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+       echo c4-convex-bsd
+        exit 0 ;;
+    CRAY*X-MP:*:*:*)
+       echo xmp-cray-unicos
+        exit 0 ;;
+    CRAY*Y-MP:*:*:*)
+       echo ymp-cray-unicos${UNAME_RELEASE}
+       exit 0 ;;
+    CRAY*[A-Z]90:*:*:*)
+       echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+       | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+             -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
+       exit 0 ;;
+    CRAY*TS:*:*:*)
+       echo t90-cray-unicos${UNAME_RELEASE}
+       exit 0 ;;
+    CRAY-2:*:*:*)
+       echo cray2-cray-unicos
+        exit 0 ;;
+    F300:UNIX_System_V:*:*)
+        FUJITSU_SYS=`uname -p | tr [A-Z] [a-z] | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+        echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+        exit 0 ;;
+    F301:UNIX_System_V:*:*)
+       echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'`
+       exit 0 ;;
+    hp3[0-9][05]:NetBSD:*:*)
+       echo m68k-hp-netbsd${UNAME_RELEASE}
+       exit 0 ;;
+    hp300:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    i?86:BSD/386:*:* | *:BSD/OS:*:*)
+       echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+       exit 0 ;;
+    *:FreeBSD:*:*)
+       echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+       exit 0 ;;
+    *:NetBSD:*:*)
+       echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+       exit 0 ;;
+    *:OpenBSD:*:*)
+       echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+       exit 0 ;;
+    i*:CYGWIN*:*)
+       echo ${UNAME_MACHINE}-pc-cygwin32
+       exit 0 ;;
+    i*:MINGW*:*)
+       echo ${UNAME_MACHINE}-pc-mingw32
+       exit 0 ;;
+    p*:CYGWIN*:*)
+       echo powerpcle-unknown-cygwin32
+       exit 0 ;;
+    prep*:SunOS:5.*:*)
+       echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    *:GNU:*:*)
+       echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+       exit 0 ;;
+    *:Linux:*:*)
+       # uname on the ARM produces all sorts of strangeness, and we need to
+       # filter it out.
+       case "$UNAME_MACHINE" in
+         arm* | sa110*)              UNAME_MACHINE="arm" ;;
+       esac
+
+       # The BFD linker knows what the default object file format is, so
+       # first see if it will tell us.
+       ld_help_string=`ld --help 2>&1`
+       ld_supported_emulations=`echo $ld_help_string \
+                        | sed -ne '/supported emulations:/!d
+                                   s/[         ][      ]*/ /g
+                                   s/.*supported emulations: *//
+                                   s/ .*//
+                                   p'`
+        case "$ld_supported_emulations" in
+         i?86linux)  echo "${UNAME_MACHINE}-pc-linux-gnuaout"      ; exit 0 ;;
+         i?86coff)   echo "${UNAME_MACHINE}-pc-linux-gnucoff"      ; exit 0 ;;
+         sparclinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;;
+         armlinux)   echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;;
+         m68klinux)  echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;;
+         elf32ppc)   echo "powerpc-unknown-linux-gnu"              ; exit 0 ;;
+       esac
+
+       if test "${UNAME_MACHINE}" = "alpha" ; then
+               sed 's/^        //'  <<EOF >dummy.s
+               .globl main
+               .ent main
+       main:
+               .frame \$30,0,\$26,0
+               .prologue 0
+               .long 0x47e03d80 # implver $0
+               lda \$2,259
+               .long 0x47e20c21 # amask $2,$1
+               srl \$1,8,\$2
+               sll \$2,2,\$2
+               sll \$0,3,\$0
+               addl \$1,\$0,\$0
+               addl \$2,\$0,\$0
+               ret \$31,(\$26),1
+               .end main
+EOF
+               LIBC=""
+               ${CC-cc} dummy.s -o dummy 2>/dev/null
+               if test "$?" = 0 ; then
+                       ./dummy
+                       case "$?" in
+                       7)
+                               UNAME_MACHINE="alpha"
+                               ;;
+                       15)
+                               UNAME_MACHINE="alphaev5"
+                               ;;
+                       14)
+                               UNAME_MACHINE="alphaev56"
+                               ;;
+                       10)
+                               UNAME_MACHINE="alphapca56"
+                               ;;
+                       16)
+                               UNAME_MACHINE="alphaev6"
+                               ;;
+                       esac    
+
+                       objdump --private-headers dummy | \
+                         grep ld.so.1 > /dev/null
+                       if test "$?" = 0 ; then
+                               LIBC="libc1"
+                       fi
+               fi      
+               rm -f dummy.s dummy
+               echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} ; exit 0
+       elif test "${UNAME_MACHINE}" = "mips" ; then
+         cat >dummy.c <<EOF
+main(argc, argv)
+     int argc;
+     char *argv[];
+{
+#ifdef __MIPSEB__
+  printf ("%s-unknown-linux-gnu\n", argv[1]);
+#endif
+#ifdef __MIPSEL__
+  printf ("%sel-unknown-linux-gnu\n", argv[1]);
+#endif
+  return 0;
+}
+EOF
+         ${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0
+         rm -f dummy.c dummy
+       else
+         # Either a pre-BFD a.out linker (linux-gnuoldld)
+         # or one that does not give us useful --help.
+         # GCC wants to distinguish between linux-gnuoldld and linux-gnuaout.
+         # If ld does not provide *any* "supported emulations:"
+         # that means it is gnuoldld.
+         echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations:"
+         test $? != 0 && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0
+
+         case "${UNAME_MACHINE}" in
+         i?86)
+           VENDOR=pc;
+           ;;
+         *)
+           VENDOR=unknown;
+           ;;
+         esac
+         # Determine whether the default compiler is a.out or elf
+         cat >dummy.c <<EOF
+#include <features.h>
+main(argc, argv)
+     int argc;
+     char *argv[];
+{
+#ifdef __ELF__
+# ifdef __GLIBC__
+#  if __GLIBC__ >= 2
+    printf ("%s-${VENDOR}-linux-gnu\n", argv[1]);
+#  else
+    printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
+#  endif
+# else
+   printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
+# endif
+#else
+  printf ("%s-${VENDOR}-linux-gnuaout\n", argv[1]);
+#endif
+  return 0;
+}
+EOF
+         ${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0
+         rm -f dummy.c dummy
+       fi ;;
+# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.  earlier versions
+# are messed up and put the nodename in both sysname and nodename.
+    i?86:DYNIX/ptx:4*:*)
+       echo i386-sequent-sysv4
+       exit 0 ;;
+    i?86:UNIX_SV:4.2MP:2.*)
+        # Unixware is an offshoot of SVR4, but it has its own version
+        # number series starting with 2...
+        # I am not positive that other SVR4 systems won't match this,
+       # I just have to hope.  -- rms.
+        # Use sysv4.2uw... so that sysv4* matches it.
+       echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+       exit 0 ;;
+    i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*)
+       if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+               echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE}
+       else
+               echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE}
+       fi
+       exit 0 ;;
+    i?86:*:3.2:*)
+       if test -f /usr/options/cb.name; then
+               UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+               echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+       elif /bin/uname -X 2>/dev/null >/dev/null ; then
+               UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
+               (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
+               (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
+                       && UNAME_MACHINE=i586
+               echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+       else
+               echo ${UNAME_MACHINE}-pc-sysv32
+       fi
+       exit 0 ;;
+    pc:*:*:*)
+        # uname -m prints for DJGPP always 'pc', but it prints nothing about
+        # the processor, so we play safe by assuming i386.
+       echo i386-pc-msdosdjgpp
+        exit 0 ;;
+    Intel:Mach:3*:*)
+       echo i386-pc-mach3
+       exit 0 ;;
+    paragon:*:*:*)
+       echo i860-intel-osf1
+       exit 0 ;;
+    i860:*:4.*:*) # i860-SVR4
+       if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+         echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+       else # Add other i860-SVR4 vendors below as they are discovered.
+         echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+       fi
+       exit 0 ;;
+    mini*:CTIX:SYS*5:*)
+       # "miniframe"
+       echo m68010-convergent-sysv
+       exit 0 ;;
+    M68*:*:R3V[567]*:*)
+       test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
+    3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0)
+       OS_REL=''
+       test -r /etc/.relid \
+       && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+       /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+         && echo i486-ncr-sysv4.3${OS_REL} && exit 0
+       /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+         && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+          && echo i486-ncr-sysv4 && exit 0 ;;
+    m68*:LynxOS:2.*:*)
+       echo m68k-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    mc68030:UNIX_System_V:4.*:*)
+       echo m68k-atari-sysv4
+       exit 0 ;;
+    i?86:LynxOS:2.*:*)
+       echo i386-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    TSUNAMI:LynxOS:2.*:*)
+       echo sparc-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    rs6000:LynxOS:2.*:* | PowerPC:LynxOS:2.*:*)
+       echo rs6000-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    SM[BE]S:UNIX_SV:*:*)
+       echo mips-dde-sysv${UNAME_RELEASE}
+       exit 0 ;;
+    RM*:SINIX-*:*:*)
+       echo mips-sni-sysv4
+       exit 0 ;;
+    *:SINIX-*:*:*)
+       if uname -p 2>/dev/null >/dev/null ; then
+               UNAME_MACHINE=`(uname -p) 2>/dev/null`
+               echo ${UNAME_MACHINE}-sni-sysv4
+       else
+               echo ns32k-sni-sysv
+       fi
+       exit 0 ;;
+    PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+                           # says <Richard.M.Bartel@ccMail.Census.GOV>
+        echo i586-unisys-sysv4
+        exit 0 ;;
+    *:UNIX_System_V:4*:FTX*)
+       # From Gerald Hewes <hewes@openmarket.com>.
+       # How about differentiating between stratus architectures? -djm
+       echo hppa1.1-stratus-sysv4
+       exit 0 ;;
+    *:*:*:FTX*)
+       # From seanf@swdc.stratus.com.
+       echo i860-stratus-sysv4
+       exit 0 ;;
+    mc68*:A/UX:*:*)
+       echo m68k-apple-aux${UNAME_RELEASE}
+       exit 0 ;;
+    news*:NEWS-OS:*:6*)
+       echo mips-sony-newsos6
+       exit 0 ;;
+    R3000:*System_V*:*:* | R4000:UNIX_SYSV:*:*)
+       if [ -d /usr/nec ]; then
+               echo mips-nec-sysv${UNAME_RELEASE}
+       else
+               echo mips-unknown-sysv${UNAME_RELEASE}
+       fi
+        exit 0 ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+cat >dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+          "4"
+#else
+         ""
+#endif
+         ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+       printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+       printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+#if !defined (ultrix)
+  printf ("vax-dec-bsd\n"); exit (0);
+#else
+  printf ("vax-dec-ultrix\n"); exit (0);
+#endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy && rm dummy.c dummy && exit 0
+rm -f dummy.c dummy
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+       echo c1-convex-bsd
+       exit 0 ;;
+    c2*)
+       if getsysinfo -f scalar_acc
+       then echo c32-convex-bsd
+       else echo c2-convex-bsd
+       fi
+       exit 0 ;;
+    c34*)
+       echo c34-convex-bsd
+       exit 0 ;;
+    c38*)
+       echo c38-convex-bsd
+       exit 0 ;;
+    c4*)
+       echo c4-convex-bsd
+       exit 0 ;;
+    esac
+fi
+
+#echo '(Unable to guess system type)' 1>&2
+
+exit 1
index cc48687e2281c2ccc1c1c8c0149b1442a76b2b82..c273e2022a37a1933cb20f91ae407ad69da23dd5 100644 (file)
@@ -60,9 +60,6 @@
 /* Where new mail is spooled */
 #undef MAILPATH
 
-/* Should I just use the domain name? (--enable-hidden-host) */
-#undef HIDDEN_HOST
-
 /* Where to find sendmail on your system */
 #undef SENDMAIL
 
 /* Does your system have the vsnprintf() call? */
 #undef HAVE_VSNPRINTF
 
+/* Does your system have the fchdir() call? */
+#undef HAVE_FCHDIR
+
 /* The number of bytes in a long.  */
 #undef SIZEOF_LONG
 
 /* Define if you have the curs_set function.  */
 #undef HAVE_CURS_SET
 
+/* Define if you have the fchdir function.  */
+#undef HAVE_FCHDIR
+
 /* Define if you have the ftruncate function.  */
 #undef HAVE_FTRUNCATE
 
 /* Define if you have the <sys/ioctl.h> header file.  */
 #undef HAVE_SYS_IOCTL_H
 
+/* Define if you have the <sysexits.h> header file.  */
+#undef HAVE_SYSEXITS_H
+
 /* Define if you have the intl library (-lintl).  */
 #undef HAVE_LIBINTL
 
diff --git a/config.sub b/config.sub
new file mode 100755 (executable)
index 0000000..e24b850
--- /dev/null
@@ -0,0 +1,952 @@
+#! /bin/sh
+# Configuration validation subroutine script, version 1.1.
+#   Copyright (C) 1991, 92-97, 1998 Free Software Foundation, Inc.
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine.  It does not imply ALL GNU software can.
+#
+# This file 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., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#      CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#      CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+if [ x$1 = x ]
+then
+       echo Configuration name missing. 1>&2
+       echo "Usage: $0 CPU-MFR-OPSYS" 1>&2
+       echo "or     $0 ALIAS" 1>&2
+       echo where ALIAS is a recognized configuration type. 1>&2
+       exit 1
+fi
+
+# First pass through any local machine types.
+case $1 in
+       *local*)
+               echo $1
+               exit 0
+               ;;
+       *)
+       ;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  linux-gnu*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+       -sun*os*)
+               # Prevent following clause from handling this invalid input.
+               ;;
+       -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+       -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+       -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+       -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+       -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+       -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+       -apple)
+               os=
+               basic_machine=$1
+               ;;
+       -hiux*)
+               os=-hiuxwe2
+               ;;
+       -sco5)
+               os=sco3.2v5
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco4)
+               os=-sco3.2v4
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco3.2.[4-9]*)
+               os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco3.2v[4-9]*)
+               # Don't forget version if it is 3.2v4 or newer.
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -sco*)
+               os=-sco3.2v2
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -isc)
+               os=-isc2.2
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -clix*)
+               basic_machine=clipper-intergraph
+               ;;
+       -isc*)
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+               ;;
+       -lynx*)
+               os=-lynxos
+               ;;
+       -ptx*)
+               basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+               ;;
+       -windowsnt*)
+               os=`echo $os | sed -e 's/windowsnt/winnt/'`
+               ;;
+       -psos*)
+               os=-psos
+               ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+       # Recognize the basic CPU types without company name.
+       # Some are omitted here because they have special meanings below.
+       tahoe | i860 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \
+               | arme[lb] | pyramid | mn10200 | mn10300 \
+               | tron | a29k | 580 | i960 | h8300 | hppa | hppa1.0 | hppa1.1 \
+               | alpha | alphaev5 | alphaev56 | we32k | ns16k | clipper \
+               | i370 | sh | powerpc | powerpcle | 1750a | dsp16xx | pdp11 \
+               | mips64 | mipsel | mips64el | mips64orion | mips64orionel \
+               | mipstx39 | mipstx39el \
+               | sparc | sparclet | sparclite | sparc64 | v850)
+               basic_machine=$basic_machine-unknown
+               ;;
+       # We use `pc' rather than `unknown'
+       # because (1) that's what they normally are, and
+       # (2) the word "unknown" tends to confuse beginning users.
+       i[34567]86)
+         basic_machine=$basic_machine-pc
+         ;;
+       # Object if more than one company name word.
+       *-*-*)
+               echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+               exit 1
+               ;;
+       # Recognize the basic CPU types with company name.
+       vax-* | tahoe-* | i[34567]86-* | i860-* | m32r-* | m68k-* | m68000-* \
+             | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \
+             | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \
+             | power-* | none-* | 580-* | cray2-* | h8300-* | i960-* \
+             | xmp-* | ymp-* | hppa-* | hppa1.0-* | hppa1.1-* \
+             | alpha-* | alphaev5-* | alphaev56-* | we32k-* | cydra-* \
+             | ns16k-* | pn-* | np1-* | xps100-* | clipper-* | orion-* \
+             | sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \
+             | sparc64-* | mips64-* | mipsel-* \
+             | mips64el-* | mips64orion-* | mips64orionel-*  \
+             | mipstx39-* | mipstx39el-* \
+             | f301-*)
+               ;;
+       # Recognize the various machine names and aliases which stand
+       # for a CPU type and a company and sometimes even an OS.
+       3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+               basic_machine=m68000-att
+               ;;
+       3b*)
+               basic_machine=we32k-att
+               ;;
+       alliant | fx80)
+               basic_machine=fx80-alliant
+               ;;
+       altos | altos3068)
+               basic_machine=m68k-altos
+               ;;
+       am29k)
+               basic_machine=a29k-none
+               os=-bsd
+               ;;
+       amdahl)
+               basic_machine=580-amdahl
+               os=-sysv
+               ;;
+       amiga | amiga-*)
+               basic_machine=m68k-cbm
+               ;;
+       amigaos | amigados)
+               basic_machine=m68k-cbm
+               os=-amigaos
+               ;;
+       amigaunix | amix)
+               basic_machine=m68k-cbm
+               os=-sysv4
+               ;;
+       apollo68)
+               basic_machine=m68k-apollo
+               os=-sysv
+               ;;
+       aux)
+               basic_machine=m68k-apple
+               os=-aux
+               ;;
+       balance)
+               basic_machine=ns32k-sequent
+               os=-dynix
+               ;;
+       convex-c1)
+               basic_machine=c1-convex
+               os=-bsd
+               ;;
+       convex-c2)
+               basic_machine=c2-convex
+               os=-bsd
+               ;;
+       convex-c32)
+               basic_machine=c32-convex
+               os=-bsd
+               ;;
+       convex-c34)
+               basic_machine=c34-convex
+               os=-bsd
+               ;;
+       convex-c38)
+               basic_machine=c38-convex
+               os=-bsd
+               ;;
+       cray | ymp)
+               basic_machine=ymp-cray
+               os=-unicos
+               ;;
+       cray2)
+               basic_machine=cray2-cray
+               os=-unicos
+               ;;
+       [ctj]90-cray)
+               basic_machine=c90-cray
+               os=-unicos
+               ;;
+       crds | unos)
+               basic_machine=m68k-crds
+               ;;
+       da30 | da30-*)
+               basic_machine=m68k-da30
+               ;;
+       decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+               basic_machine=mips-dec
+               ;;
+       delta | 3300 | motorola-3300 | motorola-delta \
+             | 3300-motorola | delta-motorola)
+               basic_machine=m68k-motorola
+               ;;
+       delta88)
+               basic_machine=m88k-motorola
+               os=-sysv3
+               ;;
+       dpx20 | dpx20-*)
+               basic_machine=rs6000-bull
+               os=-bosx
+               ;;
+       dpx2* | dpx2*-bull)
+               basic_machine=m68k-bull
+               os=-sysv3
+               ;;
+       ebmon29k)
+               basic_machine=a29k-amd
+               os=-ebmon
+               ;;
+       elxsi)
+               basic_machine=elxsi-elxsi
+               os=-bsd
+               ;;
+       encore | umax | mmax)
+               basic_machine=ns32k-encore
+               ;;
+       fx2800)
+               basic_machine=i860-alliant
+               ;;
+       genix)
+               basic_machine=ns32k-ns
+               ;;
+       gmicro)
+               basic_machine=tron-gmicro
+               os=-sysv
+               ;;
+       h3050r* | hiux*)
+               basic_machine=hppa1.1-hitachi
+               os=-hiuxwe2
+               ;;
+       h8300hms)
+               basic_machine=h8300-hitachi
+               os=-hms
+               ;;
+       harris)
+               basic_machine=m88k-harris
+               os=-sysv3
+               ;;
+       hp300-*)
+               basic_machine=m68k-hp
+               ;;
+       hp300bsd)
+               basic_machine=m68k-hp
+               os=-bsd
+               ;;
+       hp300hpux)
+               basic_machine=m68k-hp
+               os=-hpux
+               ;;
+       hp9k2[0-9][0-9] | hp9k31[0-9])
+               basic_machine=m68000-hp
+               ;;
+       hp9k3[2-9][0-9])
+               basic_machine=m68k-hp
+               ;;
+       hp9k7[0-9][0-9] | hp7[0-9][0-9] | hp9k8[0-9]7 | hp8[0-9]7)
+               basic_machine=hppa1.1-hp
+               ;;
+       hp9k8[0-9][0-9] | hp8[0-9][0-9])
+               basic_machine=hppa1.0-hp
+               ;;
+       hppa-next)
+               os=-nextstep3
+               ;;
+       i370-ibm* | ibm*)
+               basic_machine=i370-ibm
+               os=-mvs
+               ;;
+# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
+       i[34567]86v32)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-sysv32
+               ;;
+       i[34567]86v4*)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-sysv4
+               ;;
+       i[34567]86v)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-sysv
+               ;;
+       i[34567]86sol2)
+               basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+               os=-solaris2
+               ;;
+       iris | iris4d)
+               basic_machine=mips-sgi
+               case $os in
+                   -irix*)
+                       ;;
+                   *)
+                       os=-irix4
+                       ;;
+               esac
+               ;;
+       isi68 | isi)
+               basic_machine=m68k-isi
+               os=-sysv
+               ;;
+       m88k-omron*)
+               basic_machine=m88k-omron
+               ;;
+       magnum | m3230)
+               basic_machine=mips-mips
+               os=-sysv
+               ;;
+       merlin)
+               basic_machine=ns32k-utek
+               os=-sysv
+               ;;
+       miniframe)
+               basic_machine=m68000-convergent
+               ;;
+       mipsel*-linux*)
+               basic_machine=mipsel-unknown
+               os=-linux-gnu
+               ;;
+       mips*-linux*)
+               basic_machine=mips-unknown
+               os=-linux-gnu
+               ;;
+       mips3*-*)
+               basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+               ;;
+       mips3*)
+               basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+               ;;
+       ncr3000)
+               basic_machine=i486-ncr
+               os=-sysv4
+               ;;
+       news | news700 | news800 | news900)
+               basic_machine=m68k-sony
+               os=-newsos
+               ;;
+       news1000)
+               basic_machine=m68030-sony
+               os=-newsos
+               ;;
+       news-3600 | risc-news)
+               basic_machine=mips-sony
+               os=-newsos
+               ;;
+       next | m*-next )
+               basic_machine=m68k-next
+               case $os in
+                   -nextstep* )
+                       ;;
+                   -ns2*)
+                     os=-nextstep2
+                       ;;
+                   *)
+                     os=-nextstep3
+                       ;;
+               esac
+               ;;
+       nh3000)
+               basic_machine=m68k-harris
+               os=-cxux
+               ;;
+       nh[45]000)
+               basic_machine=m88k-harris
+               os=-cxux
+               ;;
+       nindy960)
+               basic_machine=i960-intel
+               os=-nindy
+               ;;
+       np1)
+               basic_machine=np1-gould
+               ;;
+       pa-hitachi)
+               basic_machine=hppa1.1-hitachi
+               os=-hiuxwe2
+               ;;
+       paragon)
+               basic_machine=i860-intel
+               os=-osf
+               ;;
+       pbd)
+               basic_machine=sparc-tti
+               ;;
+       pbb)
+               basic_machine=m68k-tti
+               ;;
+        pc532 | pc532-*)
+               basic_machine=ns32k-pc532
+               ;;
+       pentium | p5 | k5 | nexen)
+               basic_machine=i586-pc
+               ;;
+       pentiumpro | p6 | k6 | 6x86)
+               basic_machine=i686-pc
+               ;;
+       pentiumii | pentium2)
+               basic_machine=i786-pc
+               ;;
+       pentium-* | p5-* | k5-* | nexen-*)
+               basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       pentiumpro-* | p6-* | k6-* | 6x86-*)
+               basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       pentiumii-* | pentium2-*)
+               basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       pn)
+               basic_machine=pn-gould
+               ;;
+       power)  basic_machine=rs6000-ibm
+               ;;
+       ppc)    basic_machine=powerpc-unknown
+               ;;
+       ppc-*)  basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       ppcle | powerpclittle | ppc-le | powerpc-little)
+               basic_machine=powerpcle-unknown
+               ;;
+       ppcle-* | powerpclittle-*)
+               basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+               ;;
+       ps2)
+               basic_machine=i386-ibm
+               ;;
+       rm[46]00)
+               basic_machine=mips-siemens
+               ;;
+       rtpc | rtpc-*)
+               basic_machine=romp-ibm
+               ;;
+       sequent)
+               basic_machine=i386-sequent
+               ;;
+       sh)
+               basic_machine=sh-hitachi
+               os=-hms
+               ;;
+       sps7)
+               basic_machine=m68k-bull
+               os=-sysv2
+               ;;
+       spur)
+               basic_machine=spur-unknown
+               ;;
+       sun2)
+               basic_machine=m68000-sun
+               ;;
+       sun2os3)
+               basic_machine=m68000-sun
+               os=-sunos3
+               ;;
+       sun2os4)
+               basic_machine=m68000-sun
+               os=-sunos4
+               ;;
+       sun3os3)
+               basic_machine=m68k-sun
+               os=-sunos3
+               ;;
+       sun3os4)
+               basic_machine=m68k-sun
+               os=-sunos4
+               ;;
+       sun4os3)
+               basic_machine=sparc-sun
+               os=-sunos3
+               ;;
+       sun4os4)
+               basic_machine=sparc-sun
+               os=-sunos4
+               ;;
+       sun4sol2)
+               basic_machine=sparc-sun
+               os=-solaris2
+               ;;
+       sun3 | sun3-*)
+               basic_machine=m68k-sun
+               ;;
+       sun4)
+               basic_machine=sparc-sun
+               ;;
+       sun386 | sun386i | roadrunner)
+               basic_machine=i386-sun
+               ;;
+       symmetry)
+               basic_machine=i386-sequent
+               os=-dynix
+               ;;
+       tx39)
+               basic_machine=mipstx39-unknown
+               ;;
+       tx39el)
+               basic_machine=mipstx39el-unknown
+               ;;
+       tower | tower-32)
+               basic_machine=m68k-ncr
+               ;;
+       udi29k)
+               basic_machine=a29k-amd
+               os=-udi
+               ;;
+       ultra3)
+               basic_machine=a29k-nyu
+               os=-sym1
+               ;;
+       vaxv)
+               basic_machine=vax-dec
+               os=-sysv
+               ;;
+       vms)
+               basic_machine=vax-dec
+               os=-vms
+               ;;
+       vpp*|vx|vx-*)
+               basic_machine=f301-fujitsu
+               ;;
+       vxworks960)
+               basic_machine=i960-wrs
+               os=-vxworks
+               ;;
+       vxworks68)
+               basic_machine=m68k-wrs
+               os=-vxworks
+               ;;
+       vxworks29k)
+               basic_machine=a29k-wrs
+               os=-vxworks
+               ;;
+       xmp)
+               basic_machine=xmp-cray
+               os=-unicos
+               ;;
+        xps | xps100)
+               basic_machine=xps100-honeywell
+               ;;
+       none)
+               basic_machine=none-none
+               os=-none
+               ;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+       mips)
+               if [ x$os = x-linux-gnu ]; then
+                       basic_machine=mips-unknown
+               else
+                       basic_machine=mips-mips
+               fi
+               ;;
+       romp)
+               basic_machine=romp-ibm
+               ;;
+       rs6000)
+               basic_machine=rs6000-ibm
+               ;;
+       vax)
+               basic_machine=vax-dec
+               ;;
+       pdp11)
+               basic_machine=pdp11-dec
+               ;;
+       we32k)
+               basic_machine=we32k-att
+               ;;
+       sparc)
+               basic_machine=sparc-sun
+               ;;
+        cydra)
+               basic_machine=cydra-cydrome
+               ;;
+       orion)
+               basic_machine=orion-highlevel
+               ;;
+       orion105)
+               basic_machine=clipper-highlevel
+               ;;
+       *)
+               echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+               exit 1
+               ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+       *-digital*)
+               basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+               ;;
+       *-commodore*)
+               basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+               ;;
+       *)
+               ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+        # First match some system type aliases
+        # that might get confused with valid system types.
+       # -solaris* is a basic system type, with this one exception.
+       -solaris1 | -solaris1.*)
+               os=`echo $os | sed -e 's|solaris1|sunos4|'`
+               ;;
+       -solaris)
+               os=-solaris2
+               ;;
+       -svr4*)
+               os=-sysv4
+               ;;
+       -unixware*)
+               os=-sysv4.2uw
+               ;;
+       -gnu/linux*)
+               os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+               ;;
+       # First accept the basic system types.
+       # The portable systems comes first.
+       # Each alternative MUST END IN A *, to match a version number.
+       # -sysv* is not here because it comes later, after sysvr4.
+       -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+             | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+             | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+             | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+             | -aos* \
+             | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+             | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+             | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
+             | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* \
+             | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+             | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+             | -cygwin32* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+             | -mingw32* | -linux-gnu* | -uxpv*)
+       # Remember, each alternative MUST END IN *, to match a version number.
+               ;;
+       -linux*)
+               os=`echo $os | sed -e 's|linux|linux-gnu|'`
+               ;;
+       -sunos5*)
+               os=`echo $os | sed -e 's|sunos5|solaris2|'`
+               ;;
+       -sunos6*)
+               os=`echo $os | sed -e 's|sunos6|solaris3|'`
+               ;;
+       -osfrose*)
+               os=-osfrose
+               ;;
+       -osf*)
+               os=-osf
+               ;;
+       -utek*)
+               os=-bsd
+               ;;
+       -dynix*)
+               os=-bsd
+               ;;
+       -acis*)
+               os=-aos
+               ;;
+       -ctix* | -uts*)
+               os=-sysv
+               ;;
+       -ns2 )
+               os=-nextstep2
+               ;;
+       # Preserve the version number of sinix5.
+       -sinix5.*)
+               os=`echo $os | sed -e 's|sinix|sysv|'`
+               ;;
+       -sinix*)
+               os=-sysv4
+               ;;
+       -triton*)
+               os=-sysv3
+               ;;
+       -oss*)
+               os=-sysv3
+               ;;
+       -svr4)
+               os=-sysv4
+               ;;
+       -svr3)
+               os=-sysv3
+               ;;
+       -sysvr4)
+               os=-sysv4
+               ;;
+       # This must come after -sysvr4.
+       -sysv*)
+               ;;
+       -xenix)
+               os=-xenix
+               ;;
+       -none)
+               ;;
+       *)
+               # Get rid of the `-' at the beginning of $os.
+               os=`echo $os | sed 's/[^-]*-//'`
+               echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+               exit 1
+               ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+       *-acorn)
+               os=-riscix1.2
+               ;;
+       arm*-semi)
+               os=-aout
+               ;;
+        pdp11-*)
+               os=-none
+               ;;
+       *-dec | vax-*)
+               os=-ultrix4.2
+               ;;
+       m68*-apollo)
+               os=-domain
+               ;;
+       i386-sun)
+               os=-sunos4.0.2
+               ;;
+       m68000-sun)
+               os=-sunos3
+               # This also exists in the configure program, but was not the
+               # default.
+               # os=-sunos4
+               ;;
+       *-tti)  # must be before sparc entry or we get the wrong os.
+               os=-sysv3
+               ;;
+       sparc-* | *-sun)
+               os=-sunos4.1.1
+               ;;
+       *-ibm)
+               os=-aix
+               ;;
+       *-hp)
+               os=-hpux
+               ;;
+       *-hitachi)
+               os=-hiux
+               ;;
+       i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+               os=-sysv
+               ;;
+       *-cbm)
+               os=-amigaos
+               ;;
+       *-dg)
+               os=-dgux
+               ;;
+       *-dolphin)
+               os=-sysv3
+               ;;
+       m68k-ccur)
+               os=-rtu
+               ;;
+       m88k-omron*)
+               os=-luna
+               ;;
+       *-next )
+               os=-nextstep
+               ;;
+       *-sequent)
+               os=-ptx
+               ;;
+       *-crds)
+               os=-unos
+               ;;
+       *-ns)
+               os=-genix
+               ;;
+       i370-*)
+               os=-mvs
+               ;;
+       *-next)
+               os=-nextstep3
+               ;;
+        *-gould)
+               os=-sysv
+               ;;
+        *-highlevel)
+               os=-bsd
+               ;;
+       *-encore)
+               os=-bsd
+               ;;
+        *-sgi)
+               os=-irix
+               ;;
+        *-siemens)
+               os=-sysv4
+               ;;
+       *-masscomp)
+               os=-rtu
+               ;;
+       f301-fujitsu)
+               os=-uxpv
+               ;;
+       *)
+               os=-none
+               ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+       *-unknown)
+               case $os in
+                       -riscix*)
+                               vendor=acorn
+                               ;;
+                       -sunos*)
+                               vendor=sun
+                               ;;
+                       -aix*)
+                               vendor=ibm
+                               ;;
+                       -hpux*)
+                               vendor=hp
+                               ;;
+                       -hiux*)
+                               vendor=hitachi
+                               ;;
+                       -unos*)
+                               vendor=crds
+                               ;;
+                       -dgux*)
+                               vendor=dg
+                               ;;
+                       -luna*)
+                               vendor=omron
+                               ;;
+                       -genix*)
+                               vendor=ns
+                               ;;
+                       -mvs*)
+                               vendor=ibm
+                               ;;
+                       -ptx*)
+                               vendor=sequent
+                               ;;
+                       -vxsim* | -vxworks*)
+                               vendor=wrs
+                               ;;
+                       -aux*)
+                               vendor=apple
+                               ;;
+               esac
+               basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+               ;;
+esac
+
+echo $basic_machine$os
index 240f6658f74cf602961df55ae2bbccd11241c190..60b1e9fb3c4222999644ca3308c2bbd8f9fb7576 100755 (executable)
--- a/configure
+++ b/configure
@@ -21,14 +21,14 @@ ac_help="$ac_help
   --with-homespool[=FILE]    file in user's directory where new mail is spooled"
 ac_help="$ac_help
   --with-mailpath=DIR        directory where spool mailboxes are located"
+ac_help="$ac_help
+  --with-libdir=PATH       specify where to put arch dependent files"
 ac_help="$ac_help
   --with-sharedir=PATH       specify where to put arch independent files"
 ac_help="$ac_help
   --with-docdir=PATH       specify where to put the documentation"
 ac_help="$ac_help
   --with-domain=DOMAIN       Specify your DNS domain name "
-ac_help="$ac_help
-  --enable-hidden-host       Only use the domain name for local addresses"
 ac_help="$ac_help
   --enable-pop               Enable POP3 support"
 ac_help="$ac_help
@@ -557,11 +557,58 @@ fi
 
 
 
-VERSION=0.92.11
+VERSION=0.94.4
 SUBVERSION=''
 
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+  if test -f $ac_dir/install-sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f $ac_dir/install.sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+
+# Make sure we can run config.sub.
+if $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:590: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+  case $nonopt in
+  NONE)
+    if host_alias=`$ac_config_guess`; then :
+    else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+    fi ;;
+  *) host_alias=$nonopt ;;
+  esac ;;
+esac
+
+host=`$ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+
 echo $ac_n "checking for prefix""... $ac_c" 1>&6
-echo "configure:565: checking for prefix" >&5
+echo "configure:612: checking for prefix" >&5
 if test x$prefix = xNONE; then
        mutt_cv_prefix=$ac_default_prefix
 else
@@ -572,7 +619,7 @@ echo "$ac_t""$mutt_cv_prefix" 1>&6
 # Extract the first word of "gcc", so it can be a program name with args.
 set dummy gcc; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:576: checking for $ac_word" >&5
+echo "configure:623: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -601,7 +648,7 @@ if test -z "$CC"; then
   # Extract the first word of "cc", so it can be a program name with args.
 set dummy cc; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:605: checking for $ac_word" >&5
+echo "configure:652: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -649,7 +696,7 @@ fi
 fi
 
 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
-echo "configure:653: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+echo "configure:700: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
 
 ac_ext=c
 # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
@@ -659,11 +706,11 @@ ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS
 cross_compiling=$ac_cv_prog_cc_cross
 
 cat > conftest.$ac_ext <<EOF
-#line 663 "configure"
+#line 710 "configure"
 #include "confdefs.h"
 main(){return(0);}
 EOF
-if { (eval echo configure:667: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:714: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   ac_cv_prog_cc_works=yes
   # If we can't run a trivial program, we are probably using a cross compiler.
   if (./conftest; exit) 2>/dev/null; then
@@ -683,12 +730,12 @@ if test $ac_cv_prog_cc_works = no; then
   { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
 fi
 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
-echo "configure:687: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "configure:734: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
 cross_compiling=$ac_cv_prog_cc_cross
 
 echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
-echo "configure:692: checking whether we are using GNU C" >&5
+echo "configure:739: checking whether we are using GNU C" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -697,7 +744,7 @@ else
   yes;
 #endif
 EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:701: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:748: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
   ac_cv_prog_gcc=yes
 else
   ac_cv_prog_gcc=no
@@ -712,7 +759,7 @@ if test $ac_cv_prog_gcc = yes; then
   ac_save_CFLAGS="$CFLAGS"
   CFLAGS=
   echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
-echo "configure:716: checking whether ${CC-cc} accepts -g" >&5
+echo "configure:763: checking whether ${CC-cc} accepts -g" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -740,7 +787,7 @@ else
 fi
 
 echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
-echo "configure:744: checking whether ${MAKE-make} sets \${MAKE}" >&5
+echo "configure:791: checking whether ${MAKE-make} sets \${MAKE}" >&5
 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -766,25 +813,6 @@ else
   SET_MAKE="MAKE=${MAKE-make}"
 fi
 
-ac_aux_dir=
-for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
-  if test -f $ac_dir/install-sh; then
-    ac_aux_dir=$ac_dir
-    ac_install_sh="$ac_aux_dir/install-sh -c"
-    break
-  elif test -f $ac_dir/install.sh; then
-    ac_aux_dir=$ac_dir
-    ac_install_sh="$ac_aux_dir/install.sh -c"
-    break
-  fi
-done
-if test -z "$ac_aux_dir"; then
-  { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
-fi
-ac_config_guess=$ac_aux_dir/config.guess
-ac_config_sub=$ac_aux_dir/config.sub
-ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
-
 # Find a good install program.  We prefer a C program (faster),
 # so one script is as good as another.  But avoid the broken or
 # incompatible versions:
@@ -796,7 +824,7 @@ ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
 # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
 # ./install, which can be erroneously created by make from ./install.sh.
 echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
-echo "configure:800: checking for a BSD compatible install" >&5
+echo "configure:828: checking for a BSD compatible install" >&5
 if test -z "$INSTALL"; then
 if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -846,10 +874,18 @@ test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
 test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
 
 
+case "$host" in
+*-*-hpux*)
+       if test -z "$GCC" ; then
+               CFLAGS="$CFLAGS -Ae -D_HPUX_SOURCE"
+       fi
+       ;;
+esac
+
 # Extract the first word of "sendmail", so it can be a program name with args.
 set dummy sendmail; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:853: checking for $ac_word" >&5
+echo "configure:889: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_SENDMAIL'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -891,7 +927,7 @@ if test -f $srcdir/pgp.c; then
        # Extract the first word of "gpg", so it can be a program name with args.
 set dummy gpg; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:895: checking for $ac_word" >&5
+echo "configure:931: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_GPG'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -935,7 +971,7 @@ EOF
        # Extract the first word of "pgpk", so it can be a program name with args.
 set dummy pgpk; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:939: checking for $ac_word" >&5
+echo "configure:975: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_PGPK'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -980,7 +1016,7 @@ EOF
        # Extract the first word of "pgp", so it can be a program name with args.
 set dummy pgp; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:984: checking for $ac_word" >&5
+echo "configure:1020: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_PGP'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1044,7 +1080,7 @@ EOF
 # Extract the first word of "ispell", so it can be a program name with args.
 set dummy ispell; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1048: checking for $ac_word" >&5
+echo "configure:1084: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_ISPELL'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1081,7 +1117,7 @@ EOF
 fi
 
 echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
-echo "configure:1085: checking how to run the C preprocessor" >&5
+echo "configure:1121: checking how to run the C preprocessor" >&5
 # On Suns, sometimes $CPP names a directory.
 if test -n "$CPP" && test -d "$CPP"; then
   CPP=
@@ -1096,13 +1132,13 @@ else
   # On the NeXT, cc -E runs the code through the compiler's parser,
   # not just through cpp.
   cat > conftest.$ac_ext <<EOF
-#line 1100 "configure"
+#line 1136 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1106: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1142: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   :
@@ -1113,13 +1149,13 @@ else
   rm -rf conftest*
   CPP="${CC-cc} -E -traditional-cpp"
   cat > conftest.$ac_ext <<EOF
-#line 1117 "configure"
+#line 1153 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1123: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1159: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   :
@@ -1145,7 +1181,7 @@ echo "$ac_t""$CPP" 1>&6
 if test "${with_slang+set}" = set; then
   withval="$with_slang"
   echo $ac_n "checking if -ltermlib is required""... $ac_c" 1>&6
-echo "configure:1149: checking if -ltermlib is required" >&5
+echo "configure:1185: checking if -ltermlib is required" >&5
 if eval "test \"`echo '$''{'mutt_cv_bsdish'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1153,7 +1189,7 @@ else
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
   cat > conftest.$ac_ext <<EOF
-#line 1157 "configure"
+#line 1193 "configure"
 #include "confdefs.h"
 #include <sys/param.h>
 
@@ -1166,7 +1202,7 @@ main ()
 #endif
 }
 EOF
-if { (eval echo configure:1170: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:1206: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   mutt_cv_bsdish=yes
 else
@@ -1183,7 +1219,7 @@ fi
 echo "$ac_t""$mutt_cv_bsdish" 1>&6
        
        echo $ac_n "checking for S-Lang""... $ac_c" 1>&6
-echo "configure:1187: checking for S-Lang" >&5
+echo "configure:1223: checking for S-Lang" >&5
        if test $withval = yes; then
                if test -d $srcdir/../slang; then
                        mutt_cv_slang=$srcdir/../slang/src
@@ -1229,16 +1265,16 @@ EOF
        
                
        echo $ac_n "checking if I can compile a test SLang program""... $ac_c" 1>&6
-echo "configure:1233: checking if I can compile a test SLang program" >&5
+echo "configure:1269: checking if I can compile a test SLang program" >&5
        cat > conftest.$ac_ext <<EOF
-#line 1235 "configure"
+#line 1271 "configure"
 #include "confdefs.h"
 
 int main() {
 SLtt_get_terminfo ();
 ; return 0; }
 EOF
-if { (eval echo configure:1242: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:1278: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   echo "$ac_t""yes" 1>&6
 else
@@ -1266,7 +1302,7 @@ fi
 
 
        echo $ac_n "checking for initscr in -lncurses""... $ac_c" 1>&6
-echo "configure:1270: checking for initscr in -lncurses" >&5
+echo "configure:1306: checking for initscr in -lncurses" >&5
 ac_lib_var=`echo ncurses'_'initscr | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1274,7 +1310,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lncurses  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1278 "configure"
+#line 1314 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -1285,7 +1321,7 @@ int main() {
 initscr()
 ; return 0; }
 EOF
-if { (eval echo configure:1289: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:1325: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1308,17 +1344,17 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1312: checking for $ac_hdr" >&5
+echo "configure:1348: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1317 "configure"
+#line 1353 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1322: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1358: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -1359,12 +1395,12 @@ fi
 
 
        echo $ac_n "checking for start_color""... $ac_c" 1>&6
-echo "configure:1363: checking for start_color" >&5
+echo "configure:1399: checking for start_color" >&5
 if eval "test \"`echo '$''{'ac_cv_func_start_color'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1368 "configure"
+#line 1404 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char start_color(); below.  */
@@ -1387,7 +1423,7 @@ start_color();
 
 ; return 0; }
 EOF
-if { (eval echo configure:1391: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:1427: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_start_color=yes"
 else
@@ -1412,12 +1448,12 @@ fi
        for ac_func in typeahead bkgdset curs_set meta use_default_colors
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:1416: checking for $ac_func" >&5
+echo "configure:1452: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1421 "configure"
+#line 1457 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -1440,7 +1476,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:1444: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:1480: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -1467,12 +1503,12 @@ done
        for ac_func in resizeterm
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:1471: checking for $ac_func" >&5
+echo "configure:1507: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1476 "configure"
+#line 1512 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -1495,7 +1531,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:1499: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:1535: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -1524,12 +1560,12 @@ fi
 
 
 echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
-echo "configure:1528: checking for ANSI C header files" >&5
+echo "configure:1564: checking for ANSI C header files" >&5
 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1533 "configure"
+#line 1569 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 #include <stdarg.h>
@@ -1537,7 +1573,7 @@ else
 #include <float.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1541: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1577: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -1554,7 +1590,7 @@ rm -f conftest*
 if test $ac_cv_header_stdc = yes; then
   # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
 cat > conftest.$ac_ext <<EOF
-#line 1558 "configure"
+#line 1594 "configure"
 #include "confdefs.h"
 #include <string.h>
 EOF
@@ -1572,7 +1608,7 @@ fi
 if test $ac_cv_header_stdc = yes; then
   # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
 cat > conftest.$ac_ext <<EOF
-#line 1576 "configure"
+#line 1612 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 EOF
@@ -1593,7 +1629,7 @@ if test "$cross_compiling" = yes; then
   :
 else
   cat > conftest.$ac_ext <<EOF
-#line 1597 "configure"
+#line 1633 "configure"
 #include "confdefs.h"
 #include <ctype.h>
 #define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
@@ -1604,7 +1640,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
 exit (0); }
 
 EOF
-if { (eval echo configure:1608: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:1644: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   :
 else
@@ -1628,21 +1664,21 @@ EOF
 fi
 
 
-for ac_hdr in stdarg.h sys/ioctl.h
+for ac_hdr in stdarg.h sys/ioctl.h sysexits.h
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1636: checking for $ac_hdr" >&5
+echo "configure:1672: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1641 "configure"
+#line 1677 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1646: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1682: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -1670,12 +1706,12 @@ done
 
 
 echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6
-echo "configure:1674: checking return type of signal handlers" >&5
+echo "configure:1710: checking return type of signal handlers" >&5
 if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1679 "configure"
+#line 1715 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <signal.h>
@@ -1692,7 +1728,7 @@ int main() {
 int i;
 ; return 0; }
 EOF
-if { (eval echo configure:1696: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1732: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_type_signal=void
 else
@@ -1712,12 +1748,12 @@ EOF
 
 
 echo $ac_n "checking for sys_siglist declaration in signal.h or unistd.h""... $ac_c" 1>&6
-echo "configure:1716: checking for sys_siglist declaration in signal.h or unistd.h" >&5
+echo "configure:1752: checking for sys_siglist declaration in signal.h or unistd.h" >&5
 if eval "test \"`echo '$''{'ac_cv_decl_sys_siglist'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1721 "configure"
+#line 1757 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <signal.h>
@@ -1729,7 +1765,7 @@ int main() {
 char *msg = *(sys_siglist + 1);
 ; return 0; }
 EOF
-if { (eval echo configure:1733: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1769: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_decl_sys_siglist=yes
 else
@@ -1751,7 +1787,7 @@ fi
 
 
 echo $ac_n "checking size of long""... $ac_c" 1>&6
-echo "configure:1755: checking size of long" >&5
+echo "configure:1791: checking size of long" >&5
 if eval "test \"`echo '$''{'ac_cv_sizeof_long'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1759,7 +1795,7 @@ else
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
   cat > conftest.$ac_ext <<EOF
-#line 1763 "configure"
+#line 1799 "configure"
 #include "confdefs.h"
 #include <stdio.h>
 main()
@@ -1770,7 +1806,7 @@ main()
   exit(0);
 }
 EOF
-if { (eval echo configure:1774: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:1810: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   ac_cv_sizeof_long=`cat conftestval`
 else
@@ -1791,12 +1827,12 @@ EOF
 
 
 echo $ac_n "checking for pid_t""... $ac_c" 1>&6
-echo "configure:1795: checking for pid_t" >&5
+echo "configure:1831: checking for pid_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_pid_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1800 "configure"
+#line 1836 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -1827,12 +1863,12 @@ fi
 for ac_func in setegid srand48 strerror
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:1831: checking for $ac_func" >&5
+echo "configure:1867: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1836 "configure"
+#line 1872 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -1855,7 +1891,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:1859: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:1895: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -1883,12 +1919,12 @@ done
 for ac_func in strcasecmp
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:1887: checking for $ac_func" >&5
+echo "configure:1923: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1892 "configure"
+#line 1928 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -1911,7 +1947,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:1915: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:1951: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -1939,13 +1975,14 @@ done
 
 
 mutt_cv_snprintf=no
+SNPRINTFOBJS=""
 echo $ac_n "checking for snprintf""... $ac_c" 1>&6
-echo "configure:1944: checking for snprintf" >&5
+echo "configure:1981: checking for snprintf" >&5
 if eval "test \"`echo '$''{'ac_cv_func_snprintf'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1949 "configure"
+#line 1986 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char snprintf(); below.  */
@@ -1968,7 +2005,7 @@ snprintf();
 
 ; return 0; }
 EOF
-if { (eval echo configure:1972: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2009: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_snprintf=yes"
 else
@@ -1992,12 +2029,12 @@ mutt_cv_snprintf=yes
 fi
 
 echo $ac_n "checking for vsnprintf""... $ac_c" 1>&6
-echo "configure:1996: checking for vsnprintf" >&5
+echo "configure:2033: checking for vsnprintf" >&5
 if eval "test \"`echo '$''{'ac_cv_func_vsnprintf'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2001 "configure"
+#line 2038 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char vsnprintf(); below.  */
@@ -2020,7 +2057,7 @@ vsnprintf();
 
 ; return 0; }
 EOF
-if { (eval echo configure:2024: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2061: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_vsnprintf=yes"
 else
@@ -2045,17 +2082,19 @@ fi
 
 if test $mutt_cv_snprintf = yes; then
        LIBOBJS="$LIBOBJS snprintf.o"
+       SNPRINTFOBJS="snprintf.o"
 fi
 
+
 for ac_func in ftruncate
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:2054: checking for $ac_func" >&5
+echo "configure:2093: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2059 "configure"
+#line 2098 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -2078,7 +2117,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:2082: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2121: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -2100,7 +2139,7 @@ EOF
 else
   echo "$ac_t""no" 1>&6
 echo $ac_n "checking for chsize in -lx""... $ac_c" 1>&6
-echo "configure:2104: checking for chsize in -lx" >&5
+echo "configure:2143: checking for chsize in -lx" >&5
 ac_lib_var=`echo x'_'chsize | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -2108,7 +2147,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lx  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 2112 "configure"
+#line 2151 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -2119,7 +2158,7 @@ int main() {
 chsize()
 ; return 0; }
 EOF
-if { (eval echo configure:2123: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2162: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -2153,12 +2192,12 @@ done
 for ac_func in strftime
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:2157: checking for $ac_func" >&5
+echo "configure:2196: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2162 "configure"
+#line 2201 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -2181,7 +2220,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:2185: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2224: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -2203,7 +2242,7 @@ EOF
 else
   echo "$ac_t""no" 1>&6
 echo $ac_n "checking for strftime in -lintl""... $ac_c" 1>&6
-echo "configure:2207: checking for strftime in -lintl" >&5
+echo "configure:2246: checking for strftime in -lintl" >&5
 ac_lib_var=`echo intl'_'strftime | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -2211,7 +2250,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lintl  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 2215 "configure"
+#line 2254 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -2222,7 +2261,7 @@ int main() {
 strftime()
 ; return 0; }
 EOF
-if { (eval echo configure:2226: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2265: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -2253,6 +2292,67 @@ fi
 done
 
 
+for ac_func in fchdir
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:2299: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2304 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2327: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+ cat >> confdefs.h <<\EOF
+#define HAVE_FCHDIR 1
+EOF
+
+else
+  echo "$ac_t""no" 1>&6
+mutt_cv_fchdir=no
+fi
+done
+
+
+
 mutt_cv_regex=yes
 # Check whether --with-rx or --without-rx was given.
 if test "${with_rx+set}" = set; then
@@ -2275,12 +2375,12 @@ else
   for ac_func in regcomp
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:2279: checking for $ac_func" >&5
+echo "configure:2379: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2284 "configure"
+#line 2384 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -2303,7 +2403,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:2307: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2407: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -2374,7 +2474,7 @@ if test "${with_mailpath+set}" = set; then
   mutt_cv_mailpath=$withval
 else
    echo $ac_n "checking where new mail is stored""... $ac_c" 1>&6
-echo "configure:2378: checking where new mail is stored" >&5
+echo "configure:2478: checking where new mail is stored" >&5
 if eval "test \"`echo '$''{'mutt_cv_mailpath'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2403,7 +2503,7 @@ EOF
 
 
        echo $ac_n "checking if $mutt_cv_mailpath is world writable""... $ac_c" 1>&6
-echo "configure:2407: checking if $mutt_cv_mailpath is world writable" >&5
+echo "configure:2507: checking if $mutt_cv_mailpath is world writable" >&5
 if eval "test \"`echo '$''{'mutt_cv_worldwrite'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2411,7 +2511,7 @@ else
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
   cat > conftest.$ac_ext <<EOF
-#line 2415 "configure"
+#line 2515 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -2425,7 +2525,7 @@ int main (int argc, char **argv)
        exit (1);
 }
 EOF
-if { (eval echo configure:2429: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2529: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   mutt_cv_worldwrite=yes
 else
@@ -2450,7 +2550,7 @@ EOF
        else
 
                echo $ac_n "checking if $mutt_cv_mailpath is group writable""... $ac_c" 1>&6
-echo "configure:2454: checking if $mutt_cv_mailpath is group writable" >&5
+echo "configure:2554: checking if $mutt_cv_mailpath is group writable" >&5
 if eval "test \"`echo '$''{'mutt_cv_groupwrite'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2458,7 +2558,7 @@ else
     { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
 else
   cat > conftest.$ac_ext <<EOF
-#line 2462 "configure"
+#line 2562 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -2472,7 +2572,7 @@ int main (int argc, char **argv)
        exit (1);
 }
 EOF
-if { (eval echo configure:2476: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2576: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   mutt_cv_groupwrite=yes
 else
@@ -2502,29 +2602,63 @@ EOF
        fi
 fi
 
+if test "x$mutt_cv_setgid" = "xyes" || test "x$mutt_cv_fchdir" = "xno"
+then
+       CPPFLAGS="$CPPFLAGS -DDL_STANDALONE"
+       DOTLOCK_TARGET="dotlock"
+       DOTLOCK_INSTALL_TARGET="install.dotlock"
+else
+       LIBOBJS="$LIBOBJS dotlock.o"
+fi
+
+
+
+
+
+
+# Check whether --with-libdir or --without-libdir was given.
+if test "${with_libdir+set}" = set; then
+  withval="$with_libdir"
+  mutt_cv_libdir=$withval
+else
+   echo $ac_n "checking where to put architecture-dependent files""... $ac_c" 1>&6
+echo "configure:2626: checking where to put architecture-dependent files" >&5
+if eval "test \"`echo '$''{'mutt_cv_libdir'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -d ${mutt_cv_prefix}/lib/misc; then
+                       mutt_cv_libdir="${mutt_cv_prefix}/lib/misc"
+               else
+                       mutt_cv_libdir="${mutt_cv_prefix}/lib"
+               fi
+fi
+
+echo "$ac_t""$mutt_cv_libdir" 1>&6
+       
+fi
+
+
+libdir=$mutt_cv_libdir
+
+
 # Check whether --with-sharedir or --without-sharedir was given.
 if test "${with_sharedir+set}" = set; then
   withval="$with_sharedir"
   mutt_cv_sharedir=$withval
 else
    echo $ac_n "checking where to put architecture-independent data files""... $ac_c" 1>&6
-echo "configure:2512: checking where to put architecture-independent data files" >&5
+echo "configure:2651: checking where to put architecture-independent data files" >&5
 if eval "test \"`echo '$''{'mutt_cv_sharedir'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
-  if test x$prefix = xNONE; then
-                       mutt_cv_prefix=$ac_default_prefix
-               else
-                       mutt_cv_prefix=$prefix
-               fi
-               if test -d ${mutt_cv_prefix}/share; then
+  if test -d ${mutt_cv_prefix}/share; then
                        if test -d ${mutt_cv_prefix}/share/misc; then
-                               mutt_cv_sharedir='${prefix}/share/misc'
+                               mutt_cv_sharedir="${mutt_cv_prefix}/share/misc"
                        else
-                               mutt_cv_sharedir='${prefix}/share'
+                               mutt_cv_sharedir="${mutt_cv_prefix}/share"
                        fi
                else
-                       mutt_cv_sharedir='${libdir}'
+                       mutt_cv_sharedir="$libdir"
                fi
 fi
 
@@ -2536,13 +2670,14 @@ fi
 sharedir=$mutt_cv_sharedir
 
 
+
 # Check whether --with-docdir or --without-docdir was given.
 if test "${with_docdir+set}" = set; then
   withval="$with_docdir"
   mutt_cv_docdir=$withval
 else
    echo $ac_n "checking where to put the documentation""... $ac_c" 1>&6
-echo "configure:2546: checking where to put the documentation" >&5
+echo "configure:2681: checking where to put the documentation" >&5
 if eval "test \"`echo '$''{'mutt_cv_docdir'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2564,11 +2699,11 @@ docdir=$mutt_cv_docdir
 
 
 if test x$mutt_cv_setgid = xyes; then
-       MUTT_GROUP='-g mail'
-       MUTT_PERMISSION=2755
+       DOTLOCK_GROUP='-g mail'
+       DOTLOCK_PERMISSION=2755
 else
-       MUTT_GROUP=''
-       MUTT_PERMISSION=755
+       DOTLOCK_GROUP=''
+       DOTLOCK_PERMISSION=755
 fi
 
 
@@ -2585,16 +2720,6 @@ EOF
 fi
 
 
-# Check whether --enable-hidden-host or --disable-hidden-host was given.
-if test "${enable_hidden_host+set}" = set; then
-  enableval="$enable_hidden_host"
-  cat >> confdefs.h <<\EOF
-#define HIDDEN_HOST 1
-EOF
-
-fi
-
-
 # Check whether --enable-pop or --disable-pop was given.
 if test "${enable_pop+set}" = set; then
   enableval="$enable_pop"
@@ -2603,7 +2728,7 @@ if test "${enable_pop+set}" = set; then
 EOF
 
        echo $ac_n "checking for socket in -lsocket""... $ac_c" 1>&6
-echo "configure:2607: checking for socket in -lsocket" >&5
+echo "configure:2732: checking for socket in -lsocket" >&5
 ac_lib_var=`echo socket'_'socket | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -2611,7 +2736,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lsocket  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 2615 "configure"
+#line 2740 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -2622,7 +2747,7 @@ int main() {
 socket()
 ; return 0; }
 EOF
-if { (eval echo configure:2626: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2751: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -2650,7 +2775,7 @@ else
 fi
 
        echo $ac_n "checking for gethostbyname in -lnsl""... $ac_c" 1>&6
-echo "configure:2654: checking for gethostbyname in -lnsl" >&5
+echo "configure:2779: checking for gethostbyname in -lnsl" >&5
 ac_lib_var=`echo nsl'_'gethostbyname | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -2658,7 +2783,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lnsl  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 2662 "configure"
+#line 2787 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -2669,7 +2794,7 @@ int main() {
 gethostbyname()
 ; return 0; }
 EOF
-if { (eval echo configure:2673: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2798: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -2709,7 +2834,7 @@ if test "${enable_imap+set}" = set; then
 EOF
 
        echo $ac_n "checking for socket in -lsocket""... $ac_c" 1>&6
-echo "configure:2713: checking for socket in -lsocket" >&5
+echo "configure:2838: checking for socket in -lsocket" >&5
 ac_lib_var=`echo socket'_'socket | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -2717,7 +2842,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lsocket  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 2721 "configure"
+#line 2846 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -2728,7 +2853,7 @@ int main() {
 socket()
 ; return 0; }
 EOF
-if { (eval echo configure:2732: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2857: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -2756,7 +2881,7 @@ else
 fi
 
        echo $ac_n "checking for gethostbyname in -lnsl""... $ac_c" 1>&6
-echo "configure:2760: checking for gethostbyname in -lnsl" >&5
+echo "configure:2885: checking for gethostbyname in -lnsl" >&5
 ac_lib_var=`echo nsl'_'gethostbyname | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -2764,7 +2889,7 @@ else
   ac_save_LIBS="$LIBS"
 LIBS="-lnsl  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 2768 "configure"
+#line 2893 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -2775,7 +2900,7 @@ int main() {
 gethostbyname()
 ; return 0; }
 EOF
-if { (eval echo configure:2779: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2904: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -2802,7 +2927,7 @@ else
   echo "$ac_t""no" 1>&6
 fi
 
-       LIBOBJS="$LIBOBJS imap.o"
+       LIBOBJS="$LIBOBJS imap.o socket.o"
 
 fi
 
@@ -3009,7 +3134,7 @@ done
 ac_given_srcdir=$srcdir
 ac_given_INSTALL="$INSTALL"
 
-trap 'rm -fr `echo "Makefile rx/Makefile Muttrc doc/Makefile config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+trap 'rm -fr `echo "Makefile rx/Makefile Muttrc doc/Makefile doc/dotlock.man doc/mutt.man config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
 EOF
 cat >> $CONFIG_STATUS <<EOF
 
@@ -3039,6 +3164,11 @@ s%@includedir@%$includedir%g
 s%@oldincludedir@%$oldincludedir%g
 s%@infodir@%$infodir%g
 s%@mandir@%$mandir%g
+s%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
 s%@CC@%$CC%g
 s%@SET_MAKE@%$SET_MAKE%g
 s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
@@ -3052,10 +3182,13 @@ s%@VERSION@%$VERSION%g
 s%@ISPELL@%$ISPELL%g
 s%@CPP@%$CPP%g
 s%@LIBOBJS@%$LIBOBJS%g
+s%@SNPRINTFOBJS@%$SNPRINTFOBJS%g
+s%@DOTLOCK_TARGET@%$DOTLOCK_TARGET%g
+s%@DOTLOCK_INSTALL_TARGET@%$DOTLOCK_INSTALL_TARGET%g
 s%@sharedir@%$sharedir%g
 s%@docdir@%$docdir%g
-s%@MUTT_GROUP@%$MUTT_GROUP%g
-s%@MUTT_PERMISSION@%$MUTT_PERMISSION%g
+s%@DOTLOCK_GROUP@%$DOTLOCK_GROUP%g
+s%@DOTLOCK_PERMISSION@%$DOTLOCK_PERMISSION%g
 
 CEOF
 EOF
@@ -3097,7 +3230,7 @@ EOF
 
 cat >> $CONFIG_STATUS <<EOF
 
-CONFIG_FILES=\${CONFIG_FILES-"Makefile rx/Makefile Muttrc doc/Makefile"}
+CONFIG_FILES=\${CONFIG_FILES-"Makefile rx/Makefile Muttrc doc/Makefile doc/dotlock.man doc/mutt.man"}
 EOF
 cat >> $CONFIG_STATUS <<\EOF
 for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
index 36f065076003119841c9ad9d01ce9f9cea871c04..e4a19da586437b1386b620089e44b0a8ac762b03 100644 (file)
@@ -1,9 +1,11 @@
 dnl Process this file with autoconf to produce a configure script.
 AC_INIT(mutt.h)
 AC_CONFIG_HEADER(config.h)
-VERSION=0.92.11
+VERSION=0.94.4
 SUBVERSION=''
 
+AC_CANONICAL_HOST
+
 AC_MSG_CHECKING(for prefix)
 if test x$prefix = xNONE; then
        mutt_cv_prefix=$ac_default_prefix
@@ -16,6 +18,14 @@ AC_PROG_CC
 AC_PROG_MAKE_SET
 AC_PROG_INSTALL
 
+case "$host" in
+*-*-hpux*)
+       if test -z "$GCC" ; then
+               CFLAGS="$CFLAGS -Ae -D_HPUX_SOURCE"
+       fi
+       ;;
+esac
+
 AC_PATH_PROG(SENDMAIL, sendmail, no, `echo $PATH | sed "s/:/ /"` /usr/sbin /usr/lib)
 AC_DEFINE_UNQUOTED(SENDMAIL, "$ac_cv_path_SENDMAIL")
 
@@ -164,7 +174,7 @@ main ()
 
 AC_HEADER_STDC
 
-AC_CHECK_HEADERS(stdarg.h sys/ioctl.h)
+AC_CHECK_HEADERS(stdarg.h sys/ioctl.h sysexits.h)
 
 AC_TYPE_SIGNAL
 
@@ -180,11 +190,14 @@ AC_CHECK_FUNCS(setegid srand48 strerror)
 AC_REPLACE_FUNCS(strcasecmp)
 
 mutt_cv_snprintf=no
+SNPRINTFOBJS=""
 AC_CHECK_FUNC(snprintf, [AC_DEFINE(HAVE_SNPRINTF)], [mutt_cv_snprintf=yes])
 AC_CHECK_FUNC(vsnprintf, [AC_DEFINE(HAVE_VSNPRINTF)], [mutt_cv_snprintf=yes])
 if test $mutt_cv_snprintf = yes; then
        LIBOBJS="$LIBOBJS snprintf.o"
+       SNPRINTFOBJS="snprintf.o"
 fi
+AC_SUBST(SNPRINTFOBJS)
 
 dnl SCO uses chsize() instead of ftruncate()
 AC_CHECK_FUNCS(ftruncate, break, [AC_CHECK_LIB(x, chsize)])
@@ -192,6 +205,10 @@ AC_CHECK_FUNCS(ftruncate, break, [AC_CHECK_LIB(x, chsize)])
 dnl SCO has strftime() in libintl
 AC_CHECK_FUNCS(strftime, break, [AC_CHECK_LIB(intl, strftime)])
 
+dnl AIX may not have fchdir()
+AC_CHECK_FUNCS(fchdir, [AC_DEFINE(HAVE_FCHDIR)], [mutt_cv_fchdir=no])
+
+
 mutt_cv_regex=yes
 AC_ARG_WITH(rx, [  --with-rx[=DIR]            Use GNU rx ],
        [if test $withval != yes; then
@@ -284,29 +301,53 @@ int main (int argc, char **argv)
        fi
 fi
 
+if test "x$mutt_cv_setgid" = "xyes" || test "x$mutt_cv_fchdir" = "xno"
+then
+       CPPFLAGS="$CPPFLAGS -DDL_STANDALONE"
+       DOTLOCK_TARGET="dotlock"
+       DOTLOCK_INSTALL_TARGET="install.dotlock"
+else
+       LIBOBJS="$LIBOBJS dotlock.o"
+fi
+
+AC_SUBST(DOTLOCK_TARGET)
+AC_SUBST(DOTLOCK_INSTALL_TARGET)
+
+
+
+AC_ARG_WITH(libdir, [  --with-libdir=PATH       specify where to put arch dependent files],
+       [mutt_cv_libdir=$withval],
+       [ AC_CACHE_CHECK(where to put architecture-dependent files,
+                      mutt_cv_libdir,
+               [if test -d ${mutt_cv_prefix}/lib/misc; then
+                       mutt_cv_libdir="${mutt_cv_prefix}/lib/misc"
+               else
+                       mutt_cv_libdir="${mutt_cv_prefix}/lib"
+               fi])
+       ])
+
+libdir=$mutt_cv_libdir
+AC_SUBST(libdir)
+
 AC_ARG_WITH(sharedir, [  --with-sharedir=PATH       specify where to put arch independent files],
        [mutt_cv_sharedir=$withval],
        [ AC_CACHE_CHECK(where to put architecture-independent data files,
                       mutt_cv_sharedir,
-               [if test x$prefix = xNONE; then
-                       mutt_cv_prefix=$ac_default_prefix
-               else
-                       mutt_cv_prefix=$prefix
-               fi
-               if test -d ${mutt_cv_prefix}/share; then
+               [if test -d ${mutt_cv_prefix}/share; then
                        if test -d ${mutt_cv_prefix}/share/misc; then
-                               mutt_cv_sharedir='${prefix}/share/misc'
+                               mutt_cv_sharedir="${mutt_cv_prefix}/share/misc"
                        else
-                               mutt_cv_sharedir='${prefix}/share'
+                               mutt_cv_sharedir="${mutt_cv_prefix}/share"
                        fi
                else
-                       mutt_cv_sharedir='${libdir}'
+                       mutt_cv_sharedir="$libdir"
                fi])
        ])
 
 sharedir=$mutt_cv_sharedir
 AC_SUBST(sharedir)
 
+
 AC_ARG_WITH(docdir, [  --with-docdir=PATH       specify where to put the documentation],
        [mutt_cv_docdir=$withval],
        [ AC_CACHE_CHECK(where to put the documentation,
@@ -324,22 +365,20 @@ AC_SUBST(docdir)
 
 
 if test x$mutt_cv_setgid = xyes; then
-       MUTT_GROUP='-g mail'
-       MUTT_PERMISSION=2755
+       DOTLOCK_GROUP='-g mail'
+       DOTLOCK_PERMISSION=2755
 else
-       MUTT_GROUP=''
-       MUTT_PERMISSION=755
+       DOTLOCK_GROUP=''
+       DOTLOCK_PERMISSION=755
 fi
-AC_SUBST(MUTT_GROUP)
-AC_SUBST(MUTT_PERMISSION)
+AC_SUBST(DOTLOCK_GROUP)
+AC_SUBST(DOTLOCK_PERMISSION)
 
 AC_ARG_WITH(domain, [  --with-domain=DOMAIN       Specify your DNS domain name ],
        [if test $withval != yes; then
                AC_DEFINE_UNQUOTED(DOMAIN, "$withval")
        fi])
 
-AC_ARG_ENABLE(hidden-host, [  --enable-hidden-host       Only use the domain name for local addresses], AC_DEFINE(HIDDEN_HOST))
-
 AC_ARG_ENABLE(pop, [  --enable-pop               Enable POP3 support],
 [      AC_DEFINE(USE_POP)
        AC_CHECK_LIB(socket, socket)
@@ -351,7 +390,7 @@ AC_ARG_ENABLE(imap, [  --enable-imap              Enable IMAP support],
 [      AC_DEFINE(USE_IMAP)
        AC_CHECK_LIB(socket, socket)
        AC_CHECK_LIB(nsl, gethostbyname)
-       LIBOBJS="$LIBOBJS imap.o"
+       LIBOBJS="$LIBOBJS imap.o socket.o"
 ])
 
 AC_ARG_ENABLE(flock, [  --enable-flock             Use flock() to lock files],
@@ -402,4 +441,4 @@ AC_ARG_ENABLE(exact-address, [  --enable-exact-address     enable regeneration o
                AC_DEFINE(EXACT_ADDRESS)
        fi])
 
-AC_OUTPUT(Makefile rx/Makefile Muttrc doc/Makefile)
+AC_OUTPUT(Makefile rx/Makefile Muttrc doc/Makefile doc/dotlock.man doc/mutt.man)
diff --git a/copy.c b/copy.c
index 9dcbe98ca8609fa532ce8314793cae29be55f57d..ebd597941205ee21e6911b7524473ce149532025 100644 (file)
--- a/copy.c
+++ b/copy.c
@@ -415,18 +415,19 @@ _mutt_copy_message (FILE *fpout, FILE *fpin, HEADER *hdr, BODY *body,
     fseek (fpin, body->offset, 0);
     if (flags & M_CM_PREFIX)
     {
-      char buf[LONG_STRING];
+      int c;
       size_t bytes = body->length;
-
-      buf[sizeof (buf) - 1] = 0;
-      while (bytes > 0)
+      
+      fputs(prefix, fpout);
+      
+      while((c = fgetc(fpin)) != EOF && bytes--)
       {
-       if (fgets (buf, sizeof (buf) - 1, fpin) == NULL)
-         break;
-       bytes -= strlen (buf);
-       fputs (prefix, fpout);
-       fputs (buf, fpout);
-      }
+       fputc(c, fpout);
+       if(c == '\n')
+       {
+         fputs(prefix, fpout);
+       }
+      } 
     }
     else
     {
index c2177fc2f92ed64357dcc610e059dcf0633f9ada..fa7feb19c5ab73bae4662ccf130778039f3860bb 100644 (file)
@@ -178,6 +178,7 @@ void mutt_curses_error (const char *fmt, ...)
   vsnprintf (Errorbuf, sizeof (Errorbuf), fmt, ap);
   va_end (ap);
   
+  dprint (1, (debugfile, "%s\n", Errorbuf));
   Errorbuf[ (COLS < sizeof (Errorbuf) ? COLS : sizeof (Errorbuf)) - 2 ] = 0;
 
   BEEP ();
@@ -232,6 +233,8 @@ void mutt_perror (const char *s)
 {
   char *p = strerror (errno);
 
+  dprint (1, (debugfile, "%s: %s (errno = %d)\n", s, 
+      p ? p : "unknown error", errno));
   mutt_error ("%s: %s (errno = %d)", s, p ? p : "unknown error", errno);
 }
 
@@ -269,14 +272,14 @@ int mutt_do_pager (const char *banner,
 {
   int rc;
 
-  if (strcmp (Pager, "builtin") == 0)
-    rc = mutt_pager (banner, tempfile, do_color, info);
+  if (!Pager || strcmp (Pager, "builtin") == 0)
+    rc = mutt_pager (banner, tempfile, do_color, info, "");
   else
   {
     char cmd[STRING];
     
     endwin ();
-    snprintf (cmd, sizeof (cmd), "%s %s", Pager, tempfile);
+    snprintf (cmd, sizeof (cmd), "%s %s", NONULL(Pager), tempfile);
     mutt_system (cmd);
     mutt_unlink (tempfile);
     rc = 0;
@@ -318,7 +321,7 @@ int mutt_enter_fname (const char *prompt, char *buf, size_t blen, int *redraw, i
        != 0)
       buf[0] = 0;
     MAYBE_REDRAW (*redraw);
-    free (pc);
+    FREE (&pc);
   }
 
   return 0;
index cf06bcf909aedf0353dddadd94e59a9dbff19ae0..d1be5a8bf0fcb7b0366e7a82212fc07c28936a9c 100644 (file)
@@ -20,6 +20,7 @@
 #include "mutt_curses.h"
 #include "mutt_menu.h"
 #include "mailbox.h"
+#include "mapping.h"
 #include "sort.h"
 #include "buffy.h"
 
@@ -85,7 +86,16 @@ void index_make_entry (char *s, size_t l, MUTTMENU *menu, int num)
       flag |= M_FORMAT_FORCESUBJ;
     else
     {
-      edgemsgno = Context->v2r[menu->top + (reverse ? menu->pagelen - 1 : 0)];
+      if (reverse)
+      {
+       if (menu->top + menu->pagelen > menu->max)
+         edgemsgno = Context->v2r[menu->max - 1];
+       else
+         edgemsgno = Context->v2r[menu->top + menu->pagelen - 1];
+      }
+      else
+       edgemsgno = Context->v2r[menu->top];
+
       for (tmp = h->parent; tmp; tmp = tmp->parent)
       {
        if ((reverse && tmp->msgno > edgemsgno)
@@ -220,9 +230,9 @@ struct mapping_t IndexHelp[] = {
 /* This function handles the message index window as well as commands returned
  * from the pager (MENU_PAGER).
  */
-void mutt_index_menu (void)
+int mutt_index_menu (int attach_msg /* invoked while attaching a message */)
 {
-  char buf[LONG_STRING], helpstr[SHORT_STRING];
+  char buf[LONG_STRING], attach_msg_status[LONG_STRING] = "", helpstr[SHORT_STRING];
   int op = OP_NULL;                 /* function to execute */
   int done = 0;                /* controls when to exit the "event" loop */
   int i = 0, j;
@@ -234,6 +244,7 @@ void mutt_index_menu (void)
   char *cp;                    /* temporary variable. */
   int index_hint;   /* used to restore cursor position */
   int do_buffy_notify = 1;
+  int close = 0; /* did we OP_QUIT or OP_EXIT out of this menu? */
 
   menu = mutt_new_menu ();
   menu->menu = MENU_MAIN;
@@ -244,7 +255,8 @@ void mutt_index_menu (void)
   menu->current = ci_first_message ();
   menu->help = mutt_compile_help (helpstr, sizeof (helpstr), MENU_MAIN, IndexHelp);
   
-  mutt_buffy_check(1); /* force the buffy check after we enter the folder */
+  if (!attach_msg) 
+    mutt_buffy_check(1); /* force the buffy check after we enter the folder */
 
   FOREVER
   {
@@ -253,7 +265,7 @@ void mutt_index_menu (void)
     menu->max = Context ? Context->vcount : 0;
     oldcount = Context ? Context->msgcount : 0;
 
-    if (Context)
+    if (Context && !attach_msg)
     {
       /* check for new mail in the mailbox.  If nonzero, then something has
        * changed about the file (either we got new mail or the file was
@@ -345,17 +357,20 @@ void mutt_index_menu (void)
       }
     }
 
-    /* check for new mail in the incoming folders */
-    oldcount = newcount;
-    if ((newcount = mutt_buffy_check (0)) != oldcount)
-      menu->redraw |= REDRAW_STATUS;
-    if (do_buffy_notify)
+    if (!attach_msg)
     {
-      if (mutt_buffy_notify () && option (OPTBEEPNEW))
-       beep ();
+     /* check for new mail in the incoming folders */
+     oldcount = newcount;
+     if ((newcount = mutt_buffy_check (0)) != oldcount)
+       menu->redraw |= REDRAW_STATUS;
+     if (do_buffy_notify)
+     {
+       if (mutt_buffy_notify () && option (OPTBEEPNEW))
+       beep ();
+     }
+     else
+       do_buffy_notify = 1;
     }
-    else
-      do_buffy_notify = 1;
 
     mutt_curs_set (0);
 
@@ -384,7 +399,19 @@ void mutt_index_menu (void)
 
       if (menu->redraw & REDRAW_STATUS) 
       {
-       menu_status_line (buf, sizeof (buf), menu, NONULL (Status));
+       if (attach_msg)
+       {
+        char from_folder [STRING];
+        strfcpy(from_folder, Context->path, sizeof (from_folder));
+        mutt_pretty_mailbox (from_folder);
+        snprintf (attach_msg_status, sizeof (attach_msg_status), 
+                  "Folder: %s Tagged messages will be attached upon exiting", 
+                  from_folder);
+        snprintf (buf, sizeof (buf), M_MODEFMT, attach_msg_status);
+       }
+       else
+        menu_status_line (buf, sizeof (buf), menu, NONULL (Status));
+
        CLEARLINE (option (OPTSTATUSONTOP) ? 0 : LINES-2);
        SETCOLOR (MT_COLOR_STATUS);
        printw ("%-*.*s", COLS, COLS, buf);
@@ -527,7 +554,7 @@ void mutt_index_menu (void)
            !buf[0])
          break;
 
-       if (! isdigit (buf[0]))
+       if (! isdigit ((unsigned char) buf[0]))
        {
          mutt_error ("Argument must be a message number.");
          break;
@@ -577,7 +604,7 @@ void mutt_index_menu (void)
 
        CHECK_MSGCOUNT;
        CHECK_READONLY;
-       mutt_pattern_func (M_DELETE, "Delete messages matching: ", CURHDR);
+       mutt_pattern_func (M_DELETE, "Delete messages matching: ");
        menu->redraw = REDRAW_INDEX | REDRAW_STATUS;
        break;
 
@@ -611,7 +638,7 @@ void mutt_index_menu (void)
 
        CHECK_MSGCOUNT;
        menu->oldcurrent = Context->vcount ? CURHDR->index : -1;
-       if (mutt_pattern_func (M_LIMIT, "Limit to messages matching: ", CURHDR) == 0)
+       if (mutt_pattern_func (M_LIMIT, "Limit to messages matching: ") == 0)
        {
          if (menu->oldcurrent >= 0)
          {
@@ -634,6 +661,13 @@ void mutt_index_menu (void)
 
       case OP_QUIT:
 
+       close = op;
+       if (attach_msg)
+       {
+        done = 1;
+        break;
+       }
+
        if (query_quadoption (OPT_QUIT, "Quit Mutt?") == M_YES)
        { 
          if (!Context || mx_close_mailbox (Context) == 0)
@@ -702,13 +736,15 @@ void mutt_index_menu (void)
          if (mx_sync_mailbox (Context) == 0)
          {
            if (Context->vcount != oldvcount)
-           {
              menu->current -= dcount;
-             if (menu->current < 0 || menu->current >= Context->vcount)
-               menu->current = ci_first_message ();
-           }
            set_option (OPTSEARCHINVALID);
          }
+         
+         /* do a sanity check even if mx_sync_mailbox failed.
+          */
+
+         if (menu->current < 0 || menu->current >= Context->vcount)
+           menu->current = ci_first_message ();
        }
 
        /* check for a fatal error, or all messages deleted */
@@ -743,7 +779,7 @@ void mutt_index_menu (void)
       case OP_MAIN_TAG_PATTERN:
 
        CHECK_MSGCOUNT;
-       mutt_pattern_func (M_TAG, "Tag messages matching: ", CURHDR);
+       mutt_pattern_func (M_TAG, "Tag messages matching: ");
        menu->redraw = REDRAW_INDEX | REDRAW_STATUS;
        break;
 
@@ -751,14 +787,14 @@ void mutt_index_menu (void)
 
        CHECK_MSGCOUNT;
        CHECK_READONLY;
-       if (mutt_pattern_func (M_UNDELETE, "Undelete messages matching: ", CURHDR) == 0)
+       if (mutt_pattern_func (M_UNDELETE, "Undelete messages matching: ") == 0)
          menu->redraw = REDRAW_INDEX | REDRAW_STATUS;
        break;
 
       case OP_MAIN_UNTAG_PATTERN:
 
        CHECK_MSGCOUNT;
-       if (mutt_pattern_func (M_UNTAG, "Untag messages matching: ", CURHDR) == 0)
+       if (mutt_pattern_func (M_UNTAG, "Untag messages matching: ") == 0)
          menu->redraw = REDRAW_INDEX | REDRAW_STATUS;
        break;
 
@@ -768,7 +804,7 @@ void mutt_index_menu (void)
 
       case OP_MAIN_CHANGE_FOLDER:
       
-       if (option (OPTREADONLY))
+       if (attach_msg || option (OPTREADONLY))
          op = OP_MAIN_CHANGE_FOLDER_READONLY;
 
        /* fallback to the readonly case */
@@ -847,7 +883,7 @@ void mutt_index_menu (void)
 
        unset_option (OPTNEEDRESORT);
 
-       if ((op = mutt_display_message (CURHDR)) == -1)
+       if ((op = mutt_display_message (CURHDR, attach_msg_status)) == -1)
        {
          unset_option (OPTNEEDRESORT);
          break;
@@ -873,17 +909,17 @@ void mutt_index_menu (void)
 
       case OP_EXIT:
 
+       close = op;
+       if (menu->menu == MENU_MAIN && attach_msg)
+       {
+        done = 1;
+        break;
+       }
+
        if ((menu->menu == MENU_MAIN)
            && (query_quadoption (OPT_QUIT, 
                                  "Exit Mutt without saving?") == M_YES))
-       {
-         if (Context)
-         {
-           mx_fastclose_mailbox (Context);
-           safe_free ((void **)&Context);
-         }
          done = 1;
-       }
        break;
 
       case OP_MAIN_NEXT_UNDELETED:
@@ -1130,12 +1166,6 @@ void mutt_index_menu (void)
       case OP_MAIN_PREV_SUBTHREAD:
 
        CHECK_MSGCOUNT;
-       if (Context->msgcount != Context->vcount)
-       {
-         mutt_error ("No threads in limit mode.");
-         break;
-       }
-
        switch (op)
        {
          case OP_MAIN_NEXT_THREAD:
@@ -1511,6 +1541,7 @@ void mutt_index_menu (void)
   }
 
   mutt_menuDestroy (&menu);
+  return (close);
 }
 
 void mutt_set_header_color (CONTEXT *ctx, HEADER *curhdr)
diff --git a/date.c b/date.c
index 9cd2089761b423c1f9dea8c0de810fd79c50240b..35f4ebfdf6de998db528956df6962476eec5dedf 100644 (file)
--- a/date.c
+++ b/date.c
@@ -17,6 +17,7 @@
  */ 
 
 #include "mutt.h"
+#include <string.h>
 
 /* returns the seconds west of UTC given `g' and its corresponding gmtime()
    representation */
index a8f0d9be5530a4adb529adf1c5a83db0992e8366..44ba7c5e03c5d830292de2160807a001a8bddaad 100644 (file)
@@ -19,15 +19,22 @@ CFLAGS=@CFLAGS@ -DSHAREDIR=\"$(sharedir)\" $(XCPPFLAGS)
 LDFLAGS=@LDFLAGS@
 
 
-all: manual.txt mutt.man manual.html
+all: mutt.man dotlock.man manual.txt manual.html
 
-install: mutt.man manual.txt
+install: dotlock.man mutt.man manual.txt
        ../mkinstalldirs $(mandir)/man1
        $(INSTALL) -m 644 mutt.man $(mandir)/man1/mutt.1
+       $(INSTALL) -m 644 dotlock.man $(mandir)/man1/mutt.dotlock.1
        ../mkinstalldirs $(docdir)
        $(INSTALL) -m 644 manual.txt $(docdir)
        $(INSTALL) -m 644 PGP-Notes.txt $(docdir)
 
+mutt.man: mutt.man.in
+       (cd .. ; ./config.status)
+
+dotlock.man: dotlock.man.in
+       (cd .. ; ./config.status)
+
 uninstall:
        -rm -f $(mandir)/man1/mutt.1 $(docdir)/manual.txt       \
                $(docdir)/PGP-Notes.txt
@@ -38,8 +45,11 @@ manual.txt: manual.sgml
 manual.html: manual.sgml
        sgml2html manual
 
-mutt.man: mutt.sgml
-       sgml2txt -man mutt
+clean: 
+       rm -f *~ *.html *.orig *.rej *.man
+
+clean-real:
+       rm -f manual.txt
 
-clean clean-real distclean:
-       rm -f *~ *.html *.orig *.rej
+distclean: clean
+       rm -f Makefile
index bfc09299f91c7fb3792f9ed707fde1b50c47e164..3081198ebc2c2f9a9704ce66fa02a2652f0ea9bf 100644 (file)
@@ -1,11 +1,10 @@
                
                
-               
                USING PGP FROM WITHIN MUTT
                
 
            Thomas Roessler <roessler@guug.de>
-              Fri Jun  5 12:28:52 CEST 1998
+              Fri Jul 10 10:57:50 MEST 1998
 
 
 While encryption, verification and signing of messages are
@@ -175,3 +174,16 @@ $PGPPATH and add the following line to your muttrc:
 
 For PGP 2.6, a German version called "muttde" is available
 as well.
+
+
+
+Q: "Isn't there a security problem that mutt leaves the
+    passphrase in memory which will be dumped into core
+    files upon errors?"
+
+Yes, you may consider this a security problem.  To work
+around this, disable core dumps using resource limits.  On
+most systems, this will be the following instruction in
+your shell:
+
+       ulimit -c 0
diff --git a/doc/dotlock.man.in b/doc/dotlock.man.in
new file mode 100644 (file)
index 0000000..609251d
--- /dev/null
@@ -0,0 +1,144 @@
+.\" -*-nroff-*-
+.\"
+.\"
+.\"     Copyright (C) 1996-8 Michael R. Elkins <me@cs.hmc.edu>
+.\"    Copyright (C) 1998 Thomas Roessler <roessler@guug.de>
+.\" 
+.\"     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.
+.\"
+.TH dotlock 1 "JULY 1998" Unix "User Manuals"
+.SH NAME
+.PP
+mutt.dotlock \- Lock mail spool files.
+.SH SYNOPSIS
+.PP
+.B mutt.dotlock 
+[-t|-f|-u] [-p] [-r \fIretries\fP] \fIfile\fP
+.SH DESCRIPTION
+.PP
+.B dotlock
+implements the traditional mail spool file locking method:
+To lock \fIfile\fP, a file named \fIfile\fP.lock is
+created. The program operates with group mail privileges
+if necessary.
+.SH OPTIONS
+.PP
+.IP "-t"
+Just try.
+.B dotlock
+won't actually lock a file, but inform the invoking
+process if it's at all possible to lock \fIfile\fP.
+.IP "-f"
+Force the lock.  If another process holds a lock on
+\fIfile\fP longer than a certain amount of time, 
+.B dotlock
+will break that lock by removing the lockfile.
+.IP "-u"
+Unlock.
+.B dotlock 
+will remove \fIfile\fP.lock.
+.IP "-p"
+Use privileges.  If given this option, 
+.B dotlock
+will operate with group mail privileges when creating and
+deleting lock files.
+.IP "-r \fIretries\fP"
+This command line option tells 
+.B dotlock 
+to try locking
+\fIretries\fP times before giving up or (if invoked with
+the 
+.B -f
+command line option) break a lock.  The default value is 5.
+.B dotlock
+waits one second between successive locking attempts.  
+.SH FILES
+.PP
+.IP "\fIfile\fP.lock"
+The lock file 
+.B dotlock
+generates.
+.SH SEE ALSO
+.PP
+.BR fcntl (2),
+.BR flock (2),
+.BR lockfile (1),
+.BR mutt (1)
+.SH DIAGNOSTICS
+.PP
+.B dotlock
+gives all diagnostics in its return values:
+.TP
+.B "0 \- DL_EX_OK"
+The program was successful.
+.TP 
+.B "1 \- DL_EX_ERROR"
+An unspecified error such as bad command line parameters,
+lack of system memory and the like has occured.
+.TP 
+.B "3 \- DL_EX_EXIST"
+The 
+user wants to lock a file which has been locked by
+another process already.  If 
+.B dotlock
+is invoked with the
+.B -f 
+command line option, 
+.B dotlock
+won't generate this error, but break other processes'
+locks.
+.TP 
+.B "4 \- DL_EX_NEED_RPIVS"
+This return value only occurs if 
+.B dotlock 
+has been invoked
+with the 
+.B -t
+command line option.  It means that
+.B dotlock
+will have to use its group mail privileges to lock
+\fIfile\fP.
+.TP
+.B "5 \- DL_EX_IMPOSSIBLE"
+This return value only occurs if
+.B dotlock
+has been invoked with the
+.B -t
+command line option.  It means that
+.B dotlock 
+is unable to lock \fIfile\fP even with group mail
+privileges.
+.SH NOTES
+.PP
+.B dotlock
+tries to implement an NFS-safe dotlocking method which was
+borrowed from 
+.B lockfile
+(1).  
+.PP
+If the user can't open \fIfile\fP for reading with his
+normal privileges, dotlock will return the
+.B DL_EX_ERROR
+exit value to avoid certain attacks against other users'
+spool files. The code carefully avoids race conditions
+when checking permissions; for details of all this see the
+comments in dotlock.c.
+.SH HISTORY
+.PP
+.B dotlock
+is part of the Mutt mail user agent package.  It has been
+created to avoid running mutt with group mail privileges.
+.SH AUTHOR
+Thomas Roessler <roessler@guug.de>
index a86f22606b6537528cbc38570e6b2986e916e961..f11a6ca684736d3a9e8cf4da165d52d3a53b4f64 100644 (file)
@@ -4,7 +4,7 @@
 
 <title>The Mutt E-Mail Client
 <author>by Michael Elkins <htmlurl url="mailto:me@cs.hmc.edu" name="&lt;me@cs.hmc.edu&gt;">
-<date>v0.92.2, 23 April 1998
+<date>v0.94.2, 31 July 1998
 <abstract>
 ``All mail clients suck.  This one just sucks less.'' -me, circa 1995
 </abstract>
@@ -19,21 +19,21 @@ groups of messages.
 
 <sect1>Mutt Home Page
 <p>
-<htmlurl url="http://www.cs.hmc.edu/~me/mutt/index.html"
-name="http://www.cs.hmc.edu/~me/mutt/index.html">
+<htmlurl url="http://www.mutt.org/"
+name="http://www.mutt.org/">
 
 <sect1>Mailing Lists
 <p>
 To subscribe to one of the following mailing lists, send a message with the
 word <em/subscribe/ in the subject to
-<tt/list-name/<em/-request/<tt/@cs.hmc.edu/.
+<tt/list-name/<em/-request/<tt/@mutt.org/.
 
 <itemize>
-<item><htmlurl url="mailto:mutt-announce-request@cs.hmc.edu"
-name="mutt-announce@cs.hmc.edu"> -- low traffic list for announcements
-<item><htmlurl url="mailto:mutt-users-request@cs.hmc.edu"
-name="mutt-users@cs.hmc.edu"> -- help, bug reports and feature requests
-<item><htmlurl url="mailto:mutt-dev-request@cs.hmc.edu" name="mutt-dev@cs.hmc.edu"> -- development mailing list
+<item><htmlurl url="mailto:mutt-announce-request@mutt.org"
+name="mutt-announce@mutt.org"> -- low traffic list for announcements
+<item><htmlurl url="mailto:mutt-users-request@mutt.org"
+name="mutt-users@mutt.org"> -- help, bug reports and feature requests
+<item><htmlurl url="mailto:mutt-dev-request@mutt.org" name="mutt-dev@mutt.org"> -- development mailing list
 </itemize>
 
 <bf/Note:/ all messages posted to <em/mutt-announce/ are automatically
@@ -43,8 +43,8 @@ lists.
 <sect1>Software Distribution Sites
 <p>
 <itemize>
-<item><htmlurl url="ftp://ftp.cs.hmc.edu/pub/me/mutt/"
-name="ftp://ftp.cs.hmc.edu/pub/me/mutt/">
+<item><htmlurl url="ftp://ftp.guug.de/pub/mutt/"
+name="ftp://ftp.guug.de/pub/mutt/">
 </itemize>
 
 <sect1>IRC
@@ -80,7 +80,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 This section is intended as a brief overview of how to use Mutt.  There are
 many other features which are described elsewhere in the manual.  There
 is even more information available in the Mutt FAQ and various web
-pages.  See the <htmlurl url="http://www.cs.hmc.edu/~me/mutt/"
+pages.  See the <htmlurl url="http://www.mutt.org/mutt/"
 name="Mutt Page"> for more details.
 
 The keybindings described in this section are the defaults as distributed.
@@ -98,14 +98,14 @@ Information is presented in menus, very similar to ELM.  Here is a table
 showing the common keys used to navigate menus in Mutt.
 
 <tscreen><verb>
-j or Down      next-entry      move to the next entry
-k or Up                previous-entry  move to the previous entry
-z or PageDn    page-down       go to the next page
-Z or PageUp    page-up         go to the previous page
-= or Home      first-entry     jump to the first entry
-* or End       last-entry      jump to the last entry
-q              quit            exit the current menu
-?              help            list all keybindings for the current menu
+j or Down       next-entry      move to the next entry
+k or Up         previous-entry  move to the previous entry
+z or PageDn     page-down       go to the next page
+Z or PageUp     page-up         go to the previous page
+= or Home       first-entry     jump to the first entry
+* or End        last-entry      jump to the last entry
+q               quit            exit the current menu
+?               help            list all keybindings for the current menu
 </verb></tscreen>
 
 <sect1>Editing Input Fields<label id="editing">
@@ -115,20 +115,20 @@ textual data such as email addresses or filenames.  The keys used to move
 around while editing are very similar to those of Emacs.
 
 <tscreen><verb>
-^A or <Home>   bol             move to the start of the line
-^B or <Left>   backward-char   move back one char
-^D or <Delete> delete-char     delete the char under the cursor
-^E or <End>    eol             move to the end of the line
-^F or <Right>  forward-char    move forward one char
-^K             kill-eol        delete to the end of the line
-^U             kill-line       delete entire line
-^W             kill-word       kill the word in front of the cursor
-<Up>           history-up      recall previous string from history
-<Down>         history-down    recall next string from history
-<BackSpace>    backspace       kill the char in front of the cursor
-^G             n/a             abort
-<Tab>          n/a             complete filename (only when prompting for a file)
-<Return>       n/a             finish editing
+^A or <Home>    bol             move to the start of the line
+^B or <Left>    backward-char   move back one char
+^D or <Delete>  delete-char     delete the char under the cursor
+^E or <End>     eol             move to the end of the line
+^F or <Right>   forward-char    move forward one char
+^K              kill-eol        delete to the end of the line
+^U              kill-line       delete entire line
+^W              kill-word       kill the word in front of the cursor
+<Up>            history-up      recall previous string from history
+<Down>          history-down    recall next string from history
+<BackSpace>     backspace       kill the char in front of the cursor
+^G              n/a             abort
+<Tab>           n/a             complete filename (only when prompting for a file)
+<Return>        n/a             finish editing
 </verb></tscreen>
 
 You can remap the <em/editor/ functions using the <ref id="bind" name="bind">
@@ -152,34 +152,34 @@ modes.
 <p>
 
 <tscreen><verb>
-c              change to a different mailbox
-ESC c          change to a folder in read-only mode
-C              copy the current message to another mailbox
-ESC C          decode a message and copy it to a folder
-ESC s          decode a message and save it to a folder
-D              delete messages matching a pattern
-d              delete the current message
-F              mark as important
-l              show messages matching a pattern
-N              mark message as new
-o              change the current sort method
-O              reverse sort the mailbox
-q              save changes and exit
-s              save-message
-t              toggle the tag on a message
-ESC t          toggle tag on entire message thread
-u              undelete-message
-v              view-attachments
-x              abort changes and exit
-<Return>       display-message
-<Tab>          jump to the next new message
-@              show the author's full e-mail address
-$              save changes to mailbox
-/              search
-ESC /          search-reverse
-^L             clear and redraw the screen
-^T             tag messages matching a pattern
-^U             undelete messages matching a pattern
+c               change to a different mailbox
+ESC c           change to a folder in read-only mode
+C               copy the current message to another mailbox
+ESC C           decode a message and copy it to a folder
+ESC s           decode a message and save it to a folder
+D               delete messages matching a pattern
+d               delete the current message
+F               mark as important
+l               show messages matching a pattern
+N               mark message as new
+o               change the current sort method
+O               reverse sort the mailbox
+q               save changes and exit
+s               save-message
+t               toggle the tag on a message
+ESC t           toggle tag on entire message thread
+u               undelete-message
+v               view-attachments
+x               abort changes and exit
+<Return>        display-message
+<Tab>           jump to the next new message
+@               show the author's full e-mail address
+$               save changes to mailbox
+/               search
+ESC /           search-reverse
+^L              clear and redraw the screen
+^T              tag messages matching a pattern
+^U              undelete messages matching a pattern
 </verb></tscreen>
 
 <sect3>Status Flags
@@ -191,16 +191,16 @@ Zero or more of the following ``flags'' may appear, which mean:
 
 <p>
 <tscreen><verb>
-D      message is deleted
-K      contains a PGP public key
-M      requires mailcap to view
-N      message is new
-O      message is old
-P      message is PGP encrypted
-r      message has been replied to
-S      message is PGP signed
-!      message is flagged
-*      message is tagged
+D       message is deleted
+K       contains a PGP public key
+M       requires mailcap to view
+N       message is new
+O       message is old
+P       message is PGP encrypted
+r       message has been replied to
+S       message is PGP signed
+!       message is flagged
+*       message is tagged
 </verb></tscreen>
 
 Some of the status flags can be turned on or off using
@@ -216,10 +216,10 @@ to.  They can be customized with the
 
 <p>
 <tscreen><verb>
-+      message is to you and you only
-T      message is to you, but also to or cc'ed to others
-C      message is cc'ed to you
-F      message is from you
++       message is to you and you only
+T       message is to you, but also to or cc'ed to others
+C       message is cc'ed to you
+F       message is from you
 </verb></tscreen>
 
 <sect2>The Pager
@@ -230,13 +230,13 @@ The pager is very similar to the Unix program <em/less/ though not nearly as
 featureful.
 
 <tscreen><verb>
-<Return>       go down one line
-<Space>                display the next page (or next message if at the end of a message)
--              go back to the previous page
-n              display the next message
-?              show keybindings
-/              search for a regular expression (pattern)
-\              toggle search pattern coloring
+<Return>        go down one line
+<Space>         display the next page (or next message if at the end of a message)
+-               go back to the previous page
+n               display the next message
+?               show keybindings
+/               search for a regular expression (pattern)
+\               toggle search pattern coloring
 </verb></tscreen>
 
 In addition, many of the functions from the <em/index/ are available in
@@ -291,17 +291,17 @@ When the mailbox is <ref id="sort" name="sorted"> by <em/threads/, there are
 a few additional functions available in the <em/index/ and <em/pager/ modes.
 
 <tscreen><verb>
-^D     delete-thread           delete all messages in the current thread
-^U     undelete-thread         undelete all messages in the current thread
-^N     next-thread             jump to the start of the next thread
-^P     previous-thread         jump to the start of the previous thread
-^R     read-thread             mark the current thread as read
-ESC d  delete-subthread        delete all messages in the current subthread
-ESC u  undelete-subthread      undelete all messages in the current subthread
-ESC n  next-subthread          jump to the start of the next subthread
-ESC p  previous-subthread      jump to the start of the previous subthread
-ESC r  read-subthread          mark the current subthread as read
-ESC t  tag-thread              toggle the tag on the current thread
+^D      delete-thread           delete all messages in the current thread
+^U      undelete-thread         undelete all messages in the current thread
+^N      next-thread             jump to the start of the next thread
+^P      previous-thread         jump to the start of the previous thread
+^R      read-thread             mark the current thread as read
+ESC d   delete-subthread        delete all messages in the current subthread
+ESC u   undelete-subthread      undelete all messages in the current subthread
+ESC n   next-subthread          jump to the start of the next subthread
+ESC p   previous-subthread      jump to the start of the previous subthread
+ESC r   read-subthread          mark the current subthread as read
+ESC t   tag-thread              toggle the tag on the current thread
 </verb></tscreen>
 
 See also: <ref id="strict_threads" name="&dollar;strict&lowbar;threads">.
@@ -391,13 +391,13 @@ The following bindings are available in the <em/index/ for sending
 messages.
 
 <tscreen><verb>
-m      compose         compose a new message
-r      reply           reply to sender
-g      group-reply     reply to all recipients
-L      list-reply      reply to mailing list address
-f      forward         forward message
-b      bounce          bounce (remail) message
-ESC k  mail-key        mail a PGP public key to someone
+m       compose         compose a new message
+r       reply           reply to sender
+g       group-reply     reply to all recipients
+L       list-reply      reply to mailing list address
+f       forward         forward message
+b       bounce          bounce (remail) message
+ESC k   mail-key        mail a PGP public key to someone
 </verb></tscreen>
 
 Bouncing a message sends the message as is to the recipient you
@@ -434,21 +434,21 @@ Once you have finished editing the body of your mail message, you are
 returned to the <em/compose/ menu.  The following options are available:
 
 <tscreen><verb>
-a      attach-file             attach a file
-ESC k  attach-key              attach a PGP public key
-d      edit-description        edit description on attachment
-D      detach-file             detach a file
-T      edit-to                 edit the To field
-c      edit-cc                 edit the Cc field
-b      edit-bcc                edit the Bcc field
-y      send-message            send the message
-s      edit-subject            edit the Subject
-f      edit-fcc                specify an ``Fcc'' mailbox
-p      pgp-menu                select PGP options (``i'' version only)
-P      postpone-message        postpone this message until later
-q      quit                    quit (abort) sending the message
-i      ispell                  check spelling (if available on your system)
-^F     forget-passphrase       whipe PGP passphrase from memory
+a       attach-file             attach a file
+ESC k   attach-key              attach a PGP public key
+d       edit-description        edit description on attachment
+D       detach-file             detach a file
+T       edit-to                 edit the To field
+c       edit-cc                 edit the Cc field
+b       edit-bcc                edit the Bcc field
+y       send-message            send the message
+s       edit-subject            edit the Subject
+f       edit-fcc                specify an ``Fcc'' mailbox
+p       pgp-menu                select PGP options (``i'' version only)
+P       postpone-message        postpone this message until later
+q       quit                    quit (abort) sending the message
+i       ispell                  check spelling (if available on your system)
+^F      forget-passphrase       whipe PGP passphrase from memory
 </verb></tscreen>
 
 <sect2>Editing the message header<label id="edit_headers">
@@ -536,7 +536,7 @@ An initialization file consists of a series of <ref id="commands"
 name="commands">.  Each line of the file may contain one or more commands.
 When multiple commands are used, they must be separated by a semicolon (;).
 <tscreen><verb>
-       set realname='Mutt user' ; ignore x-
+set realname='Mutt user' ; ignore x-
 </verb></tscreen>
 The hash mark, or pound sign
 (``&num;''), is used as a ``comment'' character. You can use it to
@@ -582,8 +582,15 @@ The output of the Unix command ``uname -a'' will be substituted before the
 line is parsed.  Note that since initialization files are line oriented, only
 the first line of output from the Unix command will be substituted.
 
-For a complete list of the commands understood by mutt, see the
-<ref id="commands" name="command reference">.
+UNIX environments can be accessed like the way it is done in shells like
+sh and bash: Prepend the name of the environment by a ``$dollar;''.  For
+example,
+<tscreen><verb>
+set record=+sent_on_$HOSTNAME
+</verb></tscreen>
+
+The commands understood by mutt are explained in the next paragraphs.
+For a complete list, see the <ref id="commands" name="command reference">.
 
 <sect1>Defining/Using aliases<label id="alias">
 <p>
@@ -664,7 +671,6 @@ defined maps are:
 <item>compose
 <item>pager
 <item>pgp
-<item>url
 </itemize>
 
 <em/key/ is the key (or key sequence) you wish to bind.  To specify a
@@ -679,24 +685,24 @@ equivalent to <em/&bsol;c?/).
 In addition, <em/key/ may consist of:
 
 <tscreen><verb>
-\t             tab
-\r             carriage return
-\n             newline
-\e             escape
-up             up arrow
-down           down arrow
-left           left arrow
-right          right arrow
-pageup         Page Up
-pagedown       Page Down
-backspace      Backspace
-delete         Delete
-insert         Insert
-enter          Enter
-home           Home
-end            End
-f1             function key 1
-f10            function key 10
+\t              tab
+\r              carriage return
+\n              newline
+\e              escape
+<up>            up arrow
+<down>          down arrow
+<left>          left arrow
+<right>         right arrow
+<pageup>        Page Up
+<pagedown>      Page Down
+<backspace>     Backspace
+<delete>        Delete
+<insert>        Insert
+<enter>         Enter
+<home>          Home
+<end>           End
+f1              function key 1
+f10             function key 10
 </verb></tscreen>
 
 <em/key/ does not need to be enclosed in quotes unless it contains a
@@ -709,7 +715,7 @@ sequence.
 
 <sect1>Setting variables based upon mailbox<label id="folder-hook">
 <p>
-Usage: <tt/folder-hook/ &lsqb;!&rsqb;<em/pattern/ <em/command/
+Usage: <tt/folder-hook/ &lsqb;!&rsqb;<em/regexp/ <em/command/
 
 It is often desirable to change settings based on which mailbox you are
 reading.  The folder-hook command provides a method by which you can execute
@@ -742,7 +748,7 @@ folder-hook . set sort=date-sent
 
 <sect1>Keyboard macros<label id="macro">
 <p>
-Usage: <tt/macro/ <em/menu/ <em/key/ <em/sequence/
+Usage: <tt/macro/ <em/menu/ <em/key/ <em/sequence/ &lsqb; <em/description/ &rsqb;
 
 Macros are useful when you would like a single key to perform a series of
 actions.  When you press <em/key/ in menu <em/menu/, Mutt will behave as if
@@ -755,6 +761,9 @@ id="bind" name="key bindings">, with the addition that control
 characters in <em/sequence/ can also be specified as <em/&circ;x/.  In
 order to get a caret (``&circ;'') you need to use <em/&circ;&circ;/.
 
+Optionally you can specify a descriptive text, which is shown in the
+help screens.
+
 <bf/Note:/ Macro definitions (if any) listed in the help screen(s), are
 silently truncated at the screen width, and are not wrapped.   
 
@@ -889,11 +898,11 @@ Mutt has a few nice features for <ref id="using_lists" name="handling mailing
 lists">.  In order to take advantage of them, you must specify which addresses
 belong to mailing lists.
 
-It is important to note that you should <bf/never/ specify the domain name (
-the part after the ``@'') with the lists command.  You should only
+It is important to note that you should <bf/never/ specify the domain name
+(the part after the ``@'') with the lists command.  You should only
 specify the ``mailbox'' portion of the address (the part before the ``@'').
 For example, if you've subscribed to the Mutt mailing list, you will receive
-mail addressed to <em/mutt-users@cs.hmc.edu/.  So, to tell Mutt that this is a
+mail addressed to <em/mutt-users@mutt.org/.  So, to tell Mutt that this is a
 mailing list, you would add ``lists mutt-users'' to your initialization file.
 
 The ``unlists'' command is to remove a token from the list of mailing-lists.
@@ -986,13 +995,17 @@ Usage: <tt/hdr&lowbar;order/ <em/header1/ <em/header2/ <em/header3/
 With this command, you can specify an order in which mutt will attempt
 to present headers to you when viewing messages.
 
+``unhdr_order *'' will clear all previous headers from the order list,
+thus removing the header order effects set by the system-wide startup
+file.
+
 <tscreen><verb>
 hdr&lowbar;order From Date: From: To: Cc: Subject:
 </verb></tscreen>
 
 <sect1>Specify default save filename<label id="save-hook">
 <p>
-Usage: <tt/save-hook/ &lsqb;!&rsqb;<em/regexp/ <em/filename/
+Usage: <tt/save-hook/ &lsqb;!&rsqb;<em/pattern/ <em/filename/
 
 This command is used to override the default filename used when saving
 messages.  <em/filename/ will be used as the default filename if the message is
@@ -1000,7 +1013,7 @@ messages.  <em/filename/ will be used as the default filename if the message is
 message is addressed <em/to:/ something matching <em/regexp/.
 
 See <ref id="pattern_hook" name="matching messages"> for information on the
-exact format of <em/regexp/.
+exact format of <em/pattern/.
 
 Examples:
 
@@ -1013,7 +1026,7 @@ Also see the <ref id="fcc-save-hook" name="fcc-save-hook"> command.
 
 <sect1>Specify default Fcc: mailbox when composing<label id="fcc-hook">
 <p>
-Usage: <tt/fcc-hook/ &lsqb;!&rsqb;<em/regexp/ <em/mailbox/
+Usage: <tt/fcc-hook/ &lsqb;!&rsqb;<em/pattern/ <em/mailbox/
 
 This command is used to save outgoing mail in a mailbox other than
 <ref id="record" name="&dollar;record">.  Mutt searches the initial list of
@@ -1022,7 +1035,7 @@ as the default Fcc: mailbox.  If no match is found the message will be saved
 to <ref id="record" name="&dollar;record"> mailbox.
 
 See <ref id="pattern_hook" name="matching messages"> for information on the
-exact format of <em/regexp/.
+exact format of <em/pattern/.
 
 Example: <tt/fcc-hook aol.com&dollar; +spammers/
 
@@ -1033,23 +1046,23 @@ name="fcc-save-hook"> command.
 <sect1>Specify default save filename and default Fcc: mailbox at once<label
 id="fcc-save-hook">
 <p>
-Usage: <tt/fcc-save-hook/ &lsqb;!&rsqb;<em/regexp/ <em/mailbox/
+Usage: <tt/fcc-save-hook/ &lsqb;!&rsqb;<em/pattern/ <em/mailbox/
 
 This command is a shortcut, equivalent to doing both a <ref id="fcc-hook" name="fcc-hook">
 and a <ref id="save-hook" name="save-hook"> with its arguments.
 
 <sect1>Change settings based upon message recipients<label id="send-hook">
 <p>
-Usage: <tt/send-hook/ &lsqb;!&rsqb;<em/regexp/ <em/command/
+Usage: <tt/send-hook/ &lsqb;!&rsqb;<em/pattern/ <em/command/
 
 This command can be used to execute arbitrary configuration commands based
-upon recipients of the message.  <em/regexp/ is a regular expression
+upon recipients of the message.  <em/pattern/ is a regular expression
 matching the desired address.  <em/command/ is executed when <em/regexp/
 matches recipients of the message.  When multiple matches occur, commands are
 executed in the order they are specified in the muttrc.
 
 See <ref id="pattern_hook" name="matching messages"> for information on the
-exact format of <em/regexp/.
+exact format of <em/pattern/.
 
 Example: <tt/send-hook mutt &dquot;set mime&lowbar;forward signature=''&dquot;/
 
@@ -1063,6 +1076,18 @@ signatures based upon the recipients.
 list of recipients.  Adding a recipient after replying or editing the
 message will NOT cause any send-hook to be executed.
 
+<sect1>Choosing the PGP key of the recipient<label id="pgp-hook">
+<p>
+Usage: <tt/pgp-hook/ <em/pattern/ <em/keyid/
+
+When encrypting messages with PGP, you may want to associate a certain
+PGP key with a given e-mail address automatically, either because the
+recipient's public key can't be deduced from the destination address,
+or because, for some reasons, you need to override the key Mutt would
+normally use.  The pgp-hook command provides a method by which you can
+specify the ID of the public key to be used when encrypting messages to
+a certain recipient.
+
 <sect1>Adding key sequences to the keyboard buffer<label id="push">
 <p>
 Usage: <tt/push/ <em/string/
@@ -1078,7 +1103,7 @@ Usage: <tt/unscore/ <em/pattern/ &lsqb; <em/pattern/ ... &rsqb;
 
 The <tt/score/ commands adds <em/value/ to a message's score if <em/pattern/
 matches it.  <em/pattern/ is a string in the format described in the <ref
-id="searching" name="searching"> section.  <em/value/ is a positive or
+id="pattern" name="patterns"> section.  <em/value/ is a positive or
 negative integer.  A message's final score is the sum total of all matching
 <tt/score/ entries.  However, you may optionally prefix <em/value/ with an
 equal sign (=) to cause evaluation to stop at a particular entry if there is
@@ -1159,25 +1184,23 @@ path of your home directory.
 
 If the filename ends with a vertical bar (|), then <em/filename/ is
 considered to be an executable program from which to read input (eg.
-<tt/source ~/bin/myscript|/.
+<tt/source ~/bin/myscript|/).
 
 <sect>Advanced Usage
 
-<sect1>Searching and Regular Expressions<label id="regex"> 
+<sect1>Regular Expressions<label id="regexp">
 <p>
-All text patterns for searching and matching in Mutt must be specified
-as regular expressions (regexp) in the ``POSIX extended'' syntax (which
+All string patterns in Mutt including those in more complex
+<ref id="pattern" name="patterns"> must be specified
+using regular expressions (regexp) in the ``POSIX extended'' syntax (which
 is more or less the syntax used by egrep and GNU awk).  For your
 convenience, we have included below a brief description of this syntax.
 
 The search is case sensitive if the pattern contains at least one upper
 case letter, and case insensitive otherwise. Note that ``&bsol;''
 must be quoted if used for a regular expression in an initialization
-command: ``&bsol;&bsol;''.  For more information, see the section on
-<ref id="searching" name="searching"> below.
+command: ``&bsol;&bsol;''.
 
-<sect2>Regular Expressions<label id="regexps">
-<p>
 A regular expression is a pattern that describes a set of strings.
 Regular expressions are constructed analogously to arithmetic
 expressions, by using various operators to combine smaller expressions.
@@ -1270,7 +1293,7 @@ of several repetition operators:
 <descrip>
 <tag/?/
 The preceding item is optional and matched at most once.
-<tag/&ast;/
+<tag/*/
 The preceding item will be matched zero or more times.
 <tag/+/
 The preceding item will be matched one or more times.
@@ -1322,48 +1345,54 @@ Matches the empty string at the end of a buffer.
 Please note however that these operators are not defined by POSIX, so
 they may or may not be available in stock libraries on various systems.
 
-<sect2>Searching<label id="searching">
+<sect1>Patterns<label id="pattern">
 <p>
 Many of Mutt's commands allow you to specify a pattern to match
 (limit, tag-pattern, delete-pattern, etc.).  There are several ways to select
 messages:
 
 <tscreen><verb>
-~A             all messages
-~b PATTERN     messages which contain PATTERN in the message body
-~c USER                messages carbon-copied to USER
-~C PATTERN     message is either to: or cc: PATTERN
-~D             deleted messages
-~d [MIN]-[MAX] messages with ``date-sent'' in a Date range
-~E             expired messages
-~e PATTERN     message which contains PATTERN in the ``Sender'' field
-~F             flagged messages
-~f USER                messages originating from USER
-~h PATTERN     messages which contain PATTERN in the message header
-~i ID          message which match ID in the ``Message-ID'' field
-~L PATTERN     message is either originated or received by PATTERN
-~l             message is addressed to a known mailing list
-~m [MIN]-[MAX] message in the range MIN to MAX
-~n [MIN]-[MAX]  messages with a score in the range MIN to MAX
-~N             new messages
-~O             old messages
-~p             message is addressed to you (consults $alternates)
-~P             message is from you (consults $alternates)
-~Q             messages which have been replied to
-~R             read messages
-~r [MIN]-[MAX] messages with ``date-received'' in a Date range
-~S             superseded messages
-~s SUBJECT     messages having SUBJECT in the ``Subject'' field.
-~T             tagged messages
-~t USER                messages addressed to USER
-~U             unread messages
-~x PATTERN     messages which contain PATTERN in the `References' field
+~A              all messages
+~b EXPR         messages which contain EXPR in the message body
+~B EXPR         messages which contain EXPR in the whole message
+~c USER         messages carbon-copied to USER
+~C EXPR         message is either to: or cc: EXPR
+~D              deleted messages
+~d [MIN]-[MAX]  messages with ``date-sent'' in a Date range
+~E              expired messages
+~e EXPR         message which contains EXPR in the ``Sender'' field
+~F              flagged messages
+~f USER         messages originating from USER
+~h EXPR         messages which contain EXPR in the message header
+~i ID           message which match ID in the ``Message-ID'' field
+~L EXPR         message is either originated or received by EXPR
+~l              message is addressed to a known mailing list
+~m [MIN]-[MAX]  message in the range MIN to MAX *)
+~n [MIN]-[MAX]  messages with a score in the range MIN to MAX *)
+~N              new messages
+~O              old messages
+~p              message is addressed to you (consults $alternates)
+~P              message is from you (consults $alternates)
+~Q              messages which have been replied to
+~R              read messages
+~r [MIN]-[MAX]  messages with ``date-received'' in a Date range
+~S              superseded messages
+~s SUBJECT      messages having SUBJECT in the ``Subject'' field.
+~T              tagged messages
+~t USER         messages addressed to USER
+~U              unread messages
+~x EXPR         messages which contain EXPR in the `References' field
+~z [MIN]-[MAX]  messages with a size in the range MIN to MAX *)
 </verb></tscreen>
 
-Where PATTERN, USER, ID, and SUBJECT are 
-<ref id="regex" name="regular expressions">.
+Where EXPR, USER, ID, and SUBJECT are 
+<ref id="regexp" name="regular expressions">.
+
+*) The forms <tt/&lt;&lsqb;MAX&rsqb;/, <tt/&gt;&lsqb;MIN&rsqb;/,
+<tt/&lsqb;MIN&rsqb;-/ and <tt/-&lsqb;MAX&rsqb;/
+are allowed, too.
 
-<sect2>Complex Searches
+<sect2>Complex Patterns
 <p>
 
 Logical AND is performed by specifying more than one criterion.  For
@@ -1423,10 +1452,10 @@ be specified as:
 <em/offset/ is specified as a positive number with one of the following
 units:
 <verb>
-y      years
-m      months
-w      weeks
-d      days
+y       years
+m       months
+w       weeks
+d       days
 </verb>
 
 Example: to select messages less than 1 month old, you would use
@@ -1449,8 +1478,8 @@ a mailing list to a separate folder, or to delete all messages with a given
 subject.  To tag all messages matching a pattern, use the tag-pattern
 function, which is bound to ``control-T'' by default.  Or you can select
 individual messages by hand using the ``tag-message'' function, which is
-bound to ``t'' by default.  See <ref id="searching" name="searching"> for
-Mutt's searching syntax.
+bound to ``t'' by default.  See <ref id="pattern" name="patterns"> for
+Mutt's pattern matching syntax.
 
 Once you have tagged the desired messages, you can use the
 ``tag-prefix'' operator, which is the ``;'' (semicolon) key by default.
@@ -1466,7 +1495,8 @@ A <em/hook/ is a concept borrowed from the EMACS editor which allows you to
 execute arbitrary commands before performing some operation.  For example,
 you may wish to tailor your configuration based upon which mailbox you are
 reading, or to whom you are sending mail.  In the Mutt world, a <em/hook/
-consists of a <ref id="regex" name="regular expression"> along with a
+consists of a <ref id="regexp" name="regular expression"> or
+<ref id="pattern" name="pattern"> along with a
 configuration option/command.  See
 <itemize>
 <item><ref id="folder-hook" name="folder-hook">
@@ -1482,11 +1512,11 @@ for specific details on each type of <em/hook/ available.
 <p>
 Hooks that act upon messages (<tt/send-hook, save-hook, fcc-hook/) are
 evaluated in a slightly different manner.  For the other types of hooks, a
-<ref id="regex" name="regular expression">.  But in dealing with messages a
-finer grain of control is needed for matching since for different purposes
-you want to match different criteria.
+<ref id="regexp" name="regular expression"> is sufficient.  But in dealing
+with messages a finer grain of control is needed for matching since for
+different purposes you want to match different criteria.
 
-Mutt allows the use of the <ref id="searching" name="search pattern">
+Mutt allows the use of the <ref id="pattern" name="search pattern">
 language for matching messages in hook commands.  This works in exactly the
 same way as it would when <em/limiting/ or <em/searching/ the mailbox,
 except that you are restricted to those operators which match information
@@ -1504,8 +1534,8 @@ However, it is not required that you write the pattern to match using the
 full searching language.  You can still specify a simple <em/regular
 expression/ like the other hooks, in which case Mutt will translate your
 pattern into the full language, using the translation specified by the 
-<ref id="default_hook" name="&dollar;dfault&lowbar;hook"> variable.  The pattern
-is translated at the time the hook is declared, so the value of 
+<ref id="default_hook" name="&dollar;default&lowbar;hook"> variable.  The
+pattern is translated at the time the hook is declared, so the value of 
 <ref id="default_hook" name="&dollar;dfault&lowbar;hook"> that is in effect
 at that time will be used.
 
@@ -1530,9 +1560,9 @@ addresses, return a non-zero exit code and a one line error message.
 An example multiple response output:
 <tscreen><verb>
 Searching database ... 20 entries ... 3 matching:
-me@cs.hmc.edu  Michael Elkins  mutt dude
-blong@fiction.net      Brandon Long    mutt and more
-roessler@guug.de       Thomas Roessler mutt pgp
+me@cs.hmc.edu           Michael Elkins  mutt dude
+blong@fiction.net       Brandon Long    mutt and more
+roessler@guug.de        Thomas Roessler mutt pgp
 </verb></tscreen>
 
 There are two mechanisms for accessing the query function of mutt.  One
@@ -1603,6 +1633,8 @@ path.
 <item>- -- refers to the file you've last visited
 <item>&tilde; -- refers to your home directory
 <item>= or + -- refers to your <ref id="folder" name="&dollar;folder"> directory
+<item>@<em/alias/ -- refers to the <ref id="save-hook" 
+name="default save folder"> as determined by the address of the alias
 </itemize>
 
 <sect1>Handling Mailing Lists<label id="using_lists">
@@ -1687,6 +1719,39 @@ and it's rather limited.  If you need more functionality you
 should consider using a specialized program, such as <htmlurl
 url="http://www.ccil.org/~esr/fetchmail" name="fetchmail">
 
+<sect1>IMAP Support (OPTIONAL)
+<p>
+
+If Mutt was compiled with IMAP support (by running the <em/configure/
+script with the <em/--enable-imap/ flag), it has the ability to work
+with folders located on a remote imap server.
+
+You can access the remote inbox by selecting the folder
+<tt/{imapserver}inbox/, where <tt/imapserver/ is the name of the IMAP
+server and <tt/inbox/ is the special name for your spool mailbox on
+the IMAP server. If you want to access another mail folder at the IMAP
+server, you should use <tt>{imapserver}path/to/folder</tt> where
+<tt>path/to/folder</tt> is the path of the folder you want to access
+relative to your home directory.
+
+<bf/Note:/ The IMAP support is in a very early state and quite
+unstable at the moment. If you need a more stable way to access your
+IMAP folder, consider using a specialized program, such as <htmlurl
+url="http://www.ccil.org/~esr/fetchmail" name="fetchmail">.
+
+<sect1>Start a WWW Browser on URLs (EXTERNAL)<label id="urlview">
+<p>
+If a message contains URLs (<em/unified ressource locator/ = address in the
+WWW space like <em>http://www.mutt.org/</em>), it is efficient to get
+a menu with all the URLs and start a WWW browser on one of them.  This
+functionality is provided by the external urlview program which can be
+retrieved at <htmlurl url="ftp://ftp.cs.hmc.edu/pub/me/"
+name="ftp://ftp.cs.hmc.edu/pub/me/"> and the configuration commands:
+<tscreen><verb>
+macro index \cb |urlview\n
+macro pager \cb |urlview\n
+</verb></tscreen>
+
 <sect>Mutt's MIME Support
 <p>
 Quite a bit of effort has been made to make Mutt the premier text-mode
@@ -1974,9 +2039,9 @@ attempting to print an <tt>image/gif</tt>, and you have the following
 entries in your mailcap file, Mutt will search for an entry with the
 print command:
 <tscreen><verb>
-image/*;       xv %s
-image/gif;     ; print= anytopnm %s | pnmtops | lpr; \
-               nametemplate=%s.gif
+image/*;        xv %s
+image/gif;      ; print= anytopnm %s | pnmtops | lpr; \
+                nametemplate=%s.gif
 </verb></tscreen>
 Mutt will skip the <tt>image/*</tt> entry and use the <tt>image/gif</tt>
 entry with the print command.
@@ -1987,9 +2052,9 @@ automatically, the other to be viewed interactively from the attachment
 menu.  In addition, you can then use the test feature to determine which
 viewer to use interactively depending on your environment.
 <tscreen><verb>
-text/html;     netscape -remote 'openURL(%s)' ; test=RunningX
-text/html;     lynx %s; nametemplate=%s.html
-text/html;     lynx -dump %s; nametemplate=%s.html; copiousoutput
+text/html;      netscape -remote 'openURL(%s)' ; test=RunningX
+text/html;      lynx %s; nametemplate=%s.html
+text/html;      lynx -dump %s; nametemplate=%s.html; copiousoutput
 </verb></tscreen>
 For <ref id="auto_view" name="Autoview">, Mutt will choose the third
 entry because of the copiousoutput tag.  For interactive viewing, Mutt
@@ -2027,7 +2092,7 @@ Content-Type: text/plain; charset=iso-8859-1
 then Mutt will expand &percnt;{charset} to iso-8859-1.  The default metamail
 mailcap file uses this feature to test the charset to spawn an xterm
 using the right charset to view the message.
-<tag>&setmn;&percnt;</tag>
+<tag>&bsol;&percnt;</tag>
 This will be replaced by a &percnt;
 </descrip>
 Mutt does not currently support the &percnt;F and &percnt;n keywords
@@ -2039,11 +2104,11 @@ multipart messages, which is handled internally by Mutt.
 This mailcap file is fairly simple and standard:
 <code>
 # I'm always running X :)
-video/*;       xanim %s > /dev/null
-image/*;       xv %s > /dev/null
+video/*;        xanim %s > /dev/null
+image/*;        xv %s > /dev/null
 
 # I'm always running netscape (if my computer had more memory, maybe)
-text/html;     netscape -remote 'openURL(%s)'
+text/html;      netscape -remote 'openURL(%s)'
 </code>
 
 This mailcap file shows quite a number of examples:
@@ -2051,27 +2116,27 @@ This mailcap file shows quite a number of examples:
 <code>
 # Use xanim to view all videos   Xanim produces a header on startup,
 # send that to /dev/null so I don't see it
-video/*;       xanim %s > /dev/null
+video/*;        xanim %s > /dev/null
 
 # Send html to a running netscape by remote
-text/html;     netscape -remote 'openURL(%s)'; test=RunningNetscape
+text/html;      netscape -remote 'openURL(%s)'; test=RunningNetscape
 
 # If I'm not running netscape but I am running X, start netscape on the
 # object
-text/html;     netscape %s; test=RunningX
+text/html;      netscape %s; test=RunningX
 
 # Else use lynx to view it as text
-text/html;     lynx %s
+text/html;      lynx %s
 
 # This version would convert the text/html to text/plain
-text/html;     lynx -dump %s; copiousoutput
+text/html;      lynx -dump %s; copiousoutput
 
 # enriched.sh converts text/enriched to text/html and then uses 
 # lynx -dump to convert it to text/plain
-text/enriched; enriched.sh ; copiousoutput
+text/enriched;  enriched.sh ; copiousoutput
 
 # I use enscript to print text in two columns to a page
-text/*;                more %s; print=enscript -2Gr %s
+text/*;         more %s; print=enscript -2Gr %s
 
 # Netscape adds a flag to tell itself to view jpegs internally
 image/jpeg;xv %s; x-mozilla-flags=internal
@@ -2080,7 +2145,7 @@ image/jpeg;xv %s; x-mozilla-flags=internal
 # In addition, this uses the \ to extend the line and set my editor
 # for images
 image/*;xv %s; test=RunningX; \
-       edit=xpaint %s
+        edit=xpaint %s
 
 # Convert images to text using the netpbm tools
 image/*;  (anytopnm %s | pnmscale -xysize 80 46 | ppmtopgm | pgmtopbm |
@@ -2119,6 +2184,7 @@ application/x-gunzip;   gzcat; copiousoutput
 application/x-tar-gz; gunzip -c %s | tar -tf - ; copiousoutput
 application/postscript; ps2ascii %s; copiousoutput
 </verb></tscreen>
+
 <sect1>MIME Multipart/Alternative<label id="alternative_order">
 <p>
 Mutt has some heuristics for determining which attachment of a
@@ -2144,24 +2210,24 @@ mailbox.  However, it is possible to read other mailboxes and
 to send messages from the command line as well.
 
 <tscreen><verb>
--a     attach a file to a message
--c     specify a carbon-copy (Cc) address
--e     specify a config command to be run after initilization files are read
--F     specify an alternate file to read initialization commands
--f     specify a mailbox to load
--h     print help on command line options
--H     specify a draft file from which to read a header and body
--i     specify a file to include in a message composition
--n     do not read the system Muttrc
--m     specify a default mailbox type
--p     recall a postponed message
--R     open mailbox in read-only mode
--s     specify a subject (enclose in quotes if it contains spaces)
--v     show version number and compile-time definitions
--x     simulate the mailx(1) compose mode
--y     show a menu containing the files specified by the mailboxes command
--z     exit immediately if there are no messages in the mailbox
--Z     open the first folder with new message,exit immediately if none
+-a      attach a file to a message
+-c      specify a carbon-copy (Cc) address
+-e      specify a config command to be run after initilization files are read
+-F      specify an alternate file to read initialization commands
+-f      specify a mailbox to load
+-h      print help on command line options
+-H      specify a draft file from which to read a header and body
+-i      specify a file to include in a message composition
+-n      do not read the system Muttrc
+-m      specify a default mailbox type
+-p      recall a postponed message
+-R      open mailbox in read-only mode
+-s      specify a subject (enclose in quotes if it contains spaces)
+-v      show version number and compile-time definitions
+-x      simulate the mailx(1) compose mode
+-y      show a menu containing the files specified by the mailboxes command
+-z      exit immediately if there are no messages in the mailbox
+-Z      open the first folder with new message,exit immediately if none
 </verb></tscreen>
 
 To read messages in a mailbox
@@ -2208,6 +2274,8 @@ The following are the commands understood by mutt.
 <item>
 <tt><ref id="hdr_order" name="hdr&lowbar;order"></tt> <em/header/ &lsqb; <em/header/ ... &rsqb;
 <item>
+<tt><ref id="hdr_order" name="unhdr&lowbar;order"></tt> <em/header/ &lsqb; <em/header/ ... &rsqb;
+<item>
 <tt><ref id="lists" name="lists"></tt> <em/address/ &lsqb; <em/address/ ... &rsqb; 
 <item>
 <tt><ref id="lists" name="unlists"></tt> <em/address/ &lsqb; <em/address/ ... &rsqb; 
@@ -2283,10 +2351,10 @@ Specifies the format of the data displayed for the `alias' menu.  The
 following printf(3)-style sequences are available.
 
 <verb>
-%a     alias name
-%n     index number
-%r     address which alias expands to
-%t     character which indicates if the alias is tagged for inclusion (*/ )
+%a      alias name
+%n      index number
+%r      address which alias expands to
+%t      character which indicates if the alias is tagged for inclusion (*/ )
 </verb>
 
 <sect2>allow&lowbar;8bit
@@ -2538,14 +2606,6 @@ Default: value of environment variable &dollar;VISUAL, &dollar;EDITOR, or &dquot
 
 This variable specifies which editor to use when composing messages.
 
-<sect2>empty&lowbar;to<label id="empty_to">
-<p>
-Type: string<newline>
-Default: undisclosed-recipients
-
-Specifies the text Mutt inserts in the <tt/To:/ header of a message you're
-sending, if the <tt/To:/ and <tt/Cc:/ fields are empty.
-
 <sect2>escape<label id="escape">
 <p>
 Type: string<newline>
@@ -2584,6 +2644,30 @@ Note that if you change this variable from the default value you need to
 make sure that the assignment occurs <em/before/ you use `+' or `=' for any
 other variables since expansion takes place during the `set' command.
 
+<sect2>folder&lowbar;format<label id="folder_format">
+<p>
+Type: format string<newline>
+Default: &dquot;&percnt;N &percnt;F &percnt;2l &percnt;-8.8u &percnt;-8.8g &percnt;8s &percnt;d &percnt;f&dquot;
+
+This variable allows you to customize the file browser display to 
+your personal taste.  This string is similar to <ref id="index_format"
+name="&dollar;index&lowbar;format">, but has its own set of printf()-like
+sequences:
+
+<tscreen><verb>
+%d      date/time folder was last modified
+%f      filename
+%F      file permissions
+%g      group name (or numeric gid, if missing)
+%l      number of hard links
+%N      N if folder has new mail, blank otherwise
+%s      size in bytes
+%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"
+</verb></tscreen>
+
 <sect2>followup&lowbar;to<label id="followup_to">
 <p>
 Type: boolean<newline>
@@ -2625,7 +2709,7 @@ used instead.
 <sect2>forward&lowbar;format<label id="forward_format">
 <p>
 Type: format string<newline>
-Default: "&lsqb;&percnt;a: &percnt;s&rsqb;"
+Default: &dquot;&lsqb;&percnt;a: &percnt;s&rsqb;&dquot
 
 This variable controls the default subject when forwarding a message.  It
 uses the same format sequences as the <ref id="index_format"
@@ -2640,61 +2724,6 @@ When <em/set/ forwarded messages included in the main body of the message
 (when <ref id="mime_forward" name="mime&lowbar;forward"> is <em/unset/) will be
 quoted using <ref id="indent_string" name="indent&lowbar;string">.
 
-<sect2>index&lowbar;format<label id="index_format">
-<p>
-Type: format string<newline>
-Default: &dquot;&percnt;4C &percnt;Z &percnt;{&percnt;b &percnt;d} &percnt;-15.15L (&percnt;4l) &percnt;s&dquot;
-
-This variable allows you to customize the message index display to your
-personal taste.
-
-``Format strings'' are similar to the strings used in the ``C'' function
-<tt/printf/ to format output (see the man page for more detail).  The
-following sequences are defined in Mutt:
-
-<tscreen><verb>
-%a     address of the author
-%b     filename of the original message folder (think mailBox)
-%B     the list to which the letter was sent, or else the folder name (%b).
-%c     number of characters (bytes) in the message
-%C     current message number
-%d     date and time of the message in the format specified by
-       ``date_format''
-%f     entire From: line (address + real name)
-%F     author name, or recipient name if the message is from you
-%i     message-id of the current message
-%l     number of lines in the message
-%L     list-from function
-%m     total number of message in the mailbox
-%N      message score
-%n     author's real name (or address if missing)
-%O      (_O_riginal save folder)  Where mutt would formerly have stashed the
-       message: list name or recipient name if no list
-%s     subject of the message
-%S     status of the message (N/D/d/!/*/r)
-%t     `to:' field (recipients)
-%T     the appropriate character from the $to_chars string
-%u     user (login) name of the author
-%Z     message status flags
-
-%{fmt} the date and time of the message is converted to sender's 
-       time zone, and ``fmt'' is expanded by the system call 
-       ``strftime''; a leading bang disables locales
-%[fmt] the date and time of the message is converted to the local
-       time zone, and ``fmt'' is expanded by the system call
-       ``strftime''; a leading bang disables locales
-%(fmt) the local date and time when the message was received.
-       ``fmt'' is expanded by the system call ``strftime'';
-       a leading bang disables locales
-%<fmt> the current local time. ``fmt'' is expanded by the system
-       call ``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"
-</verb></tscreen>
-
-See also: <ref id="to_chars" name="&dollar;to&lowbar;chars">.
-
 <sect2>hdrs<label id="hdrs">
 <p>
 Type: boolean<newline>
@@ -2727,6 +2756,17 @@ may not be updated if a binding is changed while Mutt is running.  Since
 this variable is primarily aimed at new users, neither of these should
 present a major problem.
 
+<sect2>hidden&lowbar;host<label id="hidden_host">
+<p>
+Type: boolean<newline>
+Default: unset
+
+When set, mutt will skip the host name part of <ref
+id="hostname" name="hostname"> variable when adding the
+domain part to addresses.  This variable does not affect
+the generation, and it will not lead to the cut-off of
+first-level domains.
+
 <sect2>history<label id="history">
 <p>
 Type: number<newline>
@@ -2758,6 +2798,32 @@ to the list, and will ignore this field.  To direct a response to the
 mailing list when this option is set, use the <em/list-reply/ function;
 <em/group-reply/ will reply to both the sender and the list.
 
+<sect2>imap&lowbar;checkinterval<label id="imap_checkinterval">
+<p>
+Type: number<newline>
+Default: 0
+
+This variable configures how often (in seconds) IMAP should look for
+new mail.
+
+<sect2>imap&lowbar;pass<label id="imap_pass">
+<p>
+Type: string<newline>
+Default: unset
+
+Specifies the password for your IMAP account.  If unset, Mutt will prompt you
+for your password when you invoke the fetch-mail function. <bf/Warning/:
+you should only use this option when you are on a fairly secure machine,
+because the superuser can read your muttrc even if you are the only one who
+can read the file.
+
+<sect2>imap&lowbar;user<label id="imap_user">
+<p>
+Type: string<newline>
+Default: login name on local system
+
+Your login name on the IMAP server.
+
 <sect2>in&lowbar;reply&lowbar;to
 <p>
 Type: format string<newline>
@@ -2779,12 +2845,67 @@ included in your reply.
 <sect2>indent&lowbar;string<label id="indent_string">
 <p>
 Type: format string<newline>
-Default: "&gt; "
+Default: &dquot;&gt; &dquot;
 
 Specifies the string to prepend to each line of text quoted in a message to
 which you are replying.  You are strongly encouraged not to change this
 value, as it tends to agitate the more fanatical netizens.
 
+<sect2>index&lowbar;format<label id="index_format">
+<p>
+Type: format string<newline>
+Default: &dquot;&percnt;4C &percnt;Z &percnt;{&percnt;b &percnt;d} &percnt;-15.15L (&percnt;4l) &percnt;s&dquot;
+
+This variable allows you to customize the message index display to your
+personal taste.
+
+``Format strings'' are similar to the strings used in the ``C'' function
+<tt/printf/ to format output (see the man page for more detail).  The
+following sequences are defined in Mutt:
+
+<tscreen><verb>
+%a      address of the author
+%b      filename of the original message folder (think mailBox)
+%B      the list to which the letter was sent, or else the folder name (%b).
+%c      number of characters (bytes) in the message
+%C      current message number
+%d      date and time of the message in the format specified by
+        ``date_format''
+%f      entire From: line (address + real name)
+%F      author name, or recipient name if the message is from you
+%i      message-id of the current message
+%l      number of lines in the message
+%L      list-from function
+%m      total number of message in the mailbox
+%N      message score
+%n      author's real name (or address if missing)
+%O       (_O_riginal save folder)  Where mutt would formerly have stashed the
+        message: list name or recipient name if no list
+%s      subject of the message
+%S      status of the message (N/D/d/!/*/r)
+%t      `to:' field (recipients)
+%T      the appropriate character from the $to_chars string
+%u      user (login) name of the author
+%Z      message status flags
+
+%{fmt}  the date and time of the message is converted to sender's 
+        time zone, and ``fmt'' is expanded by the system call 
+        ``strftime''; a leading bang disables locales
+%[fmt]  the date and time of the message is converted to the local
+        time zone, and ``fmt'' is expanded by the system call
+        ``strftime''; a leading bang disables locales
+%(fmt)  the local date and time when the message was received.
+        ``fmt'' is expanded by the system call ``strftime'';
+        a leading bang disables locales
+%<fmt>  the current local time. ``fmt'' is expanded by the system
+        call ``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"
+</verb></tscreen>
+
+See also: <ref id="to_chars" name="&dollar;to&lowbar;chars">.
+
 <sect2>ispell<label id="ispell">
 <p>
 Type: string<newline>
@@ -2808,9 +2929,17 @@ Default: &dollar;MAILCAPS or &tilde;/.mailcap:/usr/local/share/mailcap:/etc/mail
 This variable specifies which files to consult when attempting to display
 MIME bodies not directly supported by Mutt.
 
+<sect2>mail&lowbar;check<label id="mail_check">
+<p>
+Type: number<newline>
+Default: 5
+
+This variable configures how often (in seconds) mutt should look for
+new mail.
+
 <sect2>mark&lowbar;old
 <p>
-Type: Boolean<newline>
+Type: boolean<newline>
 Default: set
 
 Controls whether or not Mutt makes the distinction between <em/new/ messages
@@ -2832,10 +2961,15 @@ the <ref id="smart_wrap" name="&dollar;smart&lowbar;wrap"> variable.
 <sect2>mask<label id="mask">
 <p>
 Type: string<newline>
-Default: "^(&bsol;.&bsol;.&dollar;|&lsqb;^.&rsqb;)"
+Default: "!^&bsol;.&lsqb;^.&rsqb;"
+
+A regular expression used in the file browser, optionally preceded by
+the <em/not/ operator ``!''. Files whose names don't match this mask
+will not be shown. The match is always case-sensitive.
 
-A regular expression used in the file browser. Files whose names don't
-match this mask will not be shown.
+<bf/Note:/ if you need ``!'' at the beginning of the regular expression
+you should enclose it in paranthesis, in order to distinguish it from
+the logical <em/not/ operator for the expression.
 
 <sect2>mbox<label id="mbox">
 <p>
@@ -2875,7 +3009,7 @@ avoid many redraws).
 
 <sect2>meta&lowbar;key<label id="meta_key">
 <p>
-Type: Boolean<newline>
+Type: boolean<newline>
 Default: unset
 
 If set, forces Mutt to interpret keystrokes with the high bit (bit 8) set as
@@ -2887,13 +3021,14 @@ which is the ASCII character ``x''.
 
 <sect2>mime&lowbar;forward<label id="mime_forward">
 <p>
-Type: boolean<newline>
+Type: quadoption<newline>
 Default: unset
 
 When set, the message you are forwarding will be attached as a separate
 MIME part instead of included in the main body of the message.  This is
 useful for forwarding MIME messages so the receiver can properly view the
-message as it was delivered to you.
+message as it was delivered to you. If you like to switch between MIME
+and not MIME from mail to mail, set this variable to ask-no or ask-yes.
 
 Also see <ref id="forward_decode" name="forward&lowbar;decode"> and
 <ref id="mime_forward_decode"
@@ -2920,8 +3055,8 @@ result of a <ref id="mbox-hook" name="mbox-hook"> command.
 
 <sect2>message&lowbar;format<label id="message_format">
 <p>
-Type: string<newline>
-Default: &dquot&percnt;s&dquot;
+Type: format string<newline>
+Default: &dquot;&percnt;s&dquot;
 
 This is the string displayed in the <ref id="attach_menu"
 name="attachment"> menu for attachments of type <em>message/rfc822</em>.
@@ -3006,11 +3141,13 @@ when signing is not required or encryption is requested as well.
 <sect2>pgp&lowbar;default&lowbar;version<label id="pgp_default_version">
 <p>
 Type: string<newline>
-Default: pgp2 (or pgp5, if PGP 2.* is not installed)
+Default: pgp2 (or pgp5, if PGP 2.* is not installed, or gpg, if none
+of them is installed)
 
-Set this to pgp2 (PGP 2.*), or pgp5 (PGP 5.*) depending on the
-version, you are using primary. This variable is directly used, but it
-is the default for the variables <ref id="pgp_receive_version"
+Set this to pgp2 (PGP 2.*), pgp5 (PGP 5.*), or gpg (GNU privacy guard),
+depending on the version that you primarily use. This variable is
+not directly used, but it is the default for the variables <ref
+id="pgp_receive_version"
 name="&dollar;pgp&lowbar;receive&lowbar;version">, <ref
 id="pgp_send_version" name="&dollar;pgp&lowbar;send&lowbar;version">,
 and <ref id="pgp_key_version"
@@ -3023,18 +3160,26 @@ Default: set
 
 If set, the PGP <em/+encrypttoself/ flag is used when encrypting messages.
 
+<sect2>pgp&lowbar;gpg<label id="pgp_gpg">
+<p>
+Type: string<newline>
+Default: system dependent
+
+This variable allows you to override the compile time definition of
+where the gpg (GNU Privacy Guard) binary resides on your system.
+
 <sect2>pgp&lowbar;key&lowbar;version<label id="pgp_key_version">
 <p>
 Type: string<newline>
 Default: ``default''
 
-This variable determines, which PGP version used for key ring
+This variable determines which PGP version is used for key ring
 operations like extracting keys from messages and extracting keys from
 your keyring. If you set this to default, the default defined in <ref
 id="pgp_default_version"
 name="&dollar;pgp&lowbar;default&lowbar;version"> is used. Set this to
-pgp2 (PGP 2.*), or pgp5 (PGP 5.*) if you want a different PGP version
-for key operations.
+pgp2 (PGP 2.*), pgp5 (PGP 5.*), or gpg (GNU privacy guard) if you want
+to use a different PGP version for key operations.
 
 <sect2>pgp&lowbar;long&lowbar;ids<label id="pgp_long_ids">
 <p>
@@ -3048,12 +3193,12 @@ If set, use 64 bit PGP key IDs. Unset uses the normal 32 bit Key IDs.
 Type: string<newline>
 Default: ``default''
 
-This variable determines, which PGP version used for decrypting
+This variable determines which PGP version is used for decrypting
 messages and verifying signatures. If you set this to default, the
 default defined in <ref id="pgp_default_version"
 name="&dollar;pgp&lowbar;default&lowbar;version"> will be used. Set
-this to pgp2 (PGP 2.*), or pgp5 (PGP 5.*) if you want a different PGP
-version for receiving operations.
+this to pgp2 (PGP 2.*), pgp5 (PGP 5.*), or gpg (GNU privacy guard) if
+you want to use a different PGP version for receiving operations.
 
 <sect2>pgp&lowbar;replyencrypt<label id="pgp_replyencrypt">
 <p>
@@ -3077,12 +3222,12 @@ signed!
 Type: string<newline>
 Default: ``default''
 
-This variable determines, which PGP version used for composing new
+This variable determines which PGP version is used for composing new
 messages like encrypting and signing. If you set this to default, the
 default defined in <ref id="pgp_default_version"
 name="&dollar;pgp&lowbar;default&lowbar;version"> will be used. Set
-this to pgp2 (PGP 2.*), or pgp5 (PGP 5.*) if you want a different PGP
-version for sending operations.
+this to pgp2 (PGP 2.*), pgp5 (PGP 5.*), or gpg (GNU privacy guard) if
+you want to use a different PGP version for sending operations.
 
 <sect2>pgp&lowbar;sign&lowbar;as<label id="pgp_sign_as">
 <p>
@@ -3247,7 +3392,7 @@ The name or address of your POP3 server.
 Type: string<newline>
 Default: unset
 
-Specifies the password for you POP account.  If unset, Mutt will prompt you
+Specifies the password for your POP account.  If unset, Mutt will prompt you
 for your password when you invoke the fetch-mail function. <bf/Warning/:
 you should only use this option when you are on a fairly secure machine,
 because the superuser can read your muttrc even if you are the only one who
@@ -3517,8 +3662,8 @@ Type: string<newline>
 Default: /usr/lib/sendmail -oi -oem
 
 Specifies the program and arguments used to deliver mail sent by Mutt.
-Mutt expects that the specified program will read the message header for
-recipients.
+Mutt expects that the specified program interprets
+additional arguments as recipient addresses.
 
 <sect2>sendmail&lowbar;wait<label id="sendmail_wait">
 <p>
@@ -3531,9 +3676,9 @@ the background.
 
 Mutt interprets the value of this variable as follows:
 <verb>
->0     number of seconds to wait for sendmail to finish before continuing
-0      wait forever for sendmail to finish
-<0     always put sendmail in the background without waiting
+>0      number of seconds to wait for sendmail to finish before continuing
+0       wait forever for sendmail to finish
+<0      always put sendmail in the background without waiting
 </verb>
 
 Note that if you specify a value other than 0, the output of the child
@@ -3575,7 +3720,7 @@ Default: &dquot;&tilde;f &percnt;s | &tilde;s &percnt;s&dquot;
 
 Specifies how Mutt should expand a simple search into a real search pattern.
 A simple search is one that does not contain any of the <tt/&tilde;/
-operators.  See <ref id="searching" name="searching"> for more information
+operators.  See <ref id="pattern" name="patterns"> for more information
 on search patterns.
  
 For example, if you simply type <tt/joe/ at a search or limit prompt, Mutt
@@ -3623,9 +3768,9 @@ Default: alias
 Specifies how the entries in the `alias' menu are sorted.  The following are
 legal values:
 <verb>
-alias          sort alphabetically by alias name
-address                sort alphabetically by email address
-unsorted       leave in order specified in .muttrc
+alias           sort alphabetically by alias name
+address         sort alphabetically by email address
+unsorted        leave in order specified in .muttrc
 </verb>
 
 <sect2>sort&lowbar;aux<label id="sort_aux">
@@ -3710,29 +3855,29 @@ name="&dollar;index&lowbar;format">, but has its own set of printf()-like
 sequences:
 
 <tscreen><verb>
-%b     number of mailboxes with new mail *
-%d     number of deleted messages *
-%h     local hostname
-%f     the full pathname of the current mailbox
-%F     number of flagged messages *
-%l     size (in bytes) of the current mailbox *
-%L     size (in bytes) of the messages shown (i.e., which match the current limit) *
-%m     the number of messages in the mailbox *
-%M     the number of messages shown (i.e., which match the current limit) *
-%n     number of new messages in the mailbox *
-%o     number of old unread messages
-%p     number of postponed messages *
-%P     percentage of the way through the index
-%r     modified/read-only/won't-write indicator, according to $status_chars
-%s     current sorting mode ($sort)
-%S     current aux sorting method ($sort_aux)
-%t     number of tagged messages *
-%u     number of unread messages *
-%v     Mutt version string
-%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"
+%b      number of mailboxes with new mail *
+%d      number of deleted messages *
+%h      local hostname
+%f      the full pathname of the current mailbox
+%F      number of flagged messages *
+%l      size (in bytes) of the current mailbox *
+%L      size (in bytes) of the messages shown (i.e., which match the current limit) *
+%m      the number of messages in the mailbox *
+%M      the number of messages shown (i.e., which match the current limit) *
+%n      number of new messages in the mailbox *
+%o      number of old unread messages
+%p      number of postponed messages *
+%P      percentage of the way through the index
+%r      modified/read-only/won't-write indicator, according to $status_chars
+%s      current sorting mode ($sort)
+%S      current aux sorting method ($sort_aux)
+%t      number of tagged messages *
+%u      number of unread messages *
+%v      Mutt version string
+%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"
 
 * = can be optionally printed if nonzero
 </verb></tscreen>
@@ -3744,7 +3889,7 @@ meaningful.  To optionally print a string based upon one of the above
 sequences, the following construct is used
 
 <tscreen><verb>
-       %?<sequence_char>?<optional_string>?
+        %?<sequence_char>?<optional_string>?
 </verb></tscreen>
 
 where <em/sequence&lowbar;char/ is a character from the table above, and
@@ -3757,7 +3902,15 @@ Here is an example illustrating how to optionally print the number of new
 messages in a mailbox:
 
 <tscreen><verb>
-       %?n?%n new messages.?
+        %?n?%n new messages.?
+</verb></tscreen>
+
+Additionally you can switch between two strings, the first one, if a
+value is zero, the second one, if the value is nonzero, by using the
+following construct:
+
+<tscreen><verb>
+        %?<sequence_char>?<if_string>&<else_string>?
 </verb></tscreen>
 
 <sect2>status&lowbar;on&lowbar;top<label id="status_on_top">
@@ -3797,7 +3950,7 @@ Type: boolean<newline>
 Default: unset
 
 Affects the <em/&tilde;b/ and <em/&tilde;h/ search operations described
-in section <ref id="searching" name="Searching"> above.  If set, the
+in section <ref id="pattern" name="patterns"> above.  If set, the
 headers and attachments of messages to be searched are decoded before
 searching.  If unset, messages are searched as they appear in the
 folder.
@@ -3944,6 +4097,15 @@ a single message will be displayed before writing a mailbox.
 
 Also see the <ref id="read_inc" name="&dollar;read&lowbar;inc"> variable.
 
+<sect2>write&lowbar;bcc<label id="write_bcc">
+<p>
+Type: boolean<newline>
+Default: set
+
+Controls whether mutt writes out the Bcc header when
+preparing messages to be sent.  Exim users may wish to use
+this.
+
 <sect1>Functions<label id="functions">
 <p>
 The following is the list of available functions listed by the mapping
@@ -4119,7 +4281,7 @@ search-reverse         ESC /   search backwards for a regular expression
 search-toggle              \   toggle search pattern coloring
 shell-escape               !   invoke a command in a subshell
 show-version               V   show the Mutt version number and date
-skip-quoted                S   skip beyond quoted text         
+skip-quoted                S   skip beyond quoted text
 tag-message                t   tag a message
 toggle-quoted              T   toggle display of quoted text
 top                        ^   jump to the top of the message
@@ -4253,7 +4415,7 @@ quote-char                ^V   quote the next typed key
 
 <sect1>Acknowledgements
 <p>
-Kari Hurrta
+Kari Hurtta
 <htmlurl url="mailto:kari.hurtta@fmi.fi" name="&lt;kari.hurtta@fmi.fi&gt;">
 co-developed the original MIME parsing code back in the ELM-ME days.
 
index 9dfa57e2f301d14f3916c257a9955145e00aa36c..04d985a99228a3afeee92b0b50db56cb18a02b32 100644 (file)
@@ -1,6 +1,6 @@
   The Mutt E-Mail Client
   by Michael Elkins <me@cs.hmc.edu>
-  v0.92.2, 23 April 1998
+  v0.94.2, 31 July 1998
 
   ``All mail clients suck.  This one just sucks less.'' -me, circa 1995
 
 
   1\b1.\b.1\b1.\b.  M\bMu\but\btt\bt H\bHo\bom\bme\be P\bPa\bag\bge\be
 
-  http://www.cs.hmc.edu/~me/mutt/index.html
+  http://www.mutt.org/
 
 
   1\b1.\b.2\b2.\b.  M\bMa\bai\bil\bli\bin\bng\bg L\bLi\bis\bst\bts\bs
 
   To subscribe to one of the following mailing lists, send a message
-  with the word _\bs_\bu_\bb_\bs_\bc_\br_\bi_\bb_\be in the subject to list-name_\b-
-  _\br_\be_\bq_\bu_\be_\bs_\bt@cs.hmc.edu.
+  with the word _\bs_\bu_\bb_\bs_\bc_\br_\bi_\bb_\be in the subject to list-name_\b-_\br_\be_\bq_\bu_\be_\bs_\bt@mutt.org.
 
 
-  +\bo  mutt-announce@cs.hmc.edu -- low traffic list for announcements
+  +\bo  mutt-announce@mutt.org -- low traffic list for announcements
 
-  +\bo  mutt-users@cs.hmc.edu -- help, bug reports and feature requests
+  +\bo  mutt-users@mutt.org -- help, bug reports and feature requests
 
-  +\bo  mutt-dev@cs.hmc.edu -- development mailing list
+  +\bo  mutt-dev@mutt.org -- development mailing list
 
   N\bNo\bot\bte\be:\b: all messages posted to _\bm_\bu_\bt_\bt_\b-_\ba_\bn_\bn_\bo_\bu_\bn_\bc_\be are automatically forwarded
   to _\bm_\bu_\bt_\bt_\b-_\bu_\bs_\be_\br_\bs, so you do not need to be subscribed to both lists.
@@ -38,7 +37,7 @@
   1\b1.\b.3\b3.\b.  S\bSo\bof\bft\btw\bwa\bar\bre\be D\bDi\bis\bst\btr\bri\bib\bbu\but\bti\bio\bon\bn S\bSi\bit\bte\bes\bs
 
 
-  +\bo  ftp://ftp.cs.hmc.edu/pub/me/mutt/
+  +\bo  ftp://ftp.guug.de/pub/mutt/
 
 
   1\b1.\b.4\b4.\b.  I\bIR\bRC\bC
@@ -65,7 +64,6 @@
   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.
 
 
 
+
+
   ^A or <Home>    bol             move to the start of the line
   ^B or <Left>    backward-char   move back one char
   ^D or <Delete>  delete-char     delete the char under the cursor
        n               display the next message
        ?               show keybindings
        /               search for a regular expression (pattern)
-       \              toggle search pattern coloring
+       \               toggle search pattern coloring
 
 
 
   commands are used, they must be separated by a semicolon (;).
 
 
-               set realname='Mutt user' ; ignore x-
+       set realname='Mutt user' ; ignore x-
 
 
 
   oriented, only the first line of output from the Unix command will be
   substituted.
 
-  For a complete list of the commands understood by mutt, see the
-  ``command reference''.
+  UNIX environments can be accessed like the way it is done in shells
+  like sh and bash: Prepend the name of the environment by a
+  ``$dollar;''.  For example,
+
+
+       set record=+sent_on_$HOSTNAME
+
+
+
+
+  The commands understood by mutt are explained in the next paragraphs.
+  For a complete list, see the ``command reference''.
 
 
   3\b3.\b.2\b2.\b.  D\bDe\bef\bfi\bin\bni\bin\bng\bg/\b/U\bUs\bsi\bin\bng\bg a\bal\bli\bia\bas\bse\bes\bs
   that Mutt will happily append aliases to any file, but in order for
   the new aliases to take effect you need to explicitly ``source'' this
   file too.
-
   For example:
 
 
        set alias_file=~/.mail_aliases
 
 
+
+
   To use aliases, you merely use the alias at any place in mutt where
   mutt prompts for addresses, such as the _\bT_\bo_\b: or _\bC_\bc_\b: prompt.  You can
   also enter aliases in your editor at the appropriate headers if you
 
   +\bo  pgp
 
-  +\bo  url
-
   _\bk_\be_\by is the key (or key sequence) you wish to bind.  To specify a
   control character, use the sequence _\b\_\bC_\bx, where _\bx is the letter of the
   control character (for example, to specify control-A use ``\Ca'').
   key as a three digit octal number prefixed with a ``\'' (for example
   _\b\_\b1_\b7_\b7 is equivalent to _\b\_\bc_\b?).
 
-  In addition, _\bk_\be_\by may consist of:
-
-
-
-
-
 
+  In addition, _\bk_\be_\by may consist of:
 
 
 
-  \t             tab
-  \r             carriage return
-  \n             newline
-  \e             escape
-  up              up arrow
-  down            down arrow
-  left            left arrow
-  right           right arrow
-  pageup          Page Up
-  pagedown        Page Down
-  backspace       Backspace
-  delete          Delete
-  insert          Insert
-  enter           Enter
-  home            Home
-  end             End
-  f1              function key 1
-  f10             function key 10
+       \t              tab
+       \r              carriage return
+       \n              newline
+       \e              escape
+       <up>            up arrow
+       <down>          down arrow
+       <left>          left arrow
+       <right>         right arrow
+       <pageup>        Page Up
+       <pagedown>      Page Down
+       <backspace>     Backspace
+       <delete>        Delete
+       <insert>        Insert
+       <enter>         Enter
+       <home>          Home
+       <end>           End
+       f1              function key 1
+       f10             function key 10
 
 
 
 
   3\b3.\b.4\b4.\b.  S\bSe\bet\btt\bti\bin\bng\bg v\bva\bar\bri\bia\bab\bbl\ble\bes\bs b\bba\bas\bse\bed\bd u\bup\bpo\bon\bn m\bma\bai\bil\blb\bbo\box\bx
 
-  Usage: folder-hook [!]_\bp_\ba_\bt_\bt_\be_\br_\bn _\bc_\bo_\bm_\bm_\ba_\bn_\bd
+  Usage: folder-hook [!]_\br_\be_\bg_\be_\bx_\bp _\bc_\bo_\bm_\bm_\ba_\bn_\bd
 
   It is often desirable to change settings based on which mailbox you
   are reading.  The folder-hook command provides a method by which you
   pattern ``.'':
 
 
+       folder-hook . set sort=date-sent
+
+
 
 
-       folder-hook . set sort=date-sent
 
   3\b3.\b.5\b5.\b.  K\bKe\bey\byb\bbo\boa\bar\brd\bd m\bma\bac\bcr\bro\bos\bs
 
-  Usage: macro _\bm_\be_\bn_\bu _\bk_\be_\by _\bs_\be_\bq_\bu_\be_\bn_\bc_\be
+  Usage: macro _\bm_\be_\bn_\bu _\bk_\be_\by _\bs_\be_\bq_\bu_\be_\bn_\bc_\be [ _\bd_\be_\bs_\bc_\br_\bi_\bp_\bt_\bi_\bo_\bn ]
 
   Macros are useful when you would like a single key to perform a series
   of actions.  When you press _\bk_\be_\by in menu _\bm_\be_\bn_\bu, Mutt will behave as if
   also be specified as _\b^_\bx.  In order to get a caret (``^'') you need to
   use _\b^_\b^.
 
+  Optionally you can specify a descriptive text, which is shown in the
+  help screens.
+
   N\bNo\bot\bte\be:\b: Macro definitions (if any) listed in the help screen(s), are
   silently truncated at the screen width, and are not wrapped.
 
 
   +\bo  message (informational messages)
 
+
   +\bo  normal
 
   +\bo  quoted (text matching ``$quote_regexp'' in the body of a message)
 
   If your terminal does not support color, it is still possible change
   the video attributes through the use of the ``mono'' command:
+
   Usage: mono _\b<_\bo_\bb_\bj_\be_\bc_\bt_\b> _\b<_\ba_\bt_\bt_\br_\bi_\bb_\bu_\bt_\be_\b> [ _\br_\be_\bg_\be_\bx_\bp ]
 
   where _\ba_\bt_\bt_\br_\bi_\bb_\bu_\bt_\be is one of the following:
   mailing lists.
 
   It is important to note that you should n\bne\bev\bve\ber\br specify the domain name
-  ( the part after the ``@'') with the lists command.  You should only
+  (the part after the ``@'') with the lists command.  You should only
   specify the ``mailbox'' portion of the address (the part before the
   ``@'').  For example, if you've subscribed to the Mutt mailing list,
-  you will receive mail addressed to _\bm_\bu_\bt_\bt_\b-_\bu_\bs_\be_\br_\bs_\b@_\bc_\bs_\b._\bh_\bm_\bc_\b._\be_\bd_\bu.  So, to tell
+  you will receive mail addressed to _\bm_\bu_\bt_\bt_\b-_\bu_\bs_\be_\br_\bs_\b@_\bm_\bu_\bt_\bt_\b._\bo_\br_\bg.  So, to tell
   Mutt that this is a mailing list, you would add ``lists mutt-users''
   to your initialization file.
 
-
   The ``unlists'' command is to remove a token from the list of mailing-
   lists.  Use ``unlists *'' to remove all tokens.
 
 
   The ``my_hdr'' command allows you to create your own header fields
   which will be added to every message you send.
-
   For example, if you would like to add an ``Organization:'' header
   field to all of your outgoing messages, you can put the command
 
   With this command, you can specify an order in which mutt will attempt
   to present headers to you when viewing messages.
 
+  ``unhdr_order *'' will clear all previous headers from the order list,
+  thus removing the header order effects set by the system-wide startup
+  file.
+
 
 
        hdr_order From Date: From: To: Cc: Subject:
 
   3\b3.\b.1\b13\b3.\b.  S\bSp\bpe\bec\bci\bif\bfy\by d\bde\bef\bfa\bau\bul\blt\bt s\bsa\bav\bve\be f\bfi\bil\ble\ben\bna\bam\bme\be
 
-  Usage: save-hook [!]_\br_\be_\bg_\be_\bx_\bp _\bf_\bi_\bl_\be_\bn_\ba_\bm_\be
+  Usage: save-hook [!]_\bp_\ba_\bt_\bt_\be_\br_\bn _\bf_\bi_\bl_\be_\bn_\ba_\bm_\be
 
   This command is used to override the default filename used when saving
   messages.  _\bf_\bi_\bl_\be_\bn_\ba_\bm_\be will be used as the default filename if the
   and the message is addressed _\bt_\bo_\b: something matching _\br_\be_\bg_\be_\bx_\bp.
 
   See ``matching messages'' for information on the exact format of
-  _\br_\be_\bg_\be_\bx_\bp.
+  _\bp_\ba_\bt_\bt_\be_\br_\bn.
 
   Examples:
 
        save-hook me@(turing\\.)?cs\\.hmc\\.edu$ +elkins
        save-hook aol\\.com$ +spam
 
-
-
-
   Also see the ``fcc-save-hook'' command.
 
 
   3\b3.\b.1\b14\b4.\b.  S\bSp\bpe\bec\bci\bif\bfy\by d\bde\bef\bfa\bau\bul\blt\bt F\bFc\bcc\bc:\b: m\bma\bai\bil\blb\bbo\box\bx w\bwh\bhe\ben\bn c\bco\bom\bmp\bpo\bos\bsi\bin\bng\bg
 
-  Usage: fcc-hook [!]_\br_\be_\bg_\be_\bx_\bp _\bm_\ba_\bi_\bl_\bb_\bo_\bx
+  Usage: fcc-hook [!]_\bp_\ba_\bt_\bt_\be_\br_\bn _\bm_\ba_\bi_\bl_\bb_\bo_\bx
 
   This command is used to save outgoing mail in a mailbox other than
   ``$record''.  Mutt searches the initial list of message recipients for
   ``$record'' mailbox.
 
   See ``matching messages'' for information on the exact format of
-  _\br_\be_\bg_\be_\bx_\bp.
+  _\bp_\ba_\bt_\bt_\be_\br_\bn.
 
   Example: fcc-hook aol.com$ +spammers
 
 
   3\b3.\b.1\b15\b5.\b.  S\bSp\bpe\bec\bci\bif\bfy\by d\bde\bef\bfa\bau\bul\blt\bt s\bsa\bav\bve\be f\bfi\bil\ble\ben\bna\bam\bme\be a\ban\bnd\bd d\bde\bef\bfa\bau\bul\blt\bt F\bFc\bcc\bc:\b: m\bma\bai\bil\blb\bbo\box\bx a\bat\bt o\bon\bnc\bce\be
 
-  Usage: fcc-save-hook [!]_\br_\be_\bg_\be_\bx_\bp _\bm_\ba_\bi_\bl_\bb_\bo_\bx
+  Usage: fcc-save-hook [!]_\bp_\ba_\bt_\bt_\be_\br_\bn _\bm_\ba_\bi_\bl_\bb_\bo_\bx
 
   This command is a shortcut, equivalent to doing both a ``fcc-hook''
   and a ``save-hook'' with its arguments.
 
   3\b3.\b.1\b16\b6.\b.  C\bCh\bha\ban\bng\bge\be s\bse\bet\btt\bti\bin\bng\bgs\bs b\bba\bas\bse\bed\bd u\bup\bpo\bon\bn m\bme\bes\bss\bsa\bag\bge\be r\bre\bec\bci\bip\bpi\bie\ben\bnt\bts\bs
 
-  Usage: send-hook [!]_\br_\be_\bg_\be_\bx_\bp _\bc_\bo_\bm_\bm_\ba_\bn_\bd
+  Usage: send-hook [!]_\bp_\ba_\bt_\bt_\be_\br_\bn _\bc_\bo_\bm_\bm_\ba_\bn_\bd
 
   This command can be used to execute arbitrary configuration commands
-  based upon recipients of the message.  _\br_\be_\bg_\be_\bx_\bp is a regular expression
+  based upon recipients of the message.  _\bp_\ba_\bt_\bt_\be_\br_\bn is a regular expression
   matching the desired address.  _\bc_\bo_\bm_\bm_\ba_\bn_\bd is executed when _\br_\be_\bg_\be_\bx_\bp matches
   recipients of the message.  When multiple matches occur, commands are
   executed in the order they are specified in the muttrc.
 
   See ``matching messages'' for information on the exact format of
-  _\br_\be_\bg_\be_\bx_\bp.
+  _\bp_\ba_\bt_\bt_\be_\br_\bn.
 
   Example: send-hook mutt "set mime_forward signature=''"
 
   message will NOT cause any send-hook to be executed.
 
 
-  3\b3.\b.1\b17\b7.\b.  A\bAd\bdd\bdi\bin\bng\bg k\bke\bey\by s\bse\beq\bqu\bue\ben\bnc\bce\bes\bs t\bto\bo t\bth\bhe\be k\bke\bey\byb\bbo\boa\bar\brd\bd b\bbu\buf\bff\bfe\ber\br
+  3\b3.\b.1\b17\b7.\b.  C\bCh\bho\boo\bos\bsi\bin\bng\bg t\bth\bhe\be P\bPG\bGP\bP k\bke\bey\by o\bof\bf t\bth\bhe\be r\bre\bec\bci\bip\bpi\bie\ben\bnt\bt
+
+  Usage: pgp-hook _\bp_\ba_\bt_\bt_\be_\br_\bn _\bk_\be_\by_\bi_\bd
+
+  When encrypting messages with PGP, you may want to associate a certain
+  PGP key with a given e-mail address automatically, either because the
+  recipient's public key can't be deduced from the destination address,
+  or because, for some reasons, you need to override the key Mutt would
+  normally use.  The pgp-hook command provides a method by which you can
+  specify the ID of the public key to be used when encrypting messages
+  to a certain recipient.
+
+
+  3\b3.\b.1\b18\b8.\b.  A\bAd\bdd\bdi\bin\bng\bg k\bke\bey\by s\bse\beq\bqu\bue\ben\bnc\bce\bes\bs t\bto\bo t\bth\bhe\be k\bke\bey\byb\bbo\boa\bar\brd\bd b\bbu\buf\bff\bfe\ber\br
 
   Usage: push _\bs_\bt_\br_\bi_\bn_\bg
 
   entering certain folders.
 
 
-  3\b3.\b.1\b18\b8.\b.  M\bMe\bes\bss\bsa\bag\bge\be S\bSc\bco\bor\bri\bin\bng\bg
+  3\b3.\b.1\b19\b9.\b.  M\bMe\bes\bss\bsa\bag\bge\be S\bSc\bco\bor\bri\bin\bng\bg
 
   Usage: score _\bp_\ba_\bt_\bt_\be_\br_\bn _\bv_\ba_\bl_\bu_\be
   Usage: unscore _\bp_\ba_\bt_\bt_\be_\br_\bn [ _\bp_\ba_\bt_\bt_\be_\br_\bn ... ]
 
   The score commands adds _\bv_\ba_\bl_\bu_\be to a message's score if _\bp_\ba_\bt_\bt_\be_\br_\bn matches
-  it.  _\bp_\ba_\bt_\bt_\be_\br_\bn is a string in the format described in the ``searching''
+  it.  _\bp_\ba_\bt_\bt_\be_\br_\bn is a string in the format described in the ``patterns''
   section.  _\bv_\ba_\bl_\bu_\be is a positive or negative integer.  A message's final
   score is the sum total of all matching score entries.  However, you
   may optionally prefix _\bv_\ba_\bl_\bu_\be with an equal sign (=) to cause evaluation
   the list of all score entries.
 
 
-  3\b3.\b.1\b19\b9.\b.  S\bSe\bet\btt\bti\bin\bng\bg v\bva\bar\bri\bia\bab\bbl\ble\bes\bs
+  3\b3.\b.2\b20\b0.\b.  S\bSe\bet\btt\bti\bin\bng\bg v\bva\bar\bri\bia\bab\bbl\ble\bes\bs
 
   Usage: set [no|inv]_\bv_\ba_\br_\bi_\ba_\bb_\bl_\be[=_\bv_\ba_\bl_\bu_\be] [ _\bv_\ba_\br_\bi_\ba_\bb_\bl_\be ... ]
   Usage: toggle _\bv_\ba_\br_\bi_\ba_\bb_\bl_\be [_\bv_\ba_\br_\bi_\ba_\bb_\bl_\be ... ]
 
   With the reset command there exists the special variable ``all'',
   which allows you to reset all variables to their system defaults.
-  3\b3.\b.2\b20\b0.\b.  R\bRe\bea\bad\bdi\bin\bng\bg i\bin\bni\bit\bti\bia\bal\bli\biz\bza\bat\bti\bio\bon\bn c\bco\bom\bmm\bma\ban\bnd\bds\bs f\bfr\bro\bom\bm a\ban\bno\bot\bth\bhe\ber\br f\bfi\bil\ble\be
+
+
+  3\b3.\b.2\b21\b1.\b.  R\bRe\bea\bad\bdi\bin\bng\bg i\bin\bni\bit\bti\bia\bal\bli\biz\bza\bat\bti\bio\bon\bn c\bco\bom\bmm\bma\ban\bnd\bds\bs f\bfr\bro\bom\bm a\ban\bno\bot\bth\bhe\ber\br f\bfi\bil\ble\be
 
   Usage: source _\bf_\bi_\bl_\be_\bn_\ba_\bm_\be
 
 
   If the filename ends with a vertical bar (|), then _\bf_\bi_\bl_\be_\bn_\ba_\bm_\be is
   considered to be an executable program from which to read input (eg.
-  source ~bin/myscript|/.
+  source ~bin/myscript|/).
 
 
   4\b4.\b.  A\bAd\bdv\bva\ban\bnc\bce\bed\bd U\bUs\bsa\bag\bge\be
 
-  4\b4.\b.1\b1.\b.  S\bSe\bea\bar\brc\bch\bhi\bin\bng\bg a\ban\bnd\bR\bRe\beg\bgu\bul\bla\bar\br E\bEx\bxp\bpr\bre\bes\bss\bsi\bio\bon\bns\bs
+  4\b4.\b.1\b1.\b.  R\bRe\beg\bgu\bul\bla\bar\br E\bEx\bxp\bpr\bre\bes\bss\bsi\bio\bon\bns\bs
 
-  All text patterns for searching and matching in Mutt must be specified
-  as regular expressions (regexp) in the ``POSIX extended'' syntax
-  (which is more or less the syntax used by egrep and GNU awk).  For
-  your convenience, we have included below a brief description of this
-  syntax.
+  All string patterns in Mutt including those in more complex
+  ``patterns'' must be specified using regular expressions (regexp) in
+  the ``POSIX extended'' syntax (which is more or less the syntax used
+  by egrep and GNU awk).  For your convenience, we have included below a
+  brief description of this syntax.
 
   The search is case sensitive if the pattern contains at least one
   upper case letter, and case insensitive otherwise. Note that ``\''
   must be quoted if used for a regular expression in an initialization
-  command: ``\\''.  For more information, see the section on
-  ``searching'' below.
-
-
-  4\b4.\b.1\b1.\b.1\b1.\b.  R\bRe\beg\bgu\bul\bla\bar\br E\bEx\bxp\bpr\bre\bes\bss\bsi\bio\bon\bns\bs
+  command: ``\\''.
 
   A regular expression is a pattern that describes a set of strings.
   Regular expressions are constructed analogously to arithmetic
   consist of ``[:'', a keyword denoting the class, and ``:]''.  The
   following classes are defined by the POSIX standard:
 
+
      [\b[:\b:a\bal\bln\bnu\bum\bm:\b:]\b]
         Alphanumeric characters.
 
         and ``=]''.  For example, the name ``e'' might be used to
         represent all of ``e'' ``e'' and ``e''.  In this case, [\b[[\b[=\b=e\be=\b=]\b]]\b]
         is a regexp that matches any of ``e'', ``e'' and ``e''.
+
   A regular expression matching a single character may be followed by
   one of several repetition operators:
 
      \\b\y\by Matches the empty string at either the beginning or the end of a
         word.
 
+
      \\b\B\bB Matches the empty string within a word.
 
      \\b\<\b< Matches the empty string at the beginning of a word.
   systems.
 
 
-  4\b4.\b.1\b1.\b.2\b2.\b.  S\bSe\bea\bar\brc\bch\bhi\bin\bng\bg
+  4\b4.\b.2\b2.\b.  P\bPa\bat\btt\bte\ber\brn\bns\bs
 
   Many of Mutt's commands allow you to specify a pattern to match
   (limit, tag-pattern, delete-pattern, etc.).  There are several ways to
 
 
        ~A              all messages
-       ~b PATTERN      messages which contain PATTERN in the message body
+       ~b EXPR         messages which contain EXPR in the message body
+       ~B EXPR         messages which contain EXPR in the whole message
        ~c USER         messages carbon-copied to USER
-       ~C PATTERN      message is either to: or cc: PATTERN
+       ~C EXPR         message is either to: or cc: EXPR
        ~D              deleted messages
        ~d [MIN]-[MAX]  messages with ``date-sent'' in a Date range
        ~E              expired messages
-       ~e PATTERN      message which contains PATTERN in the ``Sender'' field
+       ~e EXPR         message which contains EXPR in the ``Sender'' field
        ~F              flagged messages
        ~f USER         messages originating from USER
-       ~h PATTERN      messages which contain PATTERN in the message header
+       ~h EXPR         messages which contain EXPR in the message header
        ~i ID           message which match ID in the ``Message-ID'' field
-       ~L PATTERN      message is either originated or received by PATTERN
+       ~L EXPR         message is either originated or received by EXPR
        ~l              message is addressed to a known mailing list
-       ~m [MIN]-[MAX]  message in the range MIN to MAX
-       ~n [MIN]-[MAX]  messages with a score in the range MIN to MAX
+       ~m [MIN]-[MAX]  message in the range MIN to MAX *)
+       ~n [MIN]-[MAX]  messages with a score in the range MIN to MAX *)
        ~N              new messages
        ~O              old messages
        ~p              message is addressed to you (consults $alternates)
        ~T              tagged messages
        ~t USER         messages addressed to USER
        ~U              unread messages
-       ~x PATTERN      messages which contain PATTERN in the `References' field
+       ~x EXPR         messages which contain EXPR in the `References' field
+       ~z [MIN]-[MAX]  messages with a size in the range MIN to MAX *)
+
 
 
 
+  Where EXPR, USER, ID, and SUBJECT are ``regular expressions''.
 
-  Where PATTERN, USER, ID, and SUBJECT are ``regular expressions''.
 
+  *) The forms <[MAX], >[MIN], [MIN]- and -[MAX] are allowed, too.
 
-  4\b4.\b.1\b1.\b.3\b3.\b.  C\bCo\bom\bmp\bpl\ble\bex\bx S\bSe\bea\bar\brc\bch\bhe\bes\bs
+
+  4\b4.\b.2\b2.\b.1\b1.\b.  C\bCo\bom\bmp\bpl\ble\bex\bx P\bPa\bat\btt\bte\ber\brn\bns\bs
 
 
   Logical AND is performed by specifying more than one criterion.  For
 
   +\bo  | -- logical OR operator
 
-
   +\bo  () -- logical grouping operator
 
   Here is an example illustrating a complex search pattern.  This
 
 
 
-  4\b4.\b.1\b1.\b.4\b4.\b.  S\bSe\bea\bar\brc\bch\bhi\bin\bng\bg b\bby\by D\bDa\bat\bte\be
+  4\b4.\b.2\b2.\b.2\b2.\b.  S\bSe\bea\bar\brc\bch\bhi\bin\bng\bg b\bby\by D\bDa\bat\bte\be
 
   Mutt supports two types of dates, _\ba_\bb_\bs_\bo_\bl_\bu_\bt_\be and _\br_\be_\bl_\ba_\bt_\bi_\bv_\be.
 
   zone, so unless you change the setting of your ``$index_format'' to
   include a %[...] format, these are n\bno\bot\bt the dates shown in the main
   index.
-  4\b4.\b.2\b2.\b.  U\bUs\bsi\bin\bng\bg T\bTa\bag\bgs\bs
+
+
+  4\b4.\b.3\b3.\b.  U\bUs\bsi\bin\bng\bg T\bTa\bag\bgs\bs
 
 
   Sometimes it is desirable to perform an operation on a group of
   pattern, use the tag-pattern function, which is bound to ``control-T''
   by default.  Or you can select individual messages by hand using the
   ``tag-message'' function, which is bound to ``t'' by default.  See
-  ``searching'' for Mutt's searching syntax.
+  ``patterns'' for Mutt's pattern matching syntax.
 
   Once you have tagged the desired messages, you can use the ``tag-
   prefix'' operator, which is the ``;'' (semicolon) key by default.
   ``tag-prefix''.
 
 
-  4\b4.\b.3\b3.\b.  U\bUs\bsi\bin\bng\bg H\bHo\boo\bok\bks\bs
+  4\b4.\b.4\b4.\b.  U\bUs\bsi\bin\bng\bg H\bHo\boo\bok\bks\bs
 
   A _\bh_\bo_\bo_\bk is a concept borrowed from the EMACS editor which allows you to
   execute arbitrary commands before performing some operation.  For
   example, you may wish to tailor your configuration based upon which
   mailbox you are reading, or to whom you are sending mail.  In the Mutt
-  world, a _\bh_\bo_\bo_\bk consists of a ``regular expression'' along with a
-  configuration option/command.  See
+  world, a _\bh_\bo_\bo_\bk consists of a ``regular expression'' or ``pattern''
+  along with a configuration option/command.  See
 
   +\bo  ``folder-hook''
 
      for specific details on each type of _\bh_\bo_\bo_\bk available.
 
 
-  4\b4.\b.3\b3.\b.1\b1.\b.  M\bMe\bes\bss\bsa\bag\bge\be M\bMa\bat\btc\bch\bhi\bin\bng\bg i\bin\bn H\bHo\boo\bok\bks\bs
+  4\b4.\b.4\b4.\b.1\b1.\b.  M\bMe\bes\bss\bsa\bag\bge\be M\bMa\bat\btc\bch\bhi\bin\bng\bg i\bin\bn H\bHo\boo\bok\bks\bs
 
   Hooks that act upon messages (send-hook, save-hook, fcc-hook) are
   evaluated in a slightly different manner.  For the other types of
-  hooks, a ``regular expression''.  But in dealing with messages a finer
-  grain of control is needed for matching since for different purposes
-  you want to match different criteria.
+  hooks, a ``regular expression'' is sufficient.  But in dealing with
+  messages a finer grain of control is needed for matching since for
+  different purposes you want to match different criteria.
 
   Mutt allows the use of the ``search pattern'' language for matching
   messages in hook commands.  This works in exactly the same way as it
        send-hook '~t ^me@cs\.hmc\.edu$' 'my_hdr From: Mutt User <user@host>'
 
 
+
+
   which would execute the given command when sending mail to
   _\bm_\be_\b@_\bc_\bs_\b._\bh_\bm_\bc_\b._\be_\bd_\bu.
 
   the full searching language.  You can still specify a simple _\br_\be_\bg_\bu_\bl_\ba_\br
   _\be_\bx_\bp_\br_\be_\bs_\bs_\bi_\bo_\bn like the other hooks, in which case Mutt will translate
   your pattern into the full language, using the translation specified
-  by the ``$dfault_hook'' variable.  The pattern is translated at the
+  by the ``$default_hook'' variable.  The pattern is translated at the
   time the hook is declared, so the value of ``$dfault_hook'' that is in
   effect at that time will be used.
 
 
-  4\b4.\b.4\b4.\b.  E\bEx\bxt\bte\ber\brn\bna\bal\bl A\bAd\bdd\bdr\bre\bes\bss\bs Q\bQu\bue\ber\bri\bie\bes\bs
+  4\b4.\b.5\b5.\b.  E\bEx\bxt\bte\ber\brn\bna\bal\bl A\bAd\bdd\bdr\bre\bes\bss\bs Q\bQu\bue\ber\bri\bie\bes\bs
 
   Mutt supports connecting to external directory databases such as LDAP,
   ph/qi, bbdb, or NIS through a wrapper script which connects to mutt
   matching addresses, return a non-zero exit code and a one line error
   message.
 
+
   An example multiple response output:
 
 
        Searching database ... 20 entries ... 3 matching:
-       me@cs.hmc.edu   Michael Elkins  mutt dude
+       me@cs.hmc.edu           Michael Elkins  mutt dude
        blong@fiction.net       Brandon Long    mutt and more
        roessler@guug.de        Thomas Roessler mutt pgp
 
   or more addresses to be added to the prompt.
 
 
-
-
-
-  4\b4.\b.5\b5.\b.  M\bMa\bai\bil\blb\bbo\box\bx F\bFo\bor\brm\bma\bat\bts\bs
+  4\b4.\b.6\b6.\b.  M\bMa\bai\bil\blb\bbo\box\bx F\bFo\bor\brm\bma\bat\bts\bs
 
   Mutt supports reading and writing of four different mailbox formats:
   mbox, MMDF, MH and Maildir.  The mailbox type is autodetected, so
   locking is needed.
 
 
-  4\b4.\b.6\b6.\b.  M\bMa\bai\bil\blb\bbo\box\bx S\bSh\bho\bor\brt\btc\bcu\but\bts\bs
+  4\b4.\b.7\b7.\b.  M\bMa\bai\bil\blb\bbo\box\bx S\bSh\bho\bor\brt\btc\bcu\but\bts\bs
 
   There are a number of built in shortcuts which refer to specific
   mailboxes.  These shortcuts can be used anywhere you are prompted for
 
   +\bo  = or + -- refers to your ``$folder'' directory
 
+  +\bo  @_\ba_\bl_\bi_\ba_\bs -- refers to the ``default save folder'' as determined by
+     the address of the alias
 
-  4\b4.\b.7\b7.\b.  H\bHa\ban\bnd\bdl\bli\bin\bng\bg M\bMa\bai\bil\bli\bin\bng\bg L\bLi\bis\bst\bts\bs
 
+  4\b4.\b.8\b8.\b.  H\bHa\ban\bnd\bdl\bli\bin\bng\bg M\bMa\bai\bil\bli\bin\bng\bg L\bLi\bis\bst\bts\bs
 
 
   Mutt has a few configuration options that make dealing with large
   delete uninteresting threads and quickly find topics of value.
 
 
-  4\b4.\b.8\b8.\b.  D\bDe\bel\bli\biv\bve\ber\bry\by S\bSt\bta\bat\btu\bus\bs N\bNo\bot\bti\bif\bfi\bic\bca\bat\bti\bio\bon\bn (\b(D\bDS\bSN\bN)\b) S\bSu\bup\bpp\bpo\bor\brt\bt
+  4\b4.\b.9\b9.\b.  D\bDe\bel\bli\biv\bve\ber\bry\by S\bSt\bta\bat\btu\bus\bs N\bNo\bot\bti\bif\bfi\bic\bca\bat\bti\bio\bon\bn (\b(D\bDS\bSN\bN)\b) S\bSu\bup\bpp\bpo\bor\brt\bt
 
   RFC1894 defines a set of MIME content types for relaying information
   about the status of electronic mail messages.  These can be thought of
   Refer to the man page on sendmail for more details on DSN.
 
 
-  4\b4.\b.9\b9.\b.  P\bPO\bOP\bP3\b3 S\bSu\bup\bpp\bpo\bor\brt\bt (\b(O\bOP\bPT\bTI\bIO\bON\bNA\bAL\bL)\b)
+  4\b4.\b.1\b10\b0.\b.  P\bPO\bOP\bP3\b3 S\bSu\bup\bpp\bpo\bor\brt\bt (\b(O\bOP\bPT\bTI\bIO\bON\bNA\bAL\bL)\b)
 
 
   If Mutt was compiled with POP3 support (by running the _\bc_\bo_\bn_\bf_\bi_\bg_\bu_\br_\be
   specialized program, such as fetchmail
 
 
+  4\b4.\b.1\b11\b1.\b.  I\bIM\bMA\bAP\bP S\bSu\bup\bpp\bpo\bor\brt\bt (\b(O\bOP\bPT\bTI\bIO\bON\bNA\bAL\bL)\b)
+
+
+  If Mutt was compiled with IMAP support (by running the _\bc_\bo_\bn_\bf_\bi_\bg_\bu_\br_\be
+  script with the _\b-_\b-_\be_\bn_\ba_\bb_\bl_\be_\b-_\bi_\bm_\ba_\bp flag), it has the ability to work with
+  folders located on a remote imap server.
+
+  You can access the remote inbox by selecting the folder
+  {imapserver}inbox, where imapserver is the name of the IMAP server and
+  inbox is the special name for your spool mailbox on the IMAP server.
+  If you want to access another mail folder at the IMAP server, you
+  should use {imapserver}path/to/folder where path/to/folder is the path
+  of the folder you want to access relative to your home directory.
+
+  N\bNo\bot\bte\be:\b: The IMAP support is in a very early state and quite unstable at
+  the moment. If you need a more stable way to access your IMAP folder,
+  consider using a specialized program, such as fetchmail.
+
+
+
+
+
+  4\b4.\b.1\b12\b2.\b.  S\bSt\bta\bar\brt\bt a\ba W\bWW\bWW\bW B\bBr\bro\bow\bws\bse\ber\br o\bon\bn U\bUR\bRL\bLs\bs (\b(E\bEX\bXT\bTE\bER\bRN\bNA\bAL\bL)\b)
+
+  If a message contains URLs (_\bu_\bn_\bi_\bf_\bi_\be_\bd _\br_\be_\bs_\bs_\bo_\bu_\br_\bc_\be _\bl_\bo_\bc_\ba_\bt_\bo_\br = address in the
+  WWW space like _\bh_\bt_\bt_\bp_\b:_\b/_\b/_\bw_\bw_\bw_\b._\bm_\bu_\bt_\bt_\b._\bo_\br_\bg_\b/), it is efficient to get a menu
+  with all the URLs and start a WWW browser on one of them.  This
+  functionality is provided by the external urlview program which can be
+  retrieved at ftp://ftp.cs.hmc.edu/pub/me/ and the configuration
+  commands:
+
+
+       macro index \cb |urlview\n
+       macro pager \cb |urlview\n
+
+
+
+
+
   5\b5.\b.  M\bMu\but\btt\bt'\b's\bs M\bMI\bIM\bME\bE S\bSu\bup\bpp\bpo\bor\brt\bt
 
   Quite a bit of effort has been made to make Mutt the premier text-mode
 
 
 
-
-
-
-
-
   5\b5.\b.1\b1.\b.2\b2.\b.  T\bTh\bhe\be A\bAt\btt\bta\bac\bch\bhm\bme\ben\bnt\bt M\bMe\ben\bnu\bu
 
   The default binding for view-attachments is `v', which displays the
      mail mailcap file uses this feature to test the charset to spawn an
      xterm using the right charset to view the message.
 
-     %\b%  This will be replaced by a %
+        This will be replaced by a %
 
   Mutt does not currently support the %F and %n keywords specified in
   RFC 1524.  The main purpose of these parameters is for multipart mes-
 
 
 
+
   5\b5.\b.5\b5.\b.  M\bMI\bIM\bME\bE M\bMu\bul\blt\bti\bip\bpa\bar\brt\bt/\b/A\bAl\blt\bte\ber\brn\bna\bat\bti\biv\bve\be
 
   Mutt has some heuristics for determining which attachment of a
        -Z      open the first folder with new message,exit immediately if none
 
 
-
   To read messages in a mailbox
 
   mutt [ -nz ] [ -F _\bm_\bu_\bt_\bt_\br_\bc ] [ -m _\bt_\by_\bp_\be ] [ -f _\bm_\ba_\bi_\bl_\bb_\bo_\bx ]
 
   +\bo  ``hdr_order'' _\bh_\be_\ba_\bd_\be_\br [ _\bh_\be_\ba_\bd_\be_\br ... ]
 
+  +\bo  ``unhdr_order'' _\bh_\be_\ba_\bd_\be_\br [ _\bh_\be_\ba_\bd_\be_\br ... ]
+
   +\bo  ``lists'' _\ba_\bd_\bd_\br_\be_\bs_\bs [ _\ba_\bd_\bd_\br_\be_\bs_\bs ... ]
 
   +\bo  ``unlists'' _\ba_\bd_\bd_\br_\be_\bs_\bs [ _\ba_\bd_\bd_\br_\be_\bs_\bs ... ]
 
 
 
-
-
   6\b6.\b.3\b3.\b.5\b5.\b.  a\bal\bll\blo\bow\bw_\b_8\b8b\bbi\bit\bt
 
   Type: boolean
 
 
 
-  6\b6.\b.3\b3.\b.2\b29\b9.\b.  e\bem\bmp\bpt\bty\by_\b_t\bto\bo
-
-  Type: string
-  Default: undisclosed-recipients
-
-  Specifies the text Mutt inserts in the To: header of a message you're
-  sending, if the To: and Cc: fields are empty.
-
-
-  6\b6.\b.3\b3.\b.3\b30\b0.\b.  e\bes\bsc\bca\bap\bpe\be
+  6\b6.\b.3\b3.\b.2\b29\b9.\b.  e\bes\bsc\bca\bap\bpe\be
 
   Type: string
   Default: ~
   Escape character to use for functions in the builtin editor.
 
 
-  6\b6.\b.3\b3.\b.3\b31\b1.\b.  f\bfa\bas\bst\bt_\b_r\bre\bep\bpl\bly\by
+  6\b6.\b.3\b3.\b.3\b30\b0.\b.  f\bfa\bas\bst\bt_\b_r\bre\bep\bpl\bly\by
 
   Type: boolean
   Default: unset
   set.
 
 
-  6\b6.\b.3\b3.\b.3\b32\b2.\b.  f\bfc\bcc\bc_\b_a\bat\btt\bta\bac\bch\bh
+  6\b6.\b.3\b3.\b.3\b31\b1.\b.  f\bfc\bcc\bc_\b_a\bat\btt\bta\bac\bch\bh
 
   Type: boolean
   Default: set
   are saved along with the main body of your message.
 
 
-  6\b6.\b.3\b3.\b.3\b33\b3.\b.  f\bfo\bol\bld\bde\ber\br
+  6\b6.\b.3\b3.\b.3\b32\b2.\b.  f\bfo\bol\bld\bde\ber\br
 
   Type: String
   Default: ~/Mail
   the `set' command.
 
 
+  6\b6.\b.3\b3.\b.3\b33\b3.\b.  f\bfo\bol\bld\bde\ber\br_\b_f\bfo\bor\brm\bma\bat\bt
+
+  Type: format string
+  Default: "%N %F %2l %-8.8u %-8.8g %8s %d %f"
+
+  This variable allows you to customize the file browser display to your
+  personal taste.  This string is similar to ``$index_format'', but has
+  its own set of printf()-like sequences:
+
+
+
+       %d      date/time folder was last modified
+       %f      filename
+       %F      file permissions
+       %g      group name (or numeric gid, if missing)
+       %l      number of hard links
+       %N      N if folder has new mail, blank otherwise
+       %s      size in bytes
+       %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"
+
   6\b6.\b.3\b3.\b.3\b34\b4.\b.  f\bfo\bol\bll\blo\bow\bwu\bup\bp_\b_t\bto\bo
 
   Type: boolean
   will receive a copy of the message if it is addressed to the mailing
   list (and thus there is no need to also include your address in a
   group reply).
+
+
   6\b6.\b.3\b3.\b.3\b35\b5.\b.  f\bfo\bor\brc\bce\be_\b_n\bna\bam\bme\be
 
   Type: boolean
   ``indent_string''.
 
 
-  6\b6.\b.3\b3.\b.3\b39\b9.\b.  i\bin\bnd\bde\bex\bx_\b_f\bfo\bor\brm\bma\bat\bt
-
-  Type: format string
-  Default: "%4C %Z %{%b %d} %-15.15L (%4l) %s"
-
-  This variable allows you to customize the message index display to
-  your personal taste.
-
-  ``Format strings'' are similar to the strings used in the ``C''
-  function printf to format output (see the man page for more detail).
-  The following sequences are defined in Mutt:
-
-
-
-
-
-
-
-
-
-
-
-
-
-  %a      address of the author
-  %b      filename of the original message folder (think mailBox)
-  %B      the list to which the letter was sent, or else the folder name (%b).
-  %c      number of characters (bytes) in the message
-  %C      current message number
-  %d      date and time of the message in the format specified by
-          ``date_format''
-  %f      entire From: line (address + real name)
-  %F      author name, or recipient name if the message is from you
-  %i      message-id of the current message
-  %l      number of lines in the message
-  %L      list-from function
-  %m      total number of message in the mailbox
-  %N      message score
-  %n      author's real name (or address if missing)
-  %O       (_O_riginal save folder)  Where mutt would formerly have stashed the
-          message: list name or recipient name if no list
-  %s      subject of the message
-  %S      status of the message (N/D/d/!/*/r)
-  %t      `to:' field (recipients)
-  %T      the appropriate character from the $to_chars string
-  %u      user (login) name of the author
-  %Z      message status flags
-
-  %{fmt}  the date and time of the message is converted to sender's
-          time zone, and ``fmt'' is expanded by the system call
-          ``strftime''; a leading bang disables locales
-  %[fmt]  the date and time of the message is converted to the local
-          time zone, and ``fmt'' is expanded by the system call
-          ``strftime''; a leading bang disables locales
-  %(fmt)  the local date and time when the message was received.
-          ``fmt'' is expanded by the system call ``strftime'';
-          a leading bang disables locales
-  %<fmt>  the current local time. ``fmt'' is expanded by the system
-          call ``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"
-
-
-
-
-  See also: ``$to_chars''.
-
-
-  6\b6.\b.3\b3.\b.4\b40\b0.\b.  h\bhd\bdr\brs\bs
+  6\b6.\b.3\b3.\b.3\b39\b9.\b.  h\bhd\bdr\brs\bs
 
   Type: boolean
   Default: set
   header fields are added to every new message.
 
 
-  6\b6.\b.3\b3.\b.4\b41\b1.\b.  h\bhe\bea\bad\bde\ber\br
+  6\b6.\b.3\b3.\b.4\b40\b0.\b.  h\bhe\bea\bad\bde\ber\br
 
   Type: boolean
   Default: unset
   message you are replying to into the edit buffer.
 
 
-
-  6\b6.\b.3\b3.\b.4\b42\b2.\b.  h\bhe\bel\blp\bp
+  6\b6.\b.3\b3.\b.4\b41\b1.\b.  h\bhe\bel\blp\bp
 
   Type: boolean
   Default: set
   should present a major problem.
 
 
+  6\b6.\b.3\b3.\b.4\b42\b2.\b.  h\bhi\bid\bdd\bde\ben\bn_\b_h\bho\bos\bst\bt
+
+  Type: boolean
+  Default: unset
+
+  When set, mutt will skip the host name part of ``hostname'' variable
+  when adding the domain part to addresses.  This variable does not
+  affect the generation, and it will not lead to the cut-off of first-
+  level domains.
+
+
   6\b6.\b.3\b3.\b.4\b43\b3.\b.  h\bhi\bis\bst\bto\bor\bry\by
 
   Type: number
   will reply to both the sender and the list.
 
 
-  6\b6.\b.3\b3.\b.4\b46\b6.\b.  i\bin\bn_\b_r\bre\bep\bpl\bly\by_\b_t\bto\bo
+  6\b6.\b.3\b3.\b.4\b46\b6.\b.  i\bim\bma\bap\bp_\b_c\bch\bhe\bec\bck\bki\bin\bnt\bte\ber\brv\bva\bal\bl
+
+  Type: number
+  Default: 0
+
+  This variable configures how often (in seconds) IMAP should look for
+  new mail.
+
+
+  6\b6.\b.3\b3.\b.4\b47\b7.\b.  i\bim\bma\bap\bp_\b_p\bpa\bas\bss\bs
+
+  Type: string
+  Default: unset
+
+  Specifies the password for your IMAP account.  If unset, Mutt will
+  prompt you for your password when you invoke the fetch-mail function.
+  W\bWa\bar\brn\bni\bin\bng\bg: you should only use this option when you are on a fairly
+  secure machine, because the superuser can read your muttrc even if you
+  are the only one who can read the file.
+
+
+  6\b6.\b.3\b3.\b.4\b48\b8.\b.  i\bim\bma\bap\bp_\b_u\bus\bse\ber\br
+
+  Type: string
+  Default: login name on local system
+
+  Your login name on the IMAP server.
+
+
+  6\b6.\b.3\b3.\b.4\b49\b9.\b.  i\bin\bn_\b_r\bre\bep\bpl\bly\by_\b_t\bto\bo
 
   Type: format string
   Default: "%i; from \"%n\" on %{!%a, %b %d, %Y at %I:%M:%S%p}"
   see the section on ``$index_format''.
 
 
-  6\b6.\b.3\b3.\b.4\b47\b7.\b.  i\bin\bnc\bcl\blu\bud\bde\be
+  6\b6.\b.3\b3.\b.5\b50\b0.\b.  i\bin\bnc\bcl\blu\bud\bde\be
 
   Type: quadoption
   Default: ask-yes
 
   Controls whether or not a copy of the message(s) you are replying to
   is included in your reply.
-  6\b6.\b.3\b3.\b.4\b48\b8.\b.  i\bin\bnd\bde\ben\bnt\bt_\b_s\bst\btr\bri\bin\bng\bg
+
+
+  6\b6.\b.3\b3.\b.5\b51\b1.\b.  i\bin\bnd\bde\ben\bnt\bt_\b_s\bst\btr\bri\bin\bng\bg
 
   Type: format string
   Default: "> "
   change this value, as it tends to agitate the more fanatical netizens.
 
 
-  6\b6.\b.3\b3.\b.4\b49\b9.\b.  i\bis\bsp\bpe\bel\bll\bl
+
+
+  6\b6.\b.3\b3.\b.5\b52\b2.\b.  i\bin\bnd\bde\bex\bx_\b_f\bfo\bor\brm\bma\bat\bt
+
+  Type: format string
+  Default: "%4C %Z %{%b %d} %-15.15L (%4l) %s"
+
+  This variable allows you to customize the message index display to
+  your personal taste.
+
+  ``Format strings'' are similar to the strings used in the ``C''
+  function printf to format output (see the man page for more detail).
+  The following sequences are defined in Mutt:
+
+
+
+       %a      address of the author
+       %b      filename of the original message folder (think mailBox)
+       %B      the list to which the letter was sent, or else the folder name (%b).
+       %c      number of characters (bytes) in the message
+       %C      current message number
+       %d      date and time of the message in the format specified by
+               ``date_format''
+       %f      entire From: line (address + real name)
+       %F      author name, or recipient name if the message is from you
+       %i      message-id of the current message
+       %l      number of lines in the message
+       %L      list-from function
+       %m      total number of message in the mailbox
+       %N      message score
+       %n      author's real name (or address if missing)
+       %O       (_O_riginal save folder)  Where mutt would formerly have stashed the
+               message: list name or recipient name if no list
+       %s      subject of the message
+       %S      status of the message (N/D/d/!/*/r)
+       %t      `to:' field (recipients)
+       %T      the appropriate character from the $to_chars string
+       %u      user (login) name of the author
+       %Z      message status flags
+
+       %{fmt}  the date and time of the message is converted to sender's
+               time zone, and ``fmt'' is expanded by the system call
+               ``strftime''; a leading bang disables locales
+       %[fmt]  the date and time of the message is converted to the local
+               time zone, and ``fmt'' is expanded by the system call
+               ``strftime''; a leading bang disables locales
+       %(fmt)  the local date and time when the message was received.
+               ``fmt'' is expanded by the system call ``strftime'';
+               a leading bang disables locales
+       %<fmt>  the current local time. ``fmt'' is expanded by the system
+               call ``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"
+
+
+
+
+  See also: ``$to_chars''.
+
+
+  6\b6.\b.3\b3.\b.5\b53\b3.\b.  i\bis\bsp\bpe\bel\bll\bl
 
   Type: string
   Default: "ispell"
 
   How to invoke ispell (GNU's spell-checking software).
 
-
-  6\b6.\b.3\b3.\b.5\b50\b0.\b.  l\blo\boc\bca\bal\ble\be
+  6\b6.\b.3\b3.\b.5\b54\b4.\b.  l\blo\boc\bca\bal\ble\be
 
   Type: string
   Default: "C"
   strings your system accepts for the locale variable _\bL_\bC_\b__\bT_\bI_\bM_\bE.
 
 
-  6\b6.\b.3\b3.\b.5\b51\b1.\b.  m\bma\bai\bil\blc\bca\bap\bp_\b_p\bpa\bat\bth\bh
+  6\b6.\b.3\b3.\b.5\b55\b5.\b.  m\bma\bai\bil\blc\bca\bap\bp_\b_p\bpa\bat\bth\bh
 
   Type: string
   Default: $MAILCAPS or
   display MIME bodies not directly supported by Mutt.
 
 
-  6\b6.\b.3\b3.\b.5\b52\b2.\b.  m\bma\bar\brk\bk_\b_o\bol\bld\bd
+  6\b6.\b.3\b3.\b.5\b56\b6.\b.  m\bma\bai\bil\bl_\b_c\bch\bhe\bec\bck\bk
+
+  Type: number
+  Default: 5
+
+  This variable configures how often (in seconds) mutt should look for
+  new mail.
+
+
+  6\b6.\b.3\b3.\b.5\b57\b7.\b.  m\bma\bar\brk\bk_\b_o\bol\bld\bd
 
-  Type: Boolean
+  Type: boolean
   Default: set
 
   Controls whether or not Mutt makes the distinction between _\bn_\be_\bw
   variable.
 
 
-  6\b6.\b.3\b3.\b.5\b53\b3.\b.  m\bma\bar\brk\bke\ber\brs\bs
+  6\b6.\b.3\b3.\b.5\b58\b8.\b.  m\bma\bar\brk\bke\ber\brs\bs
 
   Type: boolean
   Default: set
   the ``$smart_wrap'' variable.
 
 
-  6\b6.\b.3\b3.\b.5\b54\b4.\b.  m\bma\bas\bsk\bk
+  6\b6.\b.3\b3.\b.5\b59\b9.\b.  m\bma\bas\bsk\bk
 
   Type: string
-  Default: "^(\.\.$|[^.])"
+  Default: "!^\.[^.]"
+
+  A regular expression used in the file browser, optionally preceded by
+  the _\bn_\bo_\bt operator ``!''. Files whose names don't match this mask will
+  not be shown. The match is always case-sensitive.
 
-  A regular expression used in the file browser. Files whose names don't
-  match this mask will not be shown.
+  N\bNo\bot\bte\be:\b: if you need ``!'' at the beginning of the regular expression you
+  should enclose it in paranthesis, in order to distinguish it from the
+  logical _\bn_\bo_\bt operator for the expression.
 
 
-  6\b6.\b.3\b3.\b.5\b55\b5.\b.  m\bmb\bbo\box\bx
+  6\b6.\b.3\b3.\b.6\b60\b0.\b.  m\bmb\bbo\box\bx
 
   Type: String
   Default: +inbox
   folder will be appended.
 
 
-  6\b6.\b.3\b3.\b.5\b56\b6.\b.  m\bmb\bbo\box\bx_\b_t\bty\byp\bpe\be
+  6\b6.\b.3\b3.\b.6\b61\b1.\b.  m\bmb\bbo\box\bx_\b_t\bty\byp\bpe\be
 
   Type: String
   Default: mbox
   mbox, MMDF, MH and Maildir.
 
 
-  6\b6.\b.3\b3.\b.5\b57\b7.\b.  m\bme\bet\bto\boo\bo
+  6\b6.\b.3\b3.\b.6\b62\b2.\b.  m\bme\bet\bto\boo\bo
 
   Type: boolean
   Default: unset
   that message rather than to yourself.
 
 
-  6\b6.\b.3\b3.\b.5\b58\b8.\b.  m\bme\ben\bnu\bu_\b_s\bsc\bcr\bro\bol\bll\bl
+  6\b6.\b.3\b3.\b.6\b63\b3.\b.  m\bme\ben\bnu\bu_\b_s\bsc\bcr\bro\bol\bll\bl
 
   Type: boolean
   Default: unset
   links to avoid many redraws).
 
 
-  6\b6.\b.3\b3.\b.5\b59\b9.\b.  m\bme\bet\bta\ba_\b_k\bke\bey\by
+  6\b6.\b.3\b3.\b.6\b64\b4.\b.  m\bme\bet\bta\ba_\b_k\bke\bey\by
 
-  Type: Boolean
+  Type: boolean
   Default: unset
 
   If set, forces Mutt to interpret keystrokes with the high bit (bit 8)
   ``x''.
 
 
-  6\b6.\b.3\b3.\b.6\b60\b0.\b.  m\bmi\bim\bme\be_\b_f\bfo\bor\brw\bwa\bar\brd\bd
+  6\b6.\b.3\b3.\b.6\b65\b5.\b.  m\bmi\bim\bme\be_\b_f\bfo\bor\brw\bwa\bar\brd\bd
 
-  Type: boolean
+  Type: quadoption
   Default: unset
 
   When set, the message you are forwarding will be attached as a
   separate MIME part instead of included in the main body of the
   message.  This is useful for forwarding MIME messages so the receiver
-  can properly view the message as it was delivered to you.
+  can properly view the message as it was delivered to you. If you like
+  to switch between MIME and not MIME from mail to mail, set this
+  variable to ask-no or ask-yes.
 
   Also see ``forward_decode'' and ``mime_forward_decode''.
 
 
-  6\b6.\b.3\b3.\b.6\b61\b1.\b.  m\bmi\bim\bme\be_\b_f\bfo\bor\brw\bwa\bar\brd\bd_\b_d\bde\bec\bco\bod\bde\be
+  6\b6.\b.3\b3.\b.6\b66\b6.\b.  m\bmi\bim\bme\be_\b_f\bfo\bor\brw\bwa\bar\brd\bd_\b_d\bde\bec\bco\bod\bde\be
 
   Type: boolean
   Default: unset
   ``forward_decode'' is used instead.
 
 
-  6\b6.\b.3\b3.\b.6\b62\b2.\b.  m\bmo\bov\bve\be
+  6\b6.\b.3\b3.\b.6\b67\b7.\b.  m\bmo\bov\bve\be
 
   Type: quadoption
   Default: ask-no
   ``mbox-hook'' command.
 
 
-  6\b6.\b.3\b3.\b.6\b63\b3.\b.  m\bme\bes\bss\bsa\bag\bge\be_\b_f\bfo\bor\brm\bma\bat\bt
+  6\b6.\b.3\b3.\b.6\b68\b8.\b.  m\bme\bes\bss\bsa\bag\bge\be_\b_f\bfo\bor\brm\bma\bat\bt
 
-  Type: string
+  Type: format string
   Default: "%s"
 
   This is the string displayed in the ``attachment'' menu for
   escape sequences see the section on ``index_format''.
 
 
-  6\b6.\b.3\b3.\b.6\b64\b4.\b.  p\bpa\bag\bge\ber\br
+  6\b6.\b.3\b3.\b.6\b69\b9.\b.  p\bpa\bag\bge\ber\br
 
   Type: string
   Default: builtin
   like to use.
 
 
-  6\b6.\b.3\b3.\b.6\b65\b5.\b.  p\bpa\bag\bge\ber\br_\b_c\bco\bon\bnt\bte\bex\bxt\bt
+  6\b6.\b.3\b3.\b.7\b70\b0.\b.  p\bpa\bag\bge\ber\br_\b_c\bco\bon\bnt\bte\bex\bxt\bt
 
   Type: number
   Default: 0
   at the top of the next page (0 lines of context).
 
 
-  6\b6.\b.3\b3.\b.6\b66\b6.\b.  p\bpa\bag\bge\ber\br_\b_f\bfo\bor\brm\bma\bat\bt
+  6\b6.\b.3\b3.\b.7\b71\b1.\b.  p\bpa\bag\bge\ber\br_\b_f\bfo\bor\brm\bma\bat\bt
 
   Type: format string
   Default: "-%S- %C/%m: %-20.20n   %s"
   displayed before each message in either the internal or an external
   pager.  The valid sequences are listed in the ``index_format''
   section.
-  6\b6.\b.3\b3.\b.6\b67\b7.\b.  p\bpa\bag\bge\ber\br_\b_i\bin\bnd\bde\bex\bx_\b_l\bli\bin\bne\bes\bs
+
+
+  6\b6.\b.3\b3.\b.7\b72\b2.\b.  p\bpa\bag\bge\ber\br_\b_i\bin\bnd\bde\bex\bx_\b_l\bli\bin\bne\bes\bs
 
   Type: number
   Default: 0
   lines as it needs.
 
 
-  6\b6.\b.3\b3.\b.6\b68\b8.\b.  p\bpa\bag\bge\ber\br_\b_s\bst\bto\bop\bp
+  6\b6.\b.3\b3.\b.7\b73\b3.\b.  p\bpa\bag\bge\ber\br_\b_s\bst\bto\bop\bp
 
   Type: boolean
   Default: unset
   you are at the end of a message and invoke the _\bn_\be_\bx_\bt_\b-_\bp_\ba_\bg_\be function.
 
 
-  6\b6.\b.3\b3.\b.6\b69\b9.\b.  p\bpg\bgp\bp_\b_a\bau\but\bto\boe\ben\bnc\bcr\bry\byp\bpt\bt
+  6\b6.\b.3\b3.\b.7\b74\b4.\b.  p\bpg\bgp\bp_\b_a\bau\but\bto\boe\ben\bnc\bcr\bry\byp\bpt\bt
 
   Type: boolean
   Default: unset
   _\bm_\be_\bn_\bu, when encryption is not required or signing is requested as well.
 
 
-  6\b6.\b.3\b3.\b.7\b70\b0.\b.  p\bpg\bgp\bp_\b_a\bau\but\bto\bos\bsi\big\bgn\bn
+  6\b6.\b.3\b3.\b.7\b75\b5.\b.  p\bpg\bgp\bp_\b_a\bau\but\bto\bos\bsi\big\bgn\bn
 
   Type: boolean
   Default: unset
   _\bm_\be_\bn_\bu, when signing is not required or encryption is requested as well.
 
 
-  6\b6.\b.3\b3.\b.7\b71\b1.\b.  p\bpg\bgp\bp_\b_d\bde\bef\bfa\bau\bul\blt\bt_\b_v\bve\ber\brs\bsi\bio\bon\bn
+  6\b6.\b.3\b3.\b.7\b76\b6.\b.  p\bpg\bgp\bp_\b_d\bde\bef\bfa\bau\bul\blt\bt_\b_v\bve\ber\brs\bsi\bio\bon\bn
 
   Type: string
-  Default: pgp2 (or pgp5, if PGP 2.* is not installed)
+  Default: pgp2 (or pgp5, if PGP 2.* is not installed, or gpg, if none
+  of them is installed)
 
-  Set this to pgp2 (PGP 2.*), or pgp5 (PGP 5.*) depending on the
-  version, you are using primary. This variable is directly used, but it
-  is the default for the variables ``$pgp_receive_version'',
-  ``$pgp_send_version'', and ``$pgp_key_version''.
+  Set this to pgp2 (PGP 2.*), pgp5 (PGP 5.*), or gpg (GNU privacy
+  guard), depending on the version that you primarily use. This variable
+  is not directly used, but it is the default for the variables
+  ``$pgp_receive_version'', ``$pgp_send_version'', and
+  ``$pgp_key_version''.
 
 
-  6\b6.\b.3\b3.\b.7\b72\b2.\b.  p\bpg\bgp\bp_\b_e\ben\bnc\bcr\bry\byp\bpt\bts\bse\bel\blf\bf
+  6\b6.\b.3\b3.\b.7\b77\b7.\b.  p\bpg\bgp\bp_\b_e\ben\bnc\bcr\bry\byp\bpt\bts\bse\bel\blf\bf
 
   Type: boolean
   Default: set
 
   If set, the PGP _\b+_\be_\bn_\bc_\br_\by_\bp_\bt_\bt_\bo_\bs_\be_\bl_\bf flag is used when encrypting messages.
 
-  6\b6.\b.3\b3.\b.7\b73\b3.\b.  p\bpg\bgp\bp_\b_k\bke\bey\by_\b_v\bve\ber\brs\bsi\bio\bon\bn
+
+  6\b6.\b.3\b3.\b.7\b78\b8.\b.  p\bpg\bgp\bp_\b_g\bgp\bpg\bg
+
+  Type: string
+  Default: system dependent
+
+  This variable allows you to override the compile time definition of
+  where the gpg (GNU Privacy Guard) binary resides on your system.
+
+
+  6\b6.\b.3\b3.\b.7\b79\b9.\b.  p\bpg\bgp\bp_\b_k\bke\bey\by_\b_v\bve\ber\brs\bsi\bio\bon\bn
 
   Type: string
   Default: ``default''
 
-  This variable determines, which PGP version used for key ring
+  This variable determines which PGP version is used for key ring
   operations like extracting keys from messages and extracting keys from
   your keyring. If you set this to default, the default defined in
-  ``$pgp_default_version'' is used. Set this to pgp2 (PGP 2.*), or pgp5
-  (PGP 5.*) if you want a different PGP version for key operations.
+  ``$pgp_default_version'' is used. Set this to pgp2 (PGP 2.*), pgp5
+  (PGP 5.*), or gpg (GNU privacy guard) if you want to use a different
+  PGP version for key operations.
 
 
-  6\b6.\b.3\b3.\b.7\b74\b4.\b.  p\bpg\bgp\bp_\b_l\blo\bon\bng\bg_\b_i\bid\bds\bs
+  6\b6.\b.3\b3.\b.8\b80\b0.\b.  p\bpg\bgp\bp_\b_l\blo\bon\bng\bg_\b_i\bid\bds\bs
 
   Type: boolean
   Default: unset
   If set, use 64 bit PGP key IDs. Unset uses the normal 32 bit Key IDs.
 
 
-  6\b6.\b.3\b3.\b.7\b75\b5.\b.  p\bpg\bgp\bp_\b_r\bre\bec\bce\bei\biv\bve\be_\b_v\bve\ber\brs\bsi\bio\bon\bn
+  6\b6.\b.3\b3.\b.8\b81\b1.\b.  p\bpg\bgp\bp_\b_r\bre\bec\bce\bei\biv\bve\be_\b_v\bve\ber\brs\bsi\bio\bon\bn
 
   Type: string
   Default: ``default''
 
-  This variable determines, which PGP version used for decrypting
+  This variable determines which PGP version is used for decrypting
   messages and verifying signatures. If you set this to default, the
   default defined in ``$pgp_default_version'' will be used. Set this to
-  pgp2 (PGP 2.*), or pgp5 (PGP 5.*) if you want a different PGP version
-  for receiving operations.
+  pgp2 (PGP 2.*), pgp5 (PGP 5.*), or gpg (GNU privacy guard) if you want
+  to use a different PGP version for receiving operations.
 
 
-  6\b6.\b.3\b3.\b.7\b76\b6.\b.  p\bpg\bgp\bp_\b_r\bre\bep\bpl\bly\bye\ben\bnc\bcr\bry\byp\bpt\bt
+  6\b6.\b.3\b3.\b.8\b82\b2.\b.  p\bpg\bgp\bp_\b_r\bre\bep\bpl\bly\bye\ben\bnc\bcr\bry\byp\bpt\bt
 
   Type: boolean
   Default: unset
   encrypted.
 
 
-  6\b6.\b.3\b3.\b.7\b77\b7.\b.  p\bpg\bgp\bp_\b_r\bre\bep\bpl\bly\bys\bsi\big\bgn\bn
+  6\b6.\b.3\b3.\b.8\b83\b3.\b.  p\bpg\bgp\bp_\b_r\bre\bep\bpl\bly\bys\bsi\big\bgn\bn
 
   Type: boolean
   Default: unset
   N\bNo\bot\bte\be:\b: this does not work on messages, that are encrypted a\ban\bnd\bd signed!
 
 
-  6\b6.\b.3\b3.\b.7\b78\b8.\b.  p\bpg\bgp\bp_\b_s\bse\ben\bnd\bd_\b_v\bve\ber\brs\bsi\bio\bon\bn
+
+
+  6\b6.\b.3\b3.\b.8\b84\b4.\b.  p\bpg\bgp\bp_\b_s\bse\ben\bnd\bd_\b_v\bve\ber\brs\bsi\bio\bon\bn
 
   Type: string
   Default: ``default''
 
-  This variable determines, which PGP version used for composing new
+  This variable determines which PGP version is used for composing new
   messages like encrypting and signing. If you set this to default, the
   default defined in ``$pgp_default_version'' will be used. Set this to
-  pgp2 (PGP 2.*), or pgp5 (PGP 5.*) if you want a different PGP version
-  for sending operations.
-
-
+  pgp2 (PGP 2.*), pgp5 (PGP 5.*), or gpg (GNU privacy guard) if you want
+  to use a different PGP version for sending operations.
 
 
-
-  6\b6.\b.3\b3.\b.7\b79\b9.\b.  p\bpg\bgp\bp_\b_s\bsi\big\bgn\bn_\b_a\bas\bs
+  6\b6.\b.3\b3.\b.8\b85\b5.\b.  p\bpg\bgp\bp_\b_s\bsi\big\bgn\bn_\b_a\bas\bs
 
   Type: string
   Default: unset
   keyid form to specify your key (e.g., ``0xABCDEFGH'').
 
 
-  6\b6.\b.3\b3.\b.8\b80\b0.\b.  p\bpg\bgp\bp_\b_s\bsi\big\bgn\bn_\b_m\bmi\bic\bca\bal\blg\bg
+  6\b6.\b.3\b3.\b.8\b86\b6.\b.  p\bpg\bgp\bp_\b_s\bsi\big\bgn\bn_\b_m\bmi\bic\bca\bal\blg\bg
 
   Type: string
   Default: pgp-md5
   of MIME headers when creating RFC 2015 signatures.
 
 
-  6\b6.\b.3\b3.\b.8\b81\b1.\b.  p\bpg\bgp\bp_\b_s\bst\btr\bri\bic\bct\bt_\b_e\ben\bnc\bc
+  6\b6.\b.3\b3.\b.8\b87\b7.\b.  p\bpg\bgp\bp_\b_s\bst\btr\bri\bic\bct\bt_\b_e\ben\bnc\bc
 
   Type: boolean
   Default: set
   you know what you are doing.
 
 
-  6\b6.\b.3\b3.\b.8\b82\b2.\b.  p\bpg\bgp\bp_\b_t\bti\bim\bme\beo\bou\but\bt
+  6\b6.\b.3\b3.\b.8\b88\b8.\b.  p\bpg\bgp\bp_\b_t\bti\bim\bme\beo\bou\but\bt
 
   Type: number
   Default: 300
   not used.
 
 
-  6\b6.\b.3\b3.\b.8\b83\b3.\b.  p\bpg\bgp\bp_\b_v\bv2\b2
+  6\b6.\b.3\b3.\b.8\b89\b9.\b.  p\bpg\bgp\bp_\b_v\bv2\b2
 
   Type: string
   Default: system dependent
 
   This variable allows you to override the compile time definition of
   where the PGP 2.* binary resides on your system.
-
-
-  6\b6.\b.3\b3.\b.8\b84\b4.\b.  p\bpg\bgp\bp_\b_v\bv2\b2_\b_l\bla\ban\bng\bgu\bua\bag\bge\be
+  6\b6.\b.3\b3.\b.9\b90\b0.\b.  p\bpg\bgp\bp_\b_v\bv2\b2_\b_l\bla\ban\bng\bgu\bua\bag\bge\be
 
   Type: string
   Default: en
   (English) or "muttde" (German) to reduce the noise produced by pgp.
 
 
-  6\b6.\b.3\b3.\b.8\b85\b5.\b.  p\bpg\bgp\bp_\b_v\bv2\b2_\b_p\bpu\bub\bbr\bri\bin\bng\bg
+  6\b6.\b.3\b3.\b.9\b91\b1.\b.  p\bpg\bgp\bp_\b_v\bv2\b2_\b_p\bpu\bub\bbr\bri\bin\bng\bg
 
   Type: string
   Default: $PGPPATH/pubring.pgp or ~/.pgp/pubring.pgp if $PGPPATH isn't
   Points to the PGP 2.* public keyring.
 
 
-  6\b6.\b.3\b3.\b.8\b86\b6.\b.  p\bpg\bgp\bp_\b_v\bv2\b2_\b_s\bse\bec\bcr\bri\bin\bng\bg
+  6\b6.\b.3\b3.\b.9\b92\b2.\b.  p\bpg\bgp\bp_\b_v\bv2\b2_\b_s\bse\bec\bcr\bri\bin\bng\bg
 
   Type: string
   Default: $PGPPATH/secring.pgp or ~/.pgp/secring.pgp if $PGPPATH isn't
   Points to the PGP 2.* secret keyring.
 
 
-  6\b6.\b.3\b3.\b.8\b87\b7.\b.  p\bpg\bgp\bp_\b_v\bv5\b5
+  6\b6.\b.3\b3.\b.9\b93\b3.\b.  p\bpg\bgp\bp_\b_v\bv5\b5
 
   Type: string
   Default: system dependent
   where the PGP 5.* binary resides on your system.
 
 
-  6\b6.\b.3\b3.\b.8\b88\b8.\b.  p\bpg\bgp\bp_\b_v\bv5\b5_\b_l\bla\ban\bng\bgu\bua\bag\bge\be
+  6\b6.\b.3\b3.\b.9\b94\b4.\b.  p\bpg\bgp\bp_\b_v\bv5\b5_\b_l\bla\ban\bng\bgu\bua\bag\bge\be
 
   Type: string
   Default: en
   (English) to reduce the noise produced by pgp.
 
 
-  6\b6.\b.3\b3.\b.8\b89\b9.\b.  p\bpg\bgp\bp_\b_v\bv5\b5_\b_p\bpu\bub\bbr\bri\bin\bng\bg
+  6\b6.\b.3\b3.\b.9\b95\b5.\b.  p\bpg\bgp\bp_\b_v\bv5\b5_\b_p\bpu\bub\bbr\bri\bin\bng\bg
 
   Type: string
   Default: $PGPPATH/pubring.pkr or ~/.pgp/pubring.pkr if $PGPPATH isn't
   Points to the PGP 5.* public keyring.
 
 
-  6\b6.\b.3\b3.\b.9\b90\b0.\b.  p\bpg\bgp\bp_\b_v\bv5\b5_\b_s\bse\bec\bcr\bri\bin\bng\bg
+  6\b6.\b.3\b3.\b.9\b96\b6.\b.  p\bpg\bgp\bp_\b_v\bv5\b5_\b_s\bse\bec\bcr\bri\bin\bng\bg
 
   Type: string
   Default: $PGPPATH/secring.skr or ~/.pgp/secring.skr if $PGPPATH isn't
   Points to the PGP 5.* secret keyring.
 
 
-  6\b6.\b.3\b3.\b.9\b91\b1.\b.  p\bpi\bip\bpe\be_\b_d\bde\bec\bco\bod\bde\be
+
+  6\b6.\b.3\b3.\b.9\b97\b7.\b.  p\bpi\bip\bpe\be_\b_d\bde\bec\bco\bod\bde\be
 
   Type: boolean
   Default: unset
   weed headers and will attempt to PGP/MIME decode the messages first.
 
 
-
-  6\b6.\b.3\b3.\b.9\b92\b2.\b.  p\bpi\bip\bpe\be_\b_s\bse\bep\bp
+  6\b6.\b.3\b3.\b.9\b98\b8.\b.  p\bpi\bip\bpe\be_\b_s\bse\bep\bp
 
   Type: string
   Default: newline
   messages to an external Unix command.
 
 
-  6\b6.\b.3\b3.\b.9\b93\b3.\b.  p\bpi\bip\bpe\be_\b_s\bsp\bpl\bli\bit\bt
+  6\b6.\b.3\b3.\b.9\b99\b9.\b.  p\bpi\bip\bpe\be_\b_s\bsp\bpl\bli\bit\bt
 
   Type: boolean
   Default: unset
   and the ``$pipe_sep'' separator is added after each message.
 
 
-  6\b6.\b.3\b3.\b.9\b94\b4.\b.  p\bpo\bop\bp_\b_d\bde\bel\ble\bet\bte\be
+  6\b6.\b.3\b3.\b.1\b10\b00\b0.\b.  p\bpo\bop\bp_\b_d\bde\bel\ble\bet\bte\be
 
   Type: boolean
   Default: unset
   download messages but also leave them on the POP server.
 
 
-  6\b6.\b.3\b3.\b.9\b95\b5.\b.  p\bpo\bop\bp_\b_h\bho\bos\bst\bt
+  6\b6.\b.3\b3.\b.1\b10\b01\b1.\b.  p\bpo\bop\bp_\b_h\bho\bos\bst\bt
 
   Type: string
   Default: none
   The name or address of your POP3 server.
 
 
-  6\b6.\b.3\b3.\b.9\b96\b6.\b.  p\bpo\bop\bp_\b_p\bpa\bas\bss\bs
+  6\b6.\b.3\b3.\b.1\b10\b02\b2.\b.  p\bpo\bop\bp_\b_p\bpa\bas\bss\bs
 
   Type: string
   Default: unset
 
-  Specifies the password for you POP account.  If unset, Mutt will
+  Specifies the password for your POP account.  If unset, Mutt will
   prompt you for your password when you invoke the fetch-mail function.
   W\bWa\bar\brn\bni\bin\bng\bg: you should only use this option when you are on a fairly
   secure machine, because the superuser can read your muttrc even if you
   are the only one who can read the file.
 
 
-  6\b6.\b.3\b3.\b.9\b97\b7.\b.  p\bpo\bop\bp_\b_p\bpo\bor\brt\bt
+  6\b6.\b.3\b3.\b.1\b10\b03\b3.\b.  p\bpo\bop\bp_\b_p\bpo\bor\brt\bt
 
   Type: number
   Default: 110
-
   This variable specifies which port your POP server is listening on.
 
 
-  6\b6.\b.3\b3.\b.9\b98\b8.\b.  p\bpo\bop\bp_\b_u\bus\bse\ber\br
+  6\b6.\b.3\b3.\b.1\b10\b04\b4.\b.  p\bpo\bop\bp_\b_u\bus\bse\ber\br
 
   Type: string
   Default: login name on local system
 
-
   Your login name on the POP3 server.
 
 
-  6\b6.\b.3\b3.\b.9\b99\b9.\b.  p\bpo\bos\bst\bt_\b_i\bin\bnd\bde\ben\bnt\bt_\b_s\bst\btr\bri\bin\bng\bg
+  6\b6.\b.3\b3.\b.1\b10\b05\b5.\b.  p\bpo\bos\bst\bt_\b_i\bin\bnd\bde\ben\bnt\bt_\b_s\bst\btr\bri\bin\bng\bg
 
   Type: format string
   Default: none
   after the inclusion of a message which is being replied to.
 
 
-  6\b6.\b.3\b3.\b.1\b10\b00\b0.\b.  p\bpo\bos\bst\btp\bpo\bon\bne\be
+  6\b6.\b.3\b3.\b.1\b10\b06\b6.\b.  p\bpo\bos\bst\btp\bpo\bon\bne\be
 
   Type: quadoption
   Default: ask-yes
   mailbox when you elect not to send immediately.
 
 
-  6\b6.\b.3\b3.\b.1\b10\b01\b1.\b.  p\bpo\bos\bst\btp\bpo\bon\bne\bed\bd
+  6\b6.\b.3\b3.\b.1\b10\b07\b7.\b.  p\bpo\bos\bst\btp\bpo\bon\bne\bed\bd
 
   Type: string
   Default: ~/postponed
   variable.
 
 
-  6\b6.\b.3\b3.\b.1\b10\b02\b2.\b.  p\bpr\bri\bin\bnt\bt
+  6\b6.\b.3\b3.\b.1\b10\b08\b8.\b.  p\bpr\bri\bin\bnt\bt
 
   Type: quadoption
   Default: ask-no
   This is useful for people (like me) who accidentally hit ``p'' often.
 
 
-  6\b6.\b.3\b3.\b.1\b10\b03\b3.\b.  p\bpr\bri\bin\bnt\bt_\b_c\bco\bom\bmm\bma\ban\bnd\bd
+  6\b6.\b.3\b3.\b.1\b10\b09\b9.\b.  p\bpr\bri\bin\bnt\bt_\b_c\bco\bom\bmm\bma\ban\bnd\bd
 
   Type: string
   Default: lpr
   This specifies the command pipe that should be used to print messages.
 
 
-  6\b6.\b.3\b3.\b.1\b10\b04\b4.\b.  p\bpr\bro\bom\bmp\bpt\bt_\b_a\baf\bft\bte\ber\br
+  6\b6.\b.3\b3.\b.1\b11\b10\b0.\b.  p\bpr\bro\bom\bmp\bpt\bt_\b_a\baf\bft\bte\ber\br
 
   Type: boolean
   Default: set
   Mutt to prompt you for a command when the pager exits rather than
   returning to the index menu.  If unset, Mutt will return to the index
   menu when the external pager exits.
-
-
-  6\b6.\b.3\b3.\b.1\b10\b05\b5.\b.  q\bqu\bue\ber\bry\by_\b_c\bco\bom\bmm\bma\ban\bnd\bd
+  6\b6.\b.3\b3.\b.1\b11\b11\b1.\b.  q\bqu\bue\ber\bry\by_\b_c\bco\bom\bmm\bma\ban\bnd\bd
 
   Type: string
   Default: null
 
-
   This specifies the command that mutt will use to make external address
   queries.  The string should contain a %s, which will be substituted
   with the query string the user types.  See ``query'' for more
   information.
 
 
-  6\b6.\b.3\b3.\b.1\b10\b06\b6.\b.  q\bqu\bui\bit\bt
+  6\b6.\b.3\b3.\b.1\b11\b12\b2.\b.  q\bqu\bui\bit\bt
 
   Type: quadoption
   Default: yes
   prompted for confirmation when you try to quit.
 
 
-  6\b6.\b.3\b3.\b.1\b10\b07\b7.\b.  q\bqu\buo\bot\bte\be_\b_r\bre\beg\bge\bex\bxp\bp
+  6\b6.\b.3\b3.\b.1\b11\b13\b3.\b.  q\bqu\buo\bot\bte\be_\b_r\bre\beg\bge\bex\bxp\bp
 
   Type: string
   Default: "^([ \t]*[>|#:}])+"
   quote characters at the beginning of quoted lines.
 
 
-  6\b6.\b.3\b3.\b.1\b10\b08\b8.\b.  r\bre\bea\bad\bd_\b_i\bin\bnc\bc
+  6\b6.\b.3\b3.\b.1\b11\b14\b4.\b.  r\bre\bea\bad\bd_\b_i\bin\bnc\bc
 
   Type: number
   Default: 10
   Also see the ``$write_inc'' variable.
 
 
-  6\b6.\b.3\b3.\b.1\b10\b09\b9.\b.  r\bre\bea\bad\bd_\b_o\bon\bnl\bly\by
+  6\b6.\b.3\b3.\b.1\b11\b15\b5.\b.  r\bre\bea\bad\bd_\b_o\bon\bnl\bly\by
 
   Type: boolean
   Default: unset
   If set, all folders are opened in read-only mode.
 
 
-  6\b6.\b.3\b3.\b.1\b11\b10\b0.\b.  r\bre\bea\bal\bln\bna\bam\bme\be
+  6\b6.\b.3\b3.\b.1\b11\b16\b6.\b.  r\bre\bea\bal\bln\bna\bam\bme\be
 
   Type: string
   Default: GCOS field from /etc/passwd
   when sending messages.
 
 
-
-  6\b6.\b.3\b3.\b.1\b11\b11\b1.\b.  r\bre\bec\bca\bal\bll\bl
+  6\b6.\b.3\b3.\b.1\b11\b17\b7.\b.  r\bre\bec\bca\bal\bll\bl
 
   Type: quadoption
   Default: ask-yes
   when composing a new message.  Also see ``postponed''
 
 
-  6\b6.\b.3\b3.\b.1\b11\b12\b2.\b.  r\bre\bec\bco\bor\brd\bd
+  6\b6.\b.3\b3.\b.1\b11\b18\b8.\b.  r\bre\bec\bco\bor\brd\bd
 
   Type: string
   Default: none
   ``$save_name'' variables, and the ``fcc-hook'' command.
 
 
-  6\b6.\b.3\b3.\b.1\b11\b13\b3.\b.  r\bre\bep\bpl\bly\by_\b_r\bre\beg\bge\bex\bxp\bp
+  6\b6.\b.3\b3.\b.1\b11\b19\b9.\b.  r\bre\bep\bpl\bly\by_\b_r\bre\beg\bge\bex\bxp\bp
 
   Type: string
   Default: "^(re|aw):[ \t]*"
   the German "Aw:".
 
 
-  6\b6.\b.3\b3.\b.1\b11\b14\b4.\b.  r\bre\bep\bpl\bly\by_\b_t\bto\bo
+  6\b6.\b.3\b3.\b.1\b12\b20\b0.\b.  r\bre\bep\bpl\bly\by_\b_t\bto\bo
 
   Type: quadoption
   Default: ask-yes
   message to the author of a message.
 
 
-  6\b6.\b.3\b3.\b.1\b11\b15\b5.\b.  r\bre\bes\bso\bol\blv\bve\be
+  6\b6.\b.3\b3.\b.1\b12\b21\b1.\b.  r\bre\bes\bso\bol\blv\bve\be
 
   Type: boolean
   Default: set
   current message is executed.
 
 
-  6\b6.\b.3\b3.\b.1\b11\b16\b6.\b.  r\bre\bev\bve\ber\brs\bse\be_\b_a\bal\bli\bia\bas\bs
+  6\b6.\b.3\b3.\b.1\b12\b22\b2.\b.  r\bre\bev\bve\ber\brs\bse\be_\b_a\bal\bli\bia\bas\bs
 
   Type: boolean
   Default: unset
 
+
   This variable controls whether or not Mutt will display the "personal"
   name from your aliases in the index menu if it finds an alias that
   matches the message's sender.  For example, if you have the following
   alias:
 
+
+
        alias juser abd30425@somewhere.net (Joe User)
 
 
   address is not human friendly (like Compu$erve addresses).
 
 
-  6\b6.\b.3\b3.\b.1\b11\b17\b7.\b.  r\bre\bev\bve\ber\brs\bse\be_\b_n\bna\bam\bme\be
+  6\b6.\b.3\b3.\b.1\b12\b23\b3.\b.  r\bre\bev\bve\ber\brs\bse\be_\b_n\bna\bam\bme\be
 
   Type: boolean
   Default: unset
   line will use your address on the current machine.
 
 
-  6\b6.\b.3\b3.\b.1\b11\b18\b8.\b.  s\bsa\bav\bve\be_\b_a\bad\bdd\bdr\bre\bes\bss\bs
+  6\b6.\b.3\b3.\b.1\b12\b24\b4.\b.  s\bsa\bav\bve\be_\b_a\bad\bdd\bdr\bre\bes\bss\bs
 
   Type: boolean
   Default: unset
   is set too, the selection of the fcc folder will be changed as well.
 
 
-  6\b6.\b.3\b3.\b.1\b11\b19\b9.\b.  s\bsa\bav\bve\be_\b_e\bem\bmp\bpt\bty\by
+  6\b6.\b.3\b3.\b.1\b12\b25\b5.\b.  s\bsa\bav\bve\be_\b_e\bem\bmp\bpt\bty\by
 
   Type: boolean
   Default: set
   MH and Maildir directories.
 
 
-  6\b6.\b.3\b3.\b.1\b12\b20\b0.\b.  s\bsa\bav\bve\be_\b_n\bna\bam\bme\be
+  6\b6.\b.3\b3.\b.1\b12\b26\b6.\b.  s\bsa\bav\bve\be_\b_n\bna\bam\bme\be
 
   Type: boolean
   Default: unset
-
   This variable controls how copies of outgoing messages are saved.
   When set, a check is made to see if a mailbox specified by the
   recipient address exists (this is done by searching for a mailbox in
   Also see the ``$force_name'' variable.
 
 
-  6\b6.\b.3\b3.\b.1\b12\b21\b1.\b.  s\bse\ben\bnd\bdm\bma\bai\bil\bl
+  6\b6.\b.3\b3.\b.1\b12\b27\b7.\b.  s\bse\ben\bnd\bdm\bma\bai\bil\bl
 
   Type: string
   Default: /usr/lib/sendmail -oi -oem
 
   Specifies the program and arguments used to deliver mail sent by Mutt.
-  Mutt expects that the specified program will read the message header
-  for recipients.
+  Mutt expects that the specified program interprets additional
+  arguments as recipient addresses.
 
 
-  6\b6.\b.3\b3.\b.1\b12\b22\b2.\b.  s\bse\ben\bnd\bdm\bma\bai\bil\bl_\b_w\bwa\bai\bit\bt
+  6\b6.\b.3\b3.\b.1\b12\b28\b8.\b.  s\bse\ben\bnd\bdm\bma\bai\bil\bl_\b_w\bwa\bai\bit\bt
 
   Type: number
   Default: 0
   will be informed as to where to find the output.
 
 
-  6\b6.\b.3\b3.\b.1\b12\b23\b3.\b.  s\bsh\bhe\bel\bll\bl
+  6\b6.\b.3\b3.\b.1\b12\b29\b9.\b.  s\bsh\bhe\bel\bll\bl
 
   Type: string
   Default: retrieved from passwd file
   Command to use when spawning a subshell.
 
 
-  6\b6.\b.3\b3.\b.1\b12\b24\b4.\b.  s\bsi\big\bg_\b_d\bda\bas\bsh\bhe\bes\bs
+  6\b6.\b.3\b3.\b.1\b13\b30\b0.\b.  s\bsi\big\bg_\b_d\bda\bas\bsh\bhe\bes\bs
 
   Type: boolean
   Default: set
   the signature in a different color in the builtin pager.
 
 
-  6\b6.\b.3\b3.\b.1\b12\b25\b5.\b.  s\bsi\big\bgn\bna\bat\btu\bur\bre\be
+
+
+
+  6\b6.\b.3\b3.\b.1\b13\b31\b1.\b.  s\bsi\big\bgn\bna\bat\btu\bur\bre\be
 
   Type: string
   Default: ~/.signature
   outgoing messages.   If the filename ends with a pipe (``|''), it is
   assumed that filename is a shell command and input should be read from
   its stdout.
-  6\b6.\b.3\b3.\b.1\b12\b26\b6.\b.  s\bsi\bim\bmp\bpl\ble\be_\b_s\bse\bea\bar\brc\bch\bh
+
+
+  6\b6.\b.3\b3.\b.1\b13\b32\b2.\b.  s\bsi\bim\bmp\bpl\ble\be_\b_s\bse\bea\bar\brc\bch\bh
 
   Type: string
   Default: "~f %s | ~s %s"
 
   Specifies how Mutt should expand a simple search into a real search
   pattern.  A simple search is one that does not contain any of the ~
-  operators.  See ``searching'' for more information on search patterns.
+  operators.  See ``patterns'' for more information on search patterns.
 
   For example, if you simply type joe at a search or limit prompt, Mutt
   will automatically expand it to the value specified by this variable.
   ~f joe | ~s joe
 
 
-  6\b6.\b.3\b3.\b.1\b12\b27\b7.\b.  s\bsm\bma\bar\brt\bt_\b_w\bwr\bra\bap\bp
+  6\b6.\b.3\b3.\b.1\b13\b33\b3.\b.  s\bsm\bma\bar\brt\bt_\b_w\bwr\bra\bap\bp
 
   Type: boolean
   Default: set
   ``$markers'' variable.
 
 
-  6\b6.\b.3\b3.\b.1\b12\b28\b8.\b.  s\bso\bor\brt\bt
+  6\b6.\b.3\b3.\b.1\b13\b34\b4.\b.  s\bso\bor\brt\bt
 
   Type: string
   Default: date-sent
   order (example: set sort=reverse-date-sent).
 
 
-  6\b6.\b.3\b3.\b.1\b12\b29\b9.\b.  s\bso\bor\brt\bt_\b_a\bal\bli\bia\bas\bs
+  6\b6.\b.3\b3.\b.1\b13\b35\b5.\b.  s\bso\bor\brt\bt_\b_a\bal\bli\bia\bas\bs
 
   Type: string
   Default: alias
   Specifies how the entries in the `alias' menu are sorted.  The
   following are legal values:
 
-
-
-
   alias           sort alphabetically by alias name
   address         sort alphabetically by email address
   unsorted        leave in order specified in .muttrc
 
 
 
-  6\b6.\b.3\b3.\b.1\b13\b30\b0.\b.  s\bso\bor\brt\bt_\b_a\bau\bux\bx
+  6\b6.\b.3\b3.\b.1\b13\b36\b6.\b.  s\bso\bor\brt\bt_\b_a\bau\bux\bx
 
   Type: string
   Default: date-sent
   you have set sort=reverse-threads.)
 
 
-  6\b6.\b.3\b3.\b.1\b13\b31\b1.\b.  s\bso\bor\brt\bt_\b_b\bbr\bro\bow\bws\bse\ber\br
+  6\b6.\b.3\b3.\b.1\b13\b37\b7.\b.  s\bso\bor\brt\bt_\b_b\bbr\bro\bow\bws\bse\ber\br
 
   Type: string
 
   order (example: set sort_browser=reverse-date).
 
 
-  6\b6.\b.3\b3.\b.1\b13\b32\b2.\b.  s\bsp\bpo\boo\bol\blf\bfi\bil\ble\be
+  6\b6.\b.3\b3.\b.1\b13\b38\b8.\b.  s\bsp\bpo\boo\bol\blf\bfi\bil\ble\be
 
   Type: string
   Default: most likely /var/mail/$USER or /usr/spool/mail/$USER
   variable $MAIL if it is not set.
 
 
-  6\b6.\b.3\b3.\b.1\b13\b33\b3.\b.  s\bso\bor\brt\bt_\b_r\bre\be
+  6\b6.\b.3\b3.\b.1\b13\b39\b9.\b.  s\bso\bor\brt\bt_\b_r\bre\be
 
   Type: boolean Default: set
 
   non-``reply_regexp'' parts of both messages are identical.
 
 
-  6\b6.\b.3\b3.\b.1\b13\b34\b4.\b.  s\bst\bta\bat\btu\bus\bs_\b_c\bch\bha\bar\brs\bs
+  6\b6.\b.3\b3.\b.1\b14\b40\b0.\b.  s\bst\bta\bat\btu\bus\bs_\b_c\bch\bha\bar\brs\bs
 
   Type: string
   Default: "-*%"
   with the toggle-write operation, bound by default to "%").
 
 
-  6\b6.\b.3\b3.\b.1\b13\b35\b5.\b.  s\bst\bta\bat\btu\bus\bs_\b_f\bfo\bor\brm\bma\bat\bt
+  6\b6.\b.3\b3.\b.1\b14\b41\b1.\b.  s\bst\bta\bat\btu\bus\bs_\b_f\bfo\bor\brm\bma\bat\bt
 
   Type: string
   Default: "-%r-Mutt: %f [Msgs:%?M?%M/?%m%?n? New:%n?%?o? Old:%o?%?d?
 
                %?<sequence_char>?<optional_string>?
 
+
+
+
   where _\bs_\be_\bq_\bu_\be_\bn_\bc_\be_\b__\bc_\bh_\ba_\br is a character from the table above, and
   _\bo_\bp_\bt_\bi_\bo_\bn_\ba_\bl_\b__\bs_\bt_\br_\bi_\bn_\bg is the string you would like printed if _\bs_\bt_\ba_\bt_\bu_\bs_\b__\bc_\bh_\ba_\br is
   nonzero.  _\bo_\bp_\bt_\bi_\bo_\bn_\ba_\bl_\b__\bs_\bt_\br_\bi_\bn_\bg m\bma\bay\by contain other sequence as well as normal
 
 
 
+  Additionally you can switch between two strings, the first one, if a
+  value is zero, the second one, if the value is nonzero, by using the
+  following construct:
+
+
+
+               %?<sequence_char>?<if_string>&<else_string>?
+
+
+
+
 
-  6\b6.\b.3\b3.\b.1\b13\b36\b6.\b.  s\bst\bta\bat\btu\bus\bs_\b_o\bon\bn_\b_t\bto\bop\bp
+  6\b6.\b.3\b3.\b.1\b14\b42\b2.\b.  s\bst\bta\bat\btu\bus\bs_\b_o\bon\bn_\b_t\bto\bop\bp
 
   Type: boolean
   Default: unset
   first line of the screen rather than near the bottom.
 
 
-  6\b6.\b.3\b3.\b.1\b13\b37\b7.\b.  s\bst\btr\bri\bic\bct\bt_\b_t\bth\bhr\bre\bea\bad\bds\bs
+  6\b6.\b.3\b3.\b.1\b14\b43\b3.\b.  s\bst\btr\bri\bic\bct\bt_\b_t\bth\bhr\bre\bea\bad\bds\bs
 
   Type: boolean
   Default: unset
   the subject ``hi'' which will get grouped together.
 
 
-  6\b6.\b.3\b3.\b.1\b13\b38\b8.\b.  s\bsu\bus\bsp\bpe\ben\bnd\bd
+  6\b6.\b.3\b3.\b.1\b14\b44\b4.\b.  s\bsu\bus\bsp\bpe\ben\bnd\bd
 
   Type: boolean
   Default: set
 
+
   When _\bu_\bn_\bs_\be_\bt, mutt won't stop when the user presses the terminal's _\bs_\bu_\bs_\bp
   key, usually ``control-Z''. This is useful if you run mutt inside an
   xterm using a command like xterm -e mutt.
 
 
-  6\b6.\b.3\b3.\b.1\b13\b39\b9.\b.  t\bth\bho\bor\bro\bou\bug\bgh\bh_\b_s\bse\bea\bar\brc\bch\bh
+  6\b6.\b.3\b3.\b.1\b14\b45\b5.\b.  t\bth\bho\bor\bro\bou\bug\bgh\bh_\b_s\bse\bea\bar\brc\bch\bh
 
   Type: boolean
   Default: unset
 
   Affects the _\b~_\bb and _\b~_\bh search operations described in section
-  ``Searching'' above.  If set, the headers and attachments of messages
+  ``patterns'' above.  If set, the headers and attachments of messages
   to be searched are decoded before searching.  If unset, messages are
   searched as they appear in the folder.
 
 
-  6\b6.\b.3\b3.\b.1\b14\b40\b0.\b.  t\bti\bil\bld\bde\be
+  6\b6.\b.3\b3.\b.1\b14\b46\b6.\b.  t\bti\bil\bld\bde\be
 
   Type: boolean
   Default: unset
 
   When set, the internal-pager will pad blank lines to the bottom of the
   screen with a tilde (~).
-  6\b6.\b.3\b3.\b.1\b14\b41\b1.\b.  t\bti\bim\bme\beo\bou\but\bt
+
+
+  6\b6.\b.3\b3.\b.1\b14\b47\b7.\b.  t\bti\bim\bme\beo\bou\but\bt
 
   Type: number
   Default: 600
   mail.  A value of zero or less will cause Mutt not to ever time out.
 
 
-  6\b6.\b.3\b3.\b.1\b14\b42\b2.\b.  t\btm\bmp\bpd\bdi\bir\br
+  6\b6.\b.3\b3.\b.1\b14\b48\b8.\b.  t\btm\bmp\bpd\bdi\bir\br
 
   Type: string
   Default: /tmp
   temporary files needed for displaying and composing messages.
 
 
-  6\b6.\b.3\b3.\b.1\b14\b43\b3.\b.  t\bto\bo_\b_c\bch\bha\bar\brs\bs
+  6\b6.\b.3\b3.\b.1\b14\b49\b9.\b.  t\bto\bo_\b_c\bch\bha\bar\brs\bs
 
   Type: string
   Default: " +TCF"
   by _\by_\bo_\bu.
 
 
-  6\b6.\b.3\b3.\b.1\b14\b44\b4.\b.  u\bus\bse\be_\b_8\b8b\bbi\bit\btm\bmi\bim\bme\be
+  6\b6.\b.3\b3.\b.1\b15\b50\b0.\b.  u\bus\bse\be_\b_8\b8b\bbi\bit\btm\bmi\bim\bme\be
 
   Type: boolean
   Default: unset
 
+
   W\bWa\bar\brn\bni\bin\bng\bg:\b: do not set this variable unless you are using a version of
   sendmail which supports the -B8BITMIME flag (such as sendmail 8.8.x)
   or you may not be able to send mail.
   sending 8-bit messages to enable ESMTP negotiation.
 
 
-  6\b6.\b.3\b3.\b.1\b14\b45\b5.\b.  u\bus\bse\be_\b_d\bdo\bom\bma\bai\bin\bn
+  6\b6.\b.3\b3.\b.1\b15\b51\b1.\b.  u\bus\bse\be_\b_d\bdo\bom\bma\bai\bin\bn
 
   Type: boolean
   Default: set
   addresses will be qualified.
 
 
-  6\b6.\b.3\b3.\b.1\b14\b46\b6.\b.  u\bus\bse\be_\b_f\bfr\bro\bom\bm
+  6\b6.\b.3\b3.\b.1\b15\b52\b2.\b.  u\bus\bse\be_\b_f\bfr\bro\bom\bm
 
   Type: boolean
   Default: set
   When _\bs_\be_\bt, Mutt will generate the `From:' header field when sending
   messages.  If _\bu_\bn_\bs_\be_\bt, no `From:' header field will be generated unless
   the user explicitly sets one using the ``my_hdr'' command.
-  6\b6.\b.3\b3.\b.1\b14\b47\b7.\b.  u\bus\bse\be_\b_m\bma\bai\bil\blc\bca\bap\bp
+
+
+  6\b6.\b.3\b3.\b.1\b15\b53\b3.\b.  u\bus\bse\be_\b_m\bma\bai\bil\blc\bca\bap\bp
 
   Type: quad-option
   Default: ask
   display MIME parts without prompting the user for confirmation.
 
 
-  6\b6.\b.3\b3.\b.1\b14\b48\b8.\b.  p\bpg\bgp\bp_\b_v\bve\ber\bri\bif\bfy\by_\b_s\bsi\big\bg
+  6\b6.\b.3\b3.\b.1\b15\b54\b4.\b.  p\bpg\bgp\bp_\b_v\bve\ber\bri\bif\bfy\by_\b_s\bsi\big\bg
 
   Type: quad-option
   Default: yes
   to verify PGP/MIME signatures.
 
 
-  6\b6.\b.3\b3.\b.1\b14\b49\b9.\b.  v\bvi\bis\bsu\bua\bal\bl
+  6\b6.\b.3\b3.\b.1\b15\b55\b5.\b.  v\bvi\bis\bsu\bua\bal\bl
 
   Type: string
   Default: $VISUAL
   the builtin editor.
 
 
-  6\b6.\b.3\b3.\b.1\b15\b50\b0.\b.  w\bwa\bai\bit\bt_\b_k\bke\bey\by
+
+  6\b6.\b.3\b3.\b.1\b15\b56\b6.\b.  w\bwa\bai\bit\bt_\b_k\bke\bey\by
 
   Type: boolean
   Default: set
   for a key only if the external command returned a non-zero status.
 
 
-  6\b6.\b.3\b3.\b.1\b15\b51\b1.\b.  w\bwr\bra\bap\bp_\b_s\bse\bea\bar\brc\bch\bh
+  6\b6.\b.3\b3.\b.1\b15\b57\b7.\b.  w\bwr\bra\bap\bp_\b_s\bse\bea\bar\brc\bch\bh
 
   Type: boolean
   Default: set
   unset, searches will not wrap.
 
 
-
-
-  6\b6.\b.3\b3.\b.1\b15\b52\b2.\b.  w\bwr\bri\bit\bte\be_\b_i\bin\bnc\bc
+  6\b6.\b.3\b3.\b.1\b15\b58\b8.\b.  w\bwr\bri\bit\bte\be_\b_i\bin\bnc\bc
 
   Type: number
   Default: 10
   Also see the ``$read_inc'' variable.
 
 
+  6\b6.\b.3\b3.\b.1\b15\b59\b9.\b.  w\bwr\bri\bit\bte\be_\b_b\bbc\bcc\bc
+
+  Type: boolean
+  Default: set
+
+  Controls whether mutt writes out the Bcc header when preparing
+  messages to be sent.  Exim users may wish to use this.
+
+
   6\b6.\b.4\b4.\b.  F\bFu\bun\bnc\bct\bti\bio\bon\bns\bs
 
   The following is the list of available functions listed by the mapping
   all menus (except as noted).
 
 
+
   bottom-page                L   move to the bottom of the page
   current-bottom     not bound   move current entry to bottom of page
   current-middle     not bound   move current entry to middle of page
 
 
 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
   bounce-message             b   remail a message to another user
   change-folder              c   open a different folder
   change-folder-readonly ESC c   open a different folder in read only mode
 
   7\b7.\b.1\b1.\b.  A\bAc\bck\bkn\bno\bow\bwl\ble\bed\bdg\bge\bem\bme\ben\bnt\bts\bs
 
-  Kari Hurrta <kari.hurtta@fmi.fi> co-developed the original MIME
+  Kari Hurtta <kari.hurtta@fmi.fi> co-developed the original MIME
   parsing code back in the ELM-ME days.
 
   The following people have been very helpful to the development of
similarity index 64%
rename from doc/mutt.man
rename to doc/mutt.man.in
index 7fcc3ced89e4da947ed2bf79093b9a070c5c3579..d46fb938e9f634822149c2cb1bee0628037ddd99 100644 (file)
-.if n .ds Q \&"
-.if t .ds Q ``
-.if n .ds U \&"
-.if t .ds U ''
-.TH "Mutt" 1 
-.tr \a\&
-.nr bi 0
-.nr ll 0
-.nr el 0
-.de DS
-..
-.de DE
-..
-.de Pp
-.ie \\n(ll>0 \{\
-.ie \\n(bi=1 \{\
-.nr bi 0
-.if \\n(t\\n(ll=0 \{.IP \\(bu\}
-.if \\n(t\\n(ll=1 \{.IP \\n+(e\\n(el.\}
-.\}
-.el .sp 
-.\}
-.el \{\
-.ie \\nh=1 \{\
-.LP
-.nr h 0
-.\}
-.el .PP 
-.\}
-..
+.\" -*-nroff-*-
+.\"
+.\"
+.\"     Copyright (C) 1996-8 Michael R. Elkins <me@cs.hmc.edu>
+.\" 
+.\"     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.
+.\"
+.TH mutt 1 "JULY 1998" Unix "User Manuals"
 .SH NAME
-
-.Pp
-mutt - The Mutt Mail User Agent
-.Pp
+.PP
+mutt \- The Mutt Mail User Agent
 .SH SYNOPSIS
-
-.Pp
-mutt [ -hnpRvxyzZ ]
-[ -a \fIfile\fP ]
-[ -b \fIaddress\fP ]
-[ -c \fIaddress\fP ]
-[ -e \fIcommand\fP ]
-[ -f \fImailbox\fP ]
-[ -F \fImuttrc\fP ]
-[ -H \fIdraftfile\fP ]
-[ -i \fIinclude\fP ]
-[ -m \fItype\fP ]
-[ -s \fIsubject\fP ]
-[ \fIaddress\fP ... ]
-.Pp
+.PP
+.B mutt 
+[-hnpRvxyzZ]
+[-a \fIfile\fP]
+[-b \fIaddress\fP]
+[-c \fIaddress\fP]
+[-e \fIcommand\fP]
+[-f \fImailbox\fP]
+[-F \fImuttrc\fP]
+[-H \fIdraftfile\fP]
+[-i \fIinclude\fP]
+[-m \fItype\fP]
+[-s \fIsubject\fP]
 .SH DESCRIPTION
-
-.Pp
+.PP
 Mutt is a small but very powerful text based program for reading electronic
 mail under unix operating systems, including support color terminals, MIME,
 and a threaded sorting mode.
-.Pp
 .SH OPTIONS
-
-.Pp
-.nr ll +1
-.nr t\n(ll 2
-.if \n(ll>1 .RS
+.PP
 .IP "-a \fIfile\fP"
-.nr bi 1
-.Pp
 Attach a file to your message using MIME.
 .IP "-b \fIaddress\fP"
-.nr bi 1
-.Pp
 Specify a blind-carbon-copy (BCC) recipient
 .IP "-c \fIaddress\fP"
-.nr bi 1
-.Pp
 Specify a carbon-copy (CC) recipient
 .IP "-e \fIcommand\fP"
-.nr bi 1
-.Pp
 Specify a configuration command to be run after processing of initialization
 files.
 .IP "-f \fImailbox\fP"
-.nr bi 1
-.Pp
 Specify which mailbox to load.
 .IP "-F \fImuttrc\fP"
-.nr bi 1
-.Pp
 Specify an initialization file to read instead of ~/.muttrc
 .IP "-h"
-.nr bi 1
-.Pp
 Display help.
 .IP "-H \fIdraft\fP"
-.nr bi 1
-.Pp
 Specify a draft file which contains header and body to use to send a
 message.
 .IP "-i \fIinclude\fP"
-.nr bi 1
-.Pp
 Specify a file to include into the body of a message.
-.IP "-m \fItype\fP "
-.nr bi 1
-.Pp
+.IP "-m \fItype\fP       "
 specify a default mailbox type
 .IP "-n"
-.nr bi 1
-.Pp
 Causes Mutt to bypass the system configuration file.
 .IP "-p"
-.nr bi 1
-.Pp
 Resume a postponed message.
 .IP "-R"
-.nr bi 1
-.Pp
 Open a mailbox in \fIread-only\fP mode.
 .IP "-s \fIsubject\fP"
-.nr bi 1
-.Pp
 Specify the subject of the message.
 .IP "-v"
-.nr bi 1
-.Pp
 Display the Mutt version number and compile-time definitions.
 .IP "-x"
-.nr bi 1
-.Pp
 Emulate the mailx compose mode.
 .IP "-y"
-.nr bi 1
-.Pp
 Start Mutt with a listing of all mailboxes specified by the \fImailboxes\fP
 command.
 .IP "-z"
-.nr bi 1
-.Pp
 When used with -f, causes Mutt not to start if there are no messages in the
 mailbox.
 .IP "-Z"
-.nr bi 1
-.Pp
 Causes Mutt to open the first mailbox specified by the \fImailboxes\fP
 command which contains new mail.
-.if \n(ll>1 .RE
-.nr ll -1
-.Pp
 .SH ENVIRONMENT
-
-.Pp
-.nr ll +1
-.nr t\n(ll 2
-.if \n(ll>1 .RS
+.PP
 .IP "EDITOR"
-.nr bi 1
-.Pp
 Editor to invoke when composing a message.
 .IP "HOME"
-.nr bi 1
-.Pp
 Full path of the user's home directory.
 .IP "MAIL"
-.nr bi 1
-.Pp
 Full path of the user's spool mailbox.
 .IP "MAILCAPS"
-.nr bi 1
-.Pp
 Path to search for mailcap files.
 .IP "MM_NOASK"
-.nr bi 1
-.Pp
 If this variable is set, mailcap are always used without prompting first.
 .IP "PGPPATH"
-.nr bi 1
-.Pp
 Directory in which the user's PGP public keyring can be found.
 .IP "TMPDIR"
-.nr bi 1
-.Pp
 Directory in which temporary files are created.
 .IP "REPLYTO"
-.nr bi 1
-.Pp
 Default Reply-To address.
 .IP "VISUAL"
-.nr bi 1
-.Pp
 Editor to invoke when the ~v command is given in the builtin editor.
-.if \n(ll>1 .RE
-.nr ll -1
-.Pp
 .SH FILES
-
-.Pp
-.nr ll +1
-.nr t\n(ll 2
-.if \n(ll>1 .RS
+.PP
 .IP "~/.muttrc"
-.nr bi 1
-.Pp
 User configuration file.
-.IP "/usr/local/share/Muttrc"
-.nr bi 1
-.Pp
+.IP "@sharedir@/Muttrc"
 System-wide configuration file.
 .IP "/tmp/muttXXXXXX"
-.nr bi 1
-.Pp
 Temporary files created by Mutt.
 .IP "~/.mailcap"
-.nr bi 1
-.Pp
 User definition for handling non-text MIME types.
-.IP "/usr/local/share/mailcap"
-.nr bi 1
-.Pp
+.IP "@sharedir@/mailcap"
 System definition for handing non-text MIME types.
 .IP "~/.mime.types"
-.nr bi 1
-.Pp
 User's personal mapping between MIME types and file extensions.
-.IP "/usr/local/share/mime.types"
-.nr bi 1
-.Pp
+.IP "@sharedir@/mime.types"
 System mapping between MIME types and file extensions.
-.Pp
-.if \n(ll>1 .RE
-.nr ll -1
-.Pp
+.IP "@libdir@/dotlock"
+The privileged dotlocking program.
 .SH BUGS
-
-.Pp
-suspend/resume while editing a file with an external editor does not work
+.PP
+Suspend/resume while editing a file with an external editor does not work
 under SunOS 4.x if you use the curses lib in /usr/5lib.  It \fIdoes\fP work
 with the S-Lang library, however.
-.Pp
+.PP
 Resizing the screen while using an external pager causes Mutt to go haywire
 on some systems.
-.Pp
+.PP
 suspend/resume does not work under Ultrix.
-.Pp
+.PP
 The help line for the index menu is not updated if you change the bindings
 for one of the functions listed while Mutt is running.
-.Pp
 .SH SEE ALSO
-
-.Pp
-curses(3), ncurses(3), sendmail(1), smail(1), mailcap(5)
-.Pp
+.PP
+.BR curses (3),
+.BR dotlock (1),
+.BR ncurses (3),
+.BR sendmail (1),
+.BR smail (1),
+.BR mailcap (5)
+.PP
 Mutt Home Page: http://www.cs.hmc.edu/~me/mutt/
-.Pp
 .SH AUTHOR
-
-.Pp
 Michael Elkins <me@cs.hmc.edu>
-.Pp
-http://www.cs.hmc.edu/~me
\ No newline at end of file
+http://www.cs.hmc.edu/~me/
diff --git a/dotlock.c b/dotlock.c
new file mode 100644 (file)
index 0000000..0b978fd
--- /dev/null
+++ b/dotlock.c
@@ -0,0 +1,714 @@
+/*
+ * Copyright (C) 1996-8 Michael R. Elkins <me@cs.hmc.edu>
+ * Copyright (C) 1998 Thomas Roessler <roessler@guug.de>
+ * 
+ *     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.
+ */ 
+
+/*
+ * This module either be compiled into Mutt, or it can be
+ * built as a separate program. For building it
+ * separately, define the DL_STANDALONE preprocessor
+ * macro.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <unistd.h>
+#include <dirent.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <sys/utsname.h>
+#include <errno.h>
+#include <time.h>
+#include <fcntl.h>
+#include <limits.h>
+
+#ifndef _POSIX_PATH_MAX
+#include <posix1_lim.h>
+#endif
+
+#include "dotlock.h"
+#include "config.h"
+
+#ifdef DL_STANDALONE
+#include "reldate.h"
+#endif
+
+# define MAXLINKS 1024 /* maximum link depth */
+
+# ifdef DL_STANDALONE
+
+# define LONG_STRING 1024
+# define MAXLOCKATTEMPT 5
+
+# define strfcpy(A,B,C) strncpy(A,B,C), *(A+(C)-1)=0
+
+# ifdef USE_SETGID
+
+#  ifdef HAVE_SETEGID
+#   define SETEGID setegid
+#  else
+#   define SETEGID setgid
+#  endif
+#  ifndef S_ISLNK
+#   define S_ISLNK(x) (((x) & S_IFMT) == S_IFLNK ? 1 : 0)
+#  endif
+
+# endif
+
+# ifndef HAVE_SNPRINTF
+extern int snprintf(char *, size_t, const char *, ...);
+# endif
+
+#else  /* DL_STANDALONE */
+
+# ifdef USE_SETGID
+#  error Do not try to compile dotlock as a mutt module when requiring egid switching!
+# endif
+
+# include "mutt.h"
+# include "mx.h"
+
+#endif /* DL_STANDALONE */
+
+static short f_try = 0;
+static short f_force = 0;
+static short f_unlock = 0;
+static short f_priv = 0;
+static int   Retry = MAXLOCKATTEMPT;
+
+#ifdef DL_STANDALONE
+static char *Hostname;
+#endif
+
+#ifdef USE_SETGID
+static gid_t UserGid;
+static gid_t MailGid;
+#endif
+
+static int dotlock_deference_symlink(char *, size_t, const char *);
+static int dotlock_prepare(char *, size_t, const char *);
+
+#ifdef DL_STANDALONE
+static int dotlock_init_privs(void);
+static void usage(const char *);
+#endif
+
+static void dotlock_expand_link(char *, const char *, const char *);
+static void BEGIN_PRIVILEGED(void);
+static void END_PRIVILEGED(void);
+
+/* These functions work on the current directory.
+ * Invoke dotlock_prepare() before and check their
+ * return value.
+ */
+
+static int dotlock_try(void);
+static int dotlock_unlock(const char *);
+static int dotlock_lock(const char *);
+
+
+#ifdef DL_STANDALONE
+
+int main(int argc, char **argv)
+{
+  int i;
+  char *p;
+  const char *f;
+  struct utsname utsname;
+  char realpath[_POSIX_PATH_MAX];
+
+
+  /* first, drop privileges */
+  
+  if(dotlock_init_privs() == -1)
+    return DL_EX_ERROR;
+
+
+  /* determine the system's host name */
+  
+  uname(&utsname);
+  if(!(Hostname = strdup(utsname.nodename)))
+    return DL_EX_ERROR;
+  if((p = strchr(Hostname, '.')))
+    *p = '\0';
+
+
+  /* parse the command line options. */
+  
+  while((i = getopt(argc, argv, "tfupr:")) != EOF)
+  {
+    switch(i)
+    {
+      case 't': f_try = 1; break;
+      case 'f': f_force = 1; break;
+      case 'u': f_unlock = 1; break;
+      case 'p': f_priv = 1; break;
+      case 'r': Retry = atoi(optarg); break;
+      default: usage(argv[0]);
+    }
+  }
+
+  if(optind == argc || f_try + f_force + f_unlock > 1 || Retry < 0)
+    usage(argv[0]);
+  
+  f = argv[optind];
+
+
+  /* If dotlock_prepare() succeeds [return value == 0],
+   * realpath contains the basename of f, and we have
+   * successfully changed our working directory to
+   * `dirname $f`.  Additionally, f has been opened for
+   * reading to verify that the user has at least read
+   * permissions on that file.
+   * 
+   * For a more detailed explanation of all this, see the
+   * lengthy comment below.
+   */
+  
+  if(dotlock_prepare(realpath, sizeof(realpath), f) != 0)
+    return DL_EX_ERROR;
+
+  /* Finally, actually perform the locking operation. */
+  
+  if(f_try)
+    return dotlock_try();
+  else if(f_unlock)
+    return dotlock_unlock(realpath);
+  else /* lock */
+    return dotlock_lock(realpath);
+
+}
+
+/* 
+ * Determine our effective group ID, and drop 
+ * privileges.
+ * 
+ * Return value:
+ * 
+ *  0 - everything went fine
+ * -1 - we couldn't drop privileges.
+ * 
+ */
+
+
+static int
+dotlock_init_privs(void)
+{
+
+# ifdef USE_SETGID
+  
+  UserGid = getgid();
+  MailGid = getegid();
+
+  if(SETEGID(UserGid) != 0)
+    return -1;
+
+# endif
+
+  return 0;
+}
+  
+
+#else  /* DL_STANDALONE */
+
+/* 
+ * This function is intended to be invoked from within
+ * mutt instead of mx.c's invoke_dotlock().
+ * 
+ */
+
+int dotlock_invoke(const char *path, int flags, int retry)
+{
+  int currdir;
+  int r;
+  char realpath[_POSIX_PATH_MAX];
+  
+  if((currdir = open(".", O_RDONLY)) == -1)
+    return DL_EX_ERROR;
+  
+  if(!(flags & DL_FL_RETRY) || retry)
+    Retry = MAXLOCKATTEMPT;
+  else
+    Retry = 0;
+  
+  f_priv = f_try = f_unlock = f_force = 0;
+  
+  if(flags & DL_FL_FORCE)
+    f_force = 1;
+
+  r = DL_EX_ERROR;
+  if(dotlock_prepare(realpath, sizeof(realpath), path) == -1)
+    goto bail;
+  
+  if(flags & DL_FL_TRY)
+    r = dotlock_try();
+  else if(flags & DL_FL_UNLOCK)
+    r = dotlock_unlock(realpath);
+  else /* lock */
+    r = dotlock_lock(realpath);
+  
+ bail:
+  
+  fchdir(currdir);
+  close(currdir);
+  
+  return r;
+}
+    
+#endif  /* DL_STANDALONE */
+  
+  
+/*
+ * Get privileges 
+ * 
+ * This function re-acquires the privileges we may have
+ * if the user told us to do so by giving the "-p"
+ * command line option.
+ * 
+ * BEGIN_PRIVILEGES() won't return if an error occurs.
+ * 
+ */
+
+static void
+BEGIN_PRIVILEGED(void)
+{
+#ifdef USE_SETGID
+  if(f_priv)
+  {
+    if(SETEGID(MailGid) != 0)
+    {
+      /* perror("setegid"); */
+      exit(DL_EX_ERROR);
+    }
+  }
+#endif
+}
+
+/*
+ * Drop privileges
+ * 
+ * This function drops the group privileges we may have.
+ * 
+ * END_PRIVILEGED() won't return if an error occurs.
+ *
+ */
+
+static void
+END_PRIVILEGED(void)
+{
+#ifdef USE_SETGID
+  if(f_priv)
+  {
+    if(SETEGID(UserGid) != 0)
+    {
+      /* perror("setegid"); */
+      exit(DL_EX_ERROR);
+    }
+  }
+#endif
+}
+
+#ifdef DL_STANDALONE
+
+/*
+ * Usage information.
+ * 
+ * This function doesn't return.
+ * 
+ */
+
+static void 
+usage(const char *av0)
+{
+  fprintf(stderr, "dotlock [Mutt %s (%s)]\n", VERSION, ReleaseDate);
+  fprintf(stderr, "usage: %s [-t|-f|-u] [-p] [-r <retries>] file\n",
+         av0);
+
+  fputs("\noptions:"
+       "\n  -t\t\ttry"
+       "\n  -f\t\tforce"
+       "\n  -u\t\tunlock"
+       "\n  -p\t\tprivileged"
+#ifndef USE_SETGID
+       " (ignored)"
+#endif
+       "\n  -r <retries>\tRetry locking"
+       "\n", stderr);
+  
+  exit(DL_EX_ERROR);
+}
+
+#endif
+
+/*
+ * Access checking: Let's avoid to lock other users' mail
+ * spool files if we aren't permitted to read them.
+ * 
+ * Some simple-minded access(2) checking isn't sufficient
+ * here: The problem is that the user may give us a
+ * deeply nested path to a file which has the same name
+ * as the file he wants to lock, but different
+ * permissions, say, e.g.
+ * /tmp/lots/of/subdirs/var/spool/mail/root.
+ * 
+ * He may then try to replace /tmp/lots/of/subdirs by a
+ * symbolic link to / after we have invoked access() to
+ * check the file's permissions.  The lockfile we'd
+ * create or remove would then actually be
+ * /var/spool/mail/root.
+ * 
+ * To avoid this attack, we proceed as follows:
+ * 
+ * - First, follow symbolic links a la
+ *   dotlock_deference_symlink().
+ * 
+ * - get the result's dirname.
+ * 
+ * - chdir to this directory.  If you can't, bail out.
+ * 
+ * - try to open the file in question, only using its
+ *   basename.  If you can't, bail out.
+ * 
+ * - fstat that file and compare the result to a
+ *   subsequent lstat (only using the basename).  If
+ *   the comparison fails, bail out.
+ * 
+ * dotlock_prepare() is invoked from main() directly
+ * after the command line parsing has been done.
+ *
+ * Return values:
+ * 
+ * 0 - Evereything's fine.  The program's new current
+ *     directory is the contains the file to be locked.
+ *     The string pointed to by bn contains the name of
+ *     the file to be locked.
+ * 
+ * -1 - Something failed. Don't continue.
+ * 
+ * tlr, Jul 15 1998
+ */
+
+static int
+dotlock_prepare(char *bn, size_t l, const char *f)
+{
+  struct stat fsb, lsb;
+  char realpath[_POSIX_PATH_MAX];
+  char *basename, *dirname;
+  char *p;
+  int fd;
+  int r;
+  
+  if(dotlock_deference_symlink(realpath, sizeof(realpath), f) == -1)
+    return -1;
+  
+  if((p = strrchr(realpath, '/')))
+  {
+    *p = '\0';
+    basename = p + 1;
+    dirname = realpath;
+  }
+  else
+  {
+    basename = realpath;
+    dirname = ".";
+  }
+
+  if(strlen(basename) + 1 > l)
+    return -1;
+  
+  strfcpy(bn, basename, l);
+  
+  if(chdir(dirname) == -1)
+    return -1;
+  
+  if((fd = open(basename, O_RDONLY)) == -1)
+    return -1;
+  
+  r = fstat(fd, &fsb);
+  close(fd);
+  
+  if(r == -1)
+    return -1;
+  
+  if(lstat(basename, &lsb) == -1)
+    return -1;
+  
+  if(S_ISLNK(lsb.st_mode))
+    return -1;
+  
+  if((lsb.st_dev != fsb.st_dev) ||
+     (lsb.st_ino != fsb.st_ino) ||
+     (lsb.st_mode != fsb.st_mode) ||
+     (lsb.st_nlink != fsb.st_nlink) ||
+     (lsb.st_uid != fsb.st_uid) ||
+     (lsb.st_gid != fsb.st_gid) ||
+     (lsb.st_rdev != fsb.st_rdev) ||
+     (lsb.st_size != fsb.st_size))
+  {
+    /* something's fishy */
+    return -1;
+  }
+  
+  return 0;
+}
+
+/*
+ * Expand a symbolic link.
+ * 
+ * This function expects newpath to have space for
+ * at least _POSIX_PATH_MAX characters.
+ *
+ */
+
+static void 
+dotlock_expand_link (char *newpath, const char *path, const char *link)
+{
+  const char *lb = NULL;
+  size_t len;
+
+  /* link is full path */
+  if (*link == '/')
+  {
+    strfcpy (newpath, link, _POSIX_PATH_MAX);
+    return;
+  }
+
+  if ((lb = strrchr (path, '/')) == NULL)
+  {
+    /* no path in link */
+    strfcpy (newpath, link, _POSIX_PATH_MAX);
+    return;
+  }
+
+  len = lb - path + 1;
+  memcpy (newpath, path, len);
+  strfcpy (newpath + len, link, _POSIX_PATH_MAX - len);
+}
+
+
+/*
+ * Deference a chain of symbolic links
+ * 
+ * The final path is written to d.
+ *
+ */
+
+static int
+dotlock_deference_symlink(char *d, size_t l, const char *path)
+{
+  struct stat sb;
+  char realpath[_POSIX_PATH_MAX];
+  const char *pathptr = path;
+  int count = 0;
+  
+  while(count++ < MAXLINKS)
+  {
+    if(lstat(pathptr, &sb) == -1)
+    {
+      /* perror(pathptr); */
+      return -1;
+    }
+    
+    if(S_ISLNK (sb.st_mode))
+    {
+      char linkfile[_POSIX_PATH_MAX];
+      char linkpath[_POSIX_PATH_MAX];
+      int len;
+
+      if((len = readlink(pathptr, linkfile, sizeof(linkfile))) == -1)
+      {
+       /* perror(pathptr); */
+       return -1;
+      }
+      
+      linkfile[len] = '\0';
+      dotlock_expand_link(linkpath, pathptr, linkfile);
+      strfcpy(realpath, linkpath, sizeof(realpath));
+      pathptr = realpath;
+    }
+    else
+      break;
+  }
+
+  strfcpy(d, pathptr, l);
+  return 0;
+}
+
+/*
+ * Dotlock a file.
+ * 
+ * realpath is assumed _not_ to be an absolute path to
+ * the file we are about to lock.  Invoke
+ * dotlock_prepare() before using this function!
+ * 
+ */
+
+static int
+dotlock_lock(const char *realpath)
+{
+  char lockfile[_POSIX_PATH_MAX + LONG_STRING];
+  char nfslockfile[_POSIX_PATH_MAX + LONG_STRING];
+  size_t prev_size = 0;
+  int fd;
+  int count = 0;
+  struct stat sb;
+  time_t t;
+  
+  snprintf(nfslockfile, sizeof(nfslockfile), "%s.%s.%d",
+          realpath, Hostname, (int) getpid());
+  snprintf(lockfile, sizeof(lockfile), "%s.lock", realpath);
+
+  
+  BEGIN_PRIVILEGED();
+
+  unlink(nfslockfile);
+
+  while ((fd = open (nfslockfile, O_WRONLY | O_EXCL | O_CREAT, 0)) < 0)
+  {
+    END_PRIVILEGED();
+
+  
+    if (errno != EAGAIN)
+    {
+      /* perror ("cannot open NFS lock file"); */
+      return DL_EX_ERROR;
+    }
+
+    
+    BEGIN_PRIVILEGED();
+  }
+
+  END_PRIVILEGED();
+
+  
+  close(fd);
+  
+  while(1)
+  {
+
+    BEGIN_PRIVILEGED();
+    link(nfslockfile, lockfile);
+    END_PRIVILEGED();
+
+    if(stat(nfslockfile, &sb) != 0)
+    {
+      /* perror("stat"); */
+      return DL_EX_ERROR;
+    }
+    
+    if(sb.st_nlink == 2)
+      break;
+    
+    if(count == 0)
+      prev_size = sb.st_size;
+    
+    if(prev_size == sb.st_size && ++count > Retry)
+    {
+      if(f_force)
+      {
+       BEGIN_PRIVILEGED();
+       unlink(lockfile);
+       END_PRIVILEGED();
+
+       count = 0;
+       continue;
+      }
+      else
+      {
+       BEGIN_PRIVILEGED();
+       unlink(nfslockfile);
+       END_PRIVILEGED();
+       return DL_EX_EXIST;
+      }
+    }
+    
+    prev_size = sb.st_size;
+    
+    /* don't trust sleep(3) as it may be interrupted
+     * by users sending signals. 
+     */
+    
+    t = time(NULL);
+    do {
+      sleep(1);
+    } while (time(NULL) == t);
+  }
+  
+  BEGIN_PRIVILEGED();
+  unlink(nfslockfile);
+  END_PRIVILEGED();
+
+  return DL_EX_OK;
+}
+
+
+/*
+ * Unlock a file. 
+ * 
+ * The same comment as for dotlock_lock() applies here.
+ * 
+ */
+
+static int
+dotlock_unlock(const char *realpath)
+{
+  char lockfile[_POSIX_PATH_MAX + LONG_STRING];
+  int i;
+
+  snprintf(lockfile, sizeof(lockfile), "%s.lock",
+          realpath);
+  
+  BEGIN_PRIVILEGED();
+  i = unlink(lockfile);
+  END_PRIVILEGED();
+  
+  if(i == -1)
+    return DL_EX_ERROR;
+  
+  return DL_EX_OK;
+}
+
+
+/*
+ * Check if a file can be locked at all.
+ * 
+ * The same comment as for dotlock_lock() applies here.
+ * 
+ */
+
+static int
+dotlock_try(void)
+{
+#ifdef USE_SETGID
+  struct stat sb;
+#endif
+
+  if(access(".", W_OK) == 0)
+    return DL_EX_OK;
+
+#ifdef USE_SETGID
+  if(stat(".", &sb) == 0)
+  {
+    if((sb.st_mode & S_IWGRP) == S_IWGRP && sb.st_gid == MailGid)
+      return DL_EX_NEED_PRIVS;
+  }
+#endif
+
+  return DL_EX_IMPOSSIBLE;
+}
diff --git a/dotlock.h b/dotlock.h
new file mode 100644 (file)
index 0000000..4dde522
--- /dev/null
+++ b/dotlock.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 1996-8 Michael R. Elkins <me@cs.hmc.edu>
+ * Copyright (C) 1998 Thomas Roessler <roessler@guug.de>
+ * 
+ *     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.
+ */ 
+
+#ifndef _DOTLOCK_H
+#define _DOTLOCK_H
+
+/* exit values */
+
+#define DL_EX_OK       0       
+#define DL_EX_ERROR    1       
+#define DL_EX_EXIST    3       
+#define DL_EX_NEED_PRIVS 4
+#define DL_EX_IMPOSSIBLE 5
+
+/* flags */
+
+#define DL_FL_TRY      (1 << 0)
+#define DL_FL_UNLOCK   (1 << 1)
+#define DL_FL_USEPRIV  (1 << 2)
+#define DL_FL_FORCE    (1 << 3)
+#define DL_FL_RETRY    (1 << 4)
+
+#ifndef DL_STANDALONE
+int dotlock_invoke(const char *, int, int);
+#endif
+
+#endif
diff --git a/edit.c b/edit.c
index 6d310d6f1f53258a5f6cb159b4bd0b55ec3f56f7..77afba4000947faf6ded4c49b13f2c5c50129cda 100644 (file)
--- a/edit.c
+++ b/edit.c
@@ -64,7 +64,7 @@ be_snarf_data (FILE *f, char **buf, int *bufmax, int *buflen, int offset,
   tmp[sizeof (tmp) - 1] = 0;
   if (prefix)
   {
-    strfcpy (tmp, Prefix, sizeof (tmp));
+    strfcpy (tmp, NONULL(Prefix), sizeof (tmp));
     tmplen = strlen (tmp);
     p = tmp + tmplen;
     tmplen = sizeof (tmp) - tmplen;
@@ -129,9 +129,9 @@ static int be_barf_file (const char *path, char **buf, int buflen)
 static void be_free_memory (char **buf, int buflen)
 {
   while (buflen-- > 0)
-    free (buf[buflen]);
+    FREE (&buf[buflen]);
   if (buf)
-    free (buf);
+    FREE (&buf);
 }
 
 static char **
@@ -323,7 +323,7 @@ int mutt_builtin_editor (const char *path, HEADER *msg, HEADER *cur)
     }
     addch ('\n');
 
-    if (tmp[0] == EscChar[0] && tmp[1] != EscChar[0])
+    if (EscChar && tmp[0] == EscChar[0] && tmp[1] != EscChar[0])
     {
       /* remove trailing whitespace from the line */
       p = tmp + strlen (tmp) - 1;
@@ -364,7 +364,7 @@ int mutt_builtin_editor (const char *path, HEADER *msg, HEADER *cur)
            }
            buf = be_include_messages (p, buf, &bufmax, &buflen,
                                       (tolower (tmp[1]) == 'm'),
-                                      (isupper (tmp[1])));
+                                      (isupper ((unsigned char) tmp[1])));
          }
          else
            addstr ("No mailbox.\n");
@@ -382,7 +382,11 @@ int mutt_builtin_editor (const char *path, HEADER *msg, HEADER *cur)
          break;
        case 'r':
          if (*p)
-           buf = be_snarf_file (p, buf, &bufmax, &buflen, 1);
+          {
+           strncpy(tmp, p, sizeof(tmp));
+           mutt_expand_path(tmp, sizeof(tmp));
+           buf = be_snarf_file (tmp, buf, &bufmax, &buflen, 1);
+          }
          else
            addstr ("missing filename.\n");
          break;
@@ -400,7 +404,7 @@ int mutt_builtin_editor (const char *path, HEADER *msg, HEADER *cur)
            buflen--;
            strfcpy (tmp, buf[buflen], sizeof (tmp));
            tmp[strlen (tmp)-1] = 0;
-           free (buf[buflen]);
+           FREE (&buf[buflen]);
            buf[buflen] = NULL;
            continue;
          }
@@ -417,9 +421,9 @@ int mutt_builtin_editor (const char *path, HEADER *msg, HEADER *cur)
            bufmax = buflen = 0;
 
            if (option (OPTEDITHDRS))
-             mutt_edit_headers (Visual, path, msg, NULL, 0);
+             mutt_edit_headers (NONULL(Visual), path, msg, NULL, 0);
            else
-             mutt_edit_file (Visual, path);
+             mutt_edit_file (NONULL(Visual), path);
 
            buf = be_snarf_file (path, buf, &bufmax, &buflen, 0);
 
diff --git a/enter.c b/enter.c
index b575db04f64ace04cfc1f68cde99a683d3c6e7b3..f9968b2c1c97ed14165aa2d3b88cc144025340c4 100644 (file)
--- a/enter.c
+++ b/enter.c
@@ -20,6 +20,7 @@
 #include "mutt_menu.h"
 #include "mutt_curses.h"
 #include "keymap.h"
+#include "history.h"
 
 #include <termios.h>
 #include <sys/types.h>
 /* macro to print control chars in reverse-video */
 #define ADDCH(x) addch (IsPrint (x) ? x : (ColorDefs[MT_COLOR_MARKERS] | (x + '@')))
 
-/* global vars used for the string-history routines */
-static char **Hist = NULL;
-static short HistCur = 0;
-static short HistLast = 0;
-
-void mutt_init_history (void)
-{
-  int i;
-  static int OldSize = 0;
-  
-  if (Hist)
-  {
-    for (i = 0 ; i < OldSize ; i ++)
-      safe_free ((void **) &Hist[i]);
-    safe_free ((void **) &Hist);
-  }
-  
-  if (HistSize)
-    Hist = safe_calloc (HistSize, sizeof (char *));
-  HistCur = 0;
-  HistLast = 0;
-  OldSize = HistSize;
-}
-
-static void sh_add (char *s)
-{
-  int prev;
-
-  if (!HistSize)
-    return; /* disabled */
-
-  if (*s)
-  {
-    prev = HistLast - 1;
-    if (prev < 0) prev = HistSize - 1;
-    if (!Hist[prev] || strcmp (Hist[prev], s) != 0)
-    {
-      safe_free ((void **) &Hist[HistLast]);
-      Hist[HistLast++] = safe_strdup (s);
-      if (HistLast > HistSize - 1)
-       HistLast = 0;
-    }
-  }
-  HistCur = HistLast; /* reset to the last entry */
-}
-
-static char *sh_next (void)
-{
-  int next;
-
-  if (!HistSize)
-    return (""); /* disabled */
-
-  next = HistCur + 1;
-  if (next > HistLast - 1)
-    next = 0;
-  if (Hist[next])
-    HistCur = next;
-  return (Hist[HistCur] ? Hist[HistCur] : "");
-}
-
-static char *sh_prev (void)
-{
-  int prev;
-
-  if (!HistSize)
-    return (""); /* disabled */
-
-  prev = HistCur - 1;
-  if (prev < 0)
-  {
-    prev = HistLast - 1;
-    if (prev < 0)
-    {
-      prev = HistSize - 1;
-      while (prev > 0 && Hist[prev] == NULL)
-       prev--;
-    }
-  }
-  if (Hist[prev])
-    HistCur = prev;
-  return (Hist[HistCur] ? Hist[HistCur] : "");
-}
 
 /* redraw flags for mutt_enter_string() */
 enum
@@ -145,6 +63,16 @@ int mutt_enter_string (unsigned char *buf, size_t buflen, int y, int x,
   int first = 1;
   int j;
   char tempbuf[_POSIX_PATH_MAX] = "";
+  history_class_t hclass;
+  
+  if(flags & (M_FILE | M_EFILE))
+    hclass = HC_FILE;
+  else if(flags & M_CMD)
+    hclass = HC_CMD;
+  else if(flags & M_ALIAS)
+    hclass = HC_ALIAS;
+  else 
+    hclass = HC_OTHER;
 
   FOREVER
   {
@@ -197,14 +125,14 @@ int mutt_enter_string (unsigned char *buf, size_t buflen, int y, int x,
        case OP_EDITOR_HISTORY_UP:
          if (!pass)
          {
-           strfcpy ((char *) buf, sh_prev (), buflen);
+           strfcpy ((char *) buf, mutt_history_prev (hclass), buflen);
            redraw = M_REDRAW_INIT;
          }
          break;
        case OP_EDITOR_HISTORY_DOWN:
          if (!pass)
          {
-           strfcpy ((char *) buf, sh_next (), buflen);
+           strfcpy ((char *) buf, mutt_history_next (hclass), buflen);
            redraw = M_REDRAW_INIT;
          }
          break;
@@ -433,7 +361,7 @@ int mutt_enter_string (unsigned char *buf, size_t buflen, int y, int x,
              if (buf[0])
              {
                mutt_pretty_mailbox ((char *) buf);
-               sh_add ((char *) buf);
+               mutt_history_add (hclass, (char *) buf);
                return (0);
              }
              return (-1);
@@ -500,7 +428,7 @@ self_insert:
       {
        buf[lastchar] = 0;
        if (!pass)
-         sh_add ((char *) buf);
+         mutt_history_add (hclass, (char *) buf);
        return (0);
       }
       else if ((ch < ' ' || IsPrint (ch)) && (lastchar + 1 < buflen))
diff --git a/from.c b/from.c
index 4279f9a84bad7d0cfa8d66b468884520d467d891..f5d2974989234966b7c6e19bf9c6b2eb75cd0a56 100644 (file)
--- a/from.c
+++ b/from.c
@@ -62,7 +62,8 @@ time_t is_from (const char *s, char *path, size_t pathlen)
   struct tm tm;
   int yr;
 
-  *path = 0;
+  if (path)
+    *path = 0;
 
   if (strncmp ("From ", s, 5) != 0)
     return 0;
@@ -102,11 +103,14 @@ time_t is_from (const char *s, char *path, size_t pathlen)
       if ((p = strchr (s, ' ')) == NULL)
        return 0;
     }
-    len = (size_t) (p - s);
-    if (len + 1 > pathlen)
-      len = pathlen - 1;
-    memcpy (path, s, len);
-    path[len] = 0;
+    if (path)
+    {
+      len = (size_t) (p - s);
+      if (len + 1 > pathlen)
+       len = pathlen - 1;
+      memcpy (path, s, len);
+      path[len] = 0;
+    }
 
     s = p + 1;
     SKIPWS (s);
@@ -156,7 +160,7 @@ time_t is_from (const char *s, char *path, size_t pathlen)
   if (!*s) return 0;
 
   /* timezone? */
-  if (isalpha (*s) || *s == '+' || *s == '-')
+  if (isalpha ((unsigned char) *s) || *s == '+' || *s == '-')
   {
     s = next_word (s);
     if (!*s) return 0;
@@ -165,7 +169,7 @@ time_t is_from (const char *s, char *path, size_t pathlen)
      * some places have two timezone fields after the time, e.g.
      *      From xxxx@yyyyyyy.fr Wed Aug  2 00:39:12 MET DST 1995
      */
-    if (isalpha (*s))
+    if (isalpha ((unsigned char) *s))
     {
       s = next_word (s);
       if (!*s) return 0;
index f8a1af178687e86cc6eafde0b2c4fbb8782e9e0d..7877f3e20c9276b4570571b6c96f0d8f036bcc41 100644 (file)
@@ -307,6 +307,7 @@ struct binding_t OpAttach[] = {
 
 struct binding_t OpCompose[] = {
   { "attach-file",     OP_COMPOSE_ATTACH_FILE,         "a" },
+  { "attach-message",  OP_COMPOSE_ATTACH_MESSAGE,      "A" },
   { "edit-bcc",                OP_COMPOSE_EDIT_BCC,            "b" },
   { "edit-cc",         OP_COMPOSE_EDIT_CC,             "c" },
   { "copy-file",       OP_SAVE,                        "C" },
@@ -332,6 +333,7 @@ struct binding_t OpCompose[] = {
   { "edit-to",         OP_COMPOSE_EDIT_TO,             "t" },
   { "edit-type",       OP_COMPOSE_EDIT_TYPE,           "\024" },
   { "toggle-unlink",   OP_COMPOSE_TOGGLE_UNLINK,       "u" },
+  { "update-encoding", OP_COMPOSE_UPDATE_ENCODING,     "U" },
   { "view-attach",     OP_VIEW_ATTACH,                 M_ENTER_S },
   { "send-message",    OP_COMPOSE_SEND_MESSAGE,        "y" },
   { "pipe-entry",      OP_PIPE,                        "|" },
@@ -358,7 +360,9 @@ struct binding_t OpBrowser[] = {
   { "sort",            OP_SORT,                "o" },
   { "sort-reverse",    OP_SORT_REVERSE,        "O" },
   { "select-new",      OP_BROWSER_NEW_FILE,    "N" },
-  { "check-new",       OP_CHECK_NEW,           "\t" },
+  { "check-new",       OP_CHECK_NEW,           NULL },
+  { "toggle-mailboxes", OP_TOGGLE_MAILBOXES,   "\t" },
+  { "view-file",       OP_BROWSER_VIEW_FILE,   " " },
   { NULL,              0,                      NULL }
 };
 
index d01f466689970d9f6af7f252f82800183bd48075..9854d0f86421a30cf86188ef1e661519b8e29ac1 100644 (file)
--- a/globals.h
+++ b/globals.h
@@ -24,7 +24,9 @@ WHERE char Errorbuf[SHORT_STRING];
 
 WHERE char *AliasFile;
 WHERE char *AliasFmt;
+WHERE char *AttachSep;
 WHERE char *Attribution;
+WHERE char *AttachFormat;
 WHERE char *Charset;
 WHERE char *DefaultHook;
 WHERE char *DateFmt;
@@ -32,7 +34,6 @@ WHERE char *DeleteFmt;
 WHERE char *DsnNotify;
 WHERE char *DsnReturn;
 WHERE char *Editor;
-WHERE char *EmptyTo;
 WHERE char *EscChar;
 WHERE char *FolderFormat;
 WHERE char *ForwFmt;
@@ -121,16 +122,11 @@ WHERE FILE *debugfile INITVAL (0);
 WHERE int debuglevel INITVAL (0);
 #endif
 
-#ifdef USE_SETGID
-WHERE gid_t MailGid;
-WHERE gid_t UserGid;
-#endif /* USE_SETGID */
-
 #ifdef MAIN_C
 const char *Weekdays[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
 const char *Months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "ERR" };
 
-const char *BodyTypes[] = { "x-unknown", "audio", "application", "image", "message", "multipart", "text", "video" };
+const char *BodyTypes[] = { "x-unknown", "audio", "application", "image", "message", "model", "multipart", "text", "video" };
 const char *BodyEncodings[] = { "x-unknown", "7bit", "8bit", "quoted-printable", "base64", "binary" };
 #else
 extern const char *Weekdays[];
index 15a0ca99cd944c8c061b73806a82ebc01de1cb3e..0ab05b6e92bfe0f1453840357aef5cc602a10111 100644 (file)
--- a/handler.c
+++ b/handler.c
@@ -65,74 +65,127 @@ int Index_64[128] = {
 
 void mutt_decode_xbit (STATE *s, long len, int istext)
 {
-  int linelen;
-  char buffer[LONG_STRING];
-
+  int c;
+  int lbreak = 1;
+  
   if (istext)
   {
-    while (len > 0)
+    while ((c = fgetc(s->fpin)) != EOF && len--)
     {
-      if (fgets (buffer, LONG_STRING, s->fpin) == 0) return;
-      linelen = strlen (buffer);
-      len -= linelen;
-      if (linelen >= 2 && buffer[linelen-2] == '\r')
+      if(lbreak && s->prefix)
       {
-       buffer[linelen-2] = '\n';
-       buffer[linelen-1] = 0;
+       state_puts(s->prefix, s);
+       lbreak = 0;
       }
-      if (s->prefix) state_puts (s->prefix, s);
-      state_puts (buffer, s);
+         
+      if (c == '\r' && len)
+      {
+       int ch;
+       
+       if((ch = fgetc(s->fpin)) != '\n')
+         ungetc(ch, s->fpin);
+       else
+       {
+         c = ch;
+         len--;
+       }
+       
+      }
+      fputc(c, s->fpout);
+      if(c == '\n')
+       lbreak = 1;
     }
   }
   else
     mutt_copy_bytes (s->fpin, s->fpout, len);
 }
 
+static int handler_state_fgetc(STATE *s)
+{
+  int ch;
+  
+  if((ch = fgetc(s->fpin)) == EOF)
+  {
+    dprint(1, (debugfile, "handler_state_fgetc: unexpected EOF.\n"));
+    state_puts ("[-- Error: unexpected end of file! --]\n", s);
+  }
+  return ch;
+}
+
 void mutt_decode_quoted (STATE *s, long len, int istext)
 {
-  char *c, buffer[LONG_STRING];
-  int ch, soft = 0;
+  int ch, lbreak = 1;
 
   while (len > 0)
   {
-    if (fgets (buffer, LONG_STRING, s->fpin) == NULL)
-    {
-      dprint (1, (debugfile, "mutt_decode_quoted: unexpected EOF.\n"));
-      state_puts ("[-- Error: unexpected end of file! --]\n", s);
+    if ((ch = handler_state_fgetc(s)) == EOF)
       break;
-    }
-    c = buffer;
-    len -= strlen (buffer);
-    if (s->prefix && !soft) state_puts (s->prefix, s);
-    soft = 0;
-    while (*c)
+
+    len--;
+    
+    if (s->prefix && lbreak)
+      state_puts (s->prefix, s);
+    
+    lbreak = 0;
+    if (ch == '=')
     {
-      if (*c == '=')
+      int ch1, ch2;
+      
+      if(!len || (ch1 = handler_state_fgetc(s)) == EOF)
+       break;
+
+      len--;
+      
+      if (ch1 == '\n' || ch1 == '\r' || ch1 == ' ' || ch1 == '\t')
       {
-        if (c[1] == '\n' || c[1] == '\r' || c[1] == ' ' || c[1] == '\t')
+       /* Skip whitespace at the end of the line since MIME does not
+        * allow for it
+        */
+       if(ch1 != '\n')
        {
-          /* Skip whitespace at the end of the line since MIME does not
-           * allow for it
-          */
-          soft = 1;
-          break;
-        }
-        ch = hexval ((int) c[1]) << 4;
-        ch |= hexval ((int) c[2]);
-        state_putc (ch, s);
-        c += 3;
+         while(len && (ch1 = handler_state_fgetc(s)) != EOF)
+         {
+           len--;
+           if(ch1 == '\n')
+             break;
+         }
+       }
+
+       if(ch1 == EOF)
+         break;
+
+       ch = EOF;
+
       }
-      else if (istext && c[0] == '\r' && c[1] == '\n')
+      else
       {
-        state_putc ('\n', s);
-        break;
+       if(!len || (ch2 = handler_state_fgetc(s)) == EOF)
+         break;
+
+       len--;
+       
+        ch = hexval (ch1) << 4;
+        ch |= hexval (ch2);
       }
-      else
+    } /* ch == '=' */
+    else if (istext && ch == '\r')
+    {
+      int ch1;
+
+      if((ch1 =fgetc(s->fpin)) == '\n')
       {
-        state_putc (*c, s);
-        c++;
+       ch = ch1;
+       len--;
       }
+      else
+       ungetc(ch1, s->fpin);
     }
+
+    if(ch != EOF)
+      state_putc (ch, s);
+
+    if(ch == '\n')
+      lbreak = 1;
   }
 }
 
@@ -157,8 +210,8 @@ void mutt_decode_base64 (STATE *s, long len, int istext)
     if (i != 4)
       return; /* didn't get a multiple of four chars! */
 
-    c1 = base64val ((int) buf[0]);
-    c2 = base64val ((int) buf[1]);
+    c1 = base64val (buf[0]);
+    c2 = base64val (buf[1]);
     ch = (c1 << 2) | (c2 >> 4);
 
     if (cr && ch != '\n') state_putc ('\r', s);
@@ -174,7 +227,7 @@ void mutt_decode_base64 (STATE *s, long len, int istext)
 
     if (buf[2] == '=')
       break;
-    c3 = base64val ((int) buf[2]);
+    c3 = base64val (buf[2]);
     ch = ((c2 & 0xf) << 4) | (c3 >> 2);
 
     if (cr && ch != '\n')
@@ -191,7 +244,7 @@ void mutt_decode_base64 (STATE *s, long len, int istext)
     }
 
     if (buf[3] == '=') break;
-    c4 = base64val ((int) buf[3]);
+    c4 = base64val (buf[3]);
     ch = ((c3 & 0x3) << 6) | c4;
 
     if (cr && ch != '\n')
@@ -655,6 +708,7 @@ void text_enriched_handler (BODY *a, STATE *s)
 
       case ST_EOF :
        enriched_putc ('\0', &stte);
+        enriched_flush (&stte, 1);
        state = DONE;
        break;
 
@@ -665,10 +719,9 @@ void text_enriched_handler (BODY *a, STATE *s)
 
   state_putc ('\n', s); /* add a final newline */
 
-  if (stte.buffer)
-    free (stte.buffer);
-  free (stte.line);
-  free (stte.param);
+  FREE (&(stte.buffer));
+  FREE (&(stte.line));
+  FREE (&(stte.param));
 }                                                                              
 
 #define TXTPLAIN    1
@@ -700,14 +753,14 @@ void alternative_handler (BODY *a, STATE *s)
       if (!strchr(t->data, '/') || 
          (i > 0 && t->data[i-1] == '/' && t->data[i] == '*'))
       {
-       if (!strcasecmp(t->data, TYPE(b->type)))
+       if (!strcasecmp(t->data, TYPE(b)))
        {
          choice = b;
        }
       }
       else
       {
-       snprintf (buf, sizeof (buf), "%s/%s", TYPE (b->type), b->subtype);
+       snprintf (buf, sizeof (buf), "%s/%s", TYPE (b), b->subtype);
        if (!strcasecmp(t->data, buf))
        {
          choice = b;
@@ -724,7 +777,7 @@ void alternative_handler (BODY *a, STATE *s)
     b = a;
   while (b && !choice)
   {
-    snprintf (buf, sizeof (buf), "%s/%s", TYPE (b->type), b->subtype);
+    snprintf (buf, sizeof (buf), "%s/%s", TYPE (b), b->subtype);
     if (mutt_is_autoview (buf))
     {
       rfc1524_entry *entry = rfc1524_new_entry ();
@@ -844,7 +897,7 @@ int mutt_can_decode (BODY *a)
 {
   char type[STRING];
 
-  snprintf (type, sizeof (type), "%s/%s", TYPE (a->type), a->subtype);
+  snprintf (type, sizeof (type), "%s/%s", TYPE (a), a->subtype);
   if (mutt_is_autoview (type))
     return (rfc1524_mailcap_lookup (a, type, NULL, M_AUTOVIEW));
   else if (a->type == TYPETEXT)
@@ -932,7 +985,7 @@ void multipart_handler (BODY *a, STATE *s)
 
       snprintf (buffer, sizeof (buffer),
                "[-- Type: %s/%s, Encoding: %s, Size: %s --]\n",
-              TYPE (p->type), p->subtype, ENCODING (p->encoding), length);
+              TYPE (p), p->subtype, ENCODING (p->encoding), length);
       state_puts (buffer, s);
       if (!option (OPTWEED))
       {
@@ -971,16 +1024,20 @@ void autoview_handler (BODY *a, STATE *s)
   char type[STRING];
   char command[LONG_STRING];
   char tempfile[_POSIX_PATH_MAX] = "";
+  char *fname;
   FILE *fpin = NULL;
   FILE *fpout = NULL;
   FILE *fperr = NULL;
   int piped = FALSE;
   pid_t thepid;
 
-  snprintf (type, sizeof (type), "%s/%s", TYPE (a->type), a->subtype);
+  snprintf (type, sizeof (type), "%s/%s", TYPE (a), a->subtype);
   rfc1524_mailcap_lookup (a, type, entry, M_AUTOVIEW);
 
-  rfc1524_expand_filename (entry->nametemplate, a->filename, tempfile, sizeof (tempfile));
+  fname = safe_strdup (a->filename);
+  mutt_sanitize_filename (fname);
+  rfc1524_expand_filename (entry->nametemplate, fname, tempfile, sizeof (tempfile));
+  FREE (&fname);
 
   if (entry->command)
   {
@@ -1104,7 +1161,7 @@ void mutt_body_handler (BODY *b, STATE *s)
 
   /* first determine which handler to use to process this part */
 
-  snprintf (type, sizeof (type), "%s/%s", TYPE (b->type), b->subtype);
+  snprintf (type, sizeof (type), "%s/%s", TYPE (b), b->subtype);
   if (mutt_is_autoview (type))
   {
     rfc1524_entry *entry = rfc1524_new_entry ();
@@ -1129,7 +1186,7 @@ void mutt_body_handler (BODY *b, STATE *s)
   }
   else if (b->type == TYPEMESSAGE)
   {
-    if (!strcasecmp ("rfc822", b->subtype) || !strcasecmp ("news", b->subtype))
+    if(mutt_is_message_type(b->type, b->subtype))
       handler = message_handler;
     else if (!strcasecmp ("delivery-status", b->subtype))
       plaintext = 1;
@@ -1275,7 +1332,7 @@ void mutt_body_handler (BODY *b, STATE *s)
   }
   else if (s->flags & M_DISPLAY)
   {
-    fprintf (s->fpout, "[-- %s/%s is unsupported ", TYPE (b->type), b->subtype);
+    fprintf (s->fpout, "[-- %s/%s is unsupported ", TYPE (b), b->subtype);
     if (!option (OPTVIEWATTACH))
     {
       if (km_expand_key (type, sizeof(type),
diff --git a/hash.c b/hash.c
index f670eb4a99b1674e9f3cfc2d82422da926c296b7..efd63a6fe97dfbe4cf4172b77b1a715993932b28 100644 (file)
--- a/hash.c
+++ b/hash.c
@@ -44,9 +44,11 @@ HASH *hash_create (int nelem)
    allow_dup    if nonzero, duplicate keys are allowed in the table */
 int hash_insert (HASH * table, const char *key, void *data, int allow_dup)
 {
-  struct hash_elem *ptr = malloc (sizeof (struct hash_elem));
-  int h = hash_string ((unsigned char *) key, table->nelem);
+  struct hash_elem *ptr;
+  int h;
 
+  ptr = (struct hash_elem *) safe_malloc (sizeof (struct hash_elem));
+  h = hash_string ((unsigned char *) key, table->nelem);
   ptr->key = key;
   ptr->data = data;
 
@@ -65,7 +67,7 @@ int hash_insert (HASH * table, const char *key, void *data, int allow_dup)
       r = strcmp (tmp->key, key);
       if (r == 0)
       {
-       free (ptr);
+       FREE (&ptr);
        return (-1);
       }
       if (r > 0)
@@ -109,9 +111,7 @@ void hash_delete_hash (HASH * table, int hash, const char *key, const void *data
        table->table[hash] = ptr->next;
       if (destroy)
        destroy (ptr->data);
-      memset (ptr, 0, sizeof (struct hash_elem));
-      free (ptr);
-      ptr = 0;
+      FREE (&ptr);
       return;
     }
   }
index 5f8ddf9d36a97e6efcd7816b7ffdb49d8300b5f6..2e9710b90f376d5186049c31ce8918f82c99a05e 100644 (file)
--- a/hdrline.c
+++ b/hdrline.c
@@ -45,6 +45,10 @@ int mutt_is_mail_list (ADDRESS *addr)
   return 0;
 }
 
+/* Search for a mailing list in the list of addresses pointed to by adr.
+ * If one is found, print pfx and the name of the list into buf, then
+ * return 1.  Otherwise, simply return 0.
+ */
 static int
 check_for_mailing_list (ADDRESS *adr, char *pfx, char *buf, int buflen)
 {
@@ -60,6 +64,26 @@ check_for_mailing_list (ADDRESS *adr, char *pfx, char *buf, int buflen)
   return 0;
 }
 
+/* Search for a mailing list in the list of addresses pointed to by adr.
+ * If one is found, print the address of the list into buf, then return 1.
+ * Otherwise, simply return 0.
+ */
+static int
+check_for_mailing_list_addr (ADDRESS *adr, char *buf, int buflen)
+{
+  for (; adr; adr = adr->next)
+  {
+    if (mutt_is_mail_list (adr))
+    {
+      if (buf && buflen)
+       snprintf (buf, buflen, "%s", adr->mailbox);
+      return 1;
+    }
+  }
+  return 0;
+}
+
+
 static int first_mailing_list (char *buf, size_t buflen, ADDRESS *a)
 {
   for (; a; a = a->next)
@@ -97,6 +121,30 @@ static void make_from (ENVELOPE *hdr, char *buf, size_t len, int do_lists)
     *buf = 0;
 }
 
+static void make_from_addr (ENVELOPE *hdr, char *buf, size_t len, int do_lists)
+{
+  int me;
+
+  me = mutt_addr_is_user (hdr->from);
+
+  if (do_lists || me)
+  {
+    if (check_for_mailing_list_addr (hdr->to, buf, len))
+      return;
+    if (check_for_mailing_list_addr (hdr->cc, buf, len))
+      return;
+  }
+
+  if (me && hdr->to)
+    snprintf (buf, len, "%s", hdr->to->mailbox);
+  else if (me && hdr->cc)
+    snprintf (buf, len, "%s", hdr->cc->mailbox);
+  else if (hdr->from)
+    strfcpy (buf, hdr->from->mailbox, len);
+  else
+    *buf = 0;
+}
+
 int mutt_user_is_recipient (ADDRESS *a)
 {
   for (; a; a = a->next)
@@ -145,6 +193,7 @@ static int user_is_recipient (ENVELOPE *hdr)
  * %m = number of messages in the mailbox
  * %n = name of author
  * %N = score
+ * %O = like %L, except using address instead of name
  * %s = subject
  * %S = short message status (e.g., N/O/D/!/r/-)
  * %t = `to:' field (recipients)
@@ -206,11 +255,11 @@ hdr_format_str (char *dest,
          strfcpy (dest, p + 1, destlen);
        else
          strfcpy (dest, ctx->path, destlen);
-       break;
       }
       else 
        strfcpy(dest, "(null)", destlen);
-
+      break;
+    
     case 'c':
       mutt_pretty_size (buf2, sizeof (buf2), (long) hdr->content->length);
       snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
@@ -259,7 +308,7 @@ hdr_format_str (char *dest,
            {
              if (len >= 5)
              {
-               sprintf (p, "%c%02d%02d", hdr->zoccident ? '-' : '+',
+               sprintf (p, "%c%02u%02u", hdr->zoccident ? '-' : '+',
                         hdr->zhours, hdr->zminutes);
                p += 5;
                len -= 5;
@@ -380,6 +429,22 @@ hdr_format_str (char *dest,
       snprintf (dest, destlen, fmt, hdr->score);
       break;
 
+    case 'O':
+      if (!optional)
+      {
+       make_from_addr (hdr->env, buf2, sizeof (buf2), 1);
+       if (!option (OPTSAVEADDRESS) && (p = strpbrk (buf2, "%@")))
+         *p = 0;
+       snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
+       snprintf (dest, destlen, fmt, buf2);
+      }
+      else if (!check_for_mailing_list_addr (hdr->env->to, NULL, 0) &&
+              !check_for_mailing_list_addr (hdr->env->cc, NULL, 0))
+      {
+       optional = 0;
+      }
+      break;
+
     case 's':
       snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
       if (flags & M_FORMAT_TREE)
index b718eaf17c79f55b65ccb3161fe304997d081504..c9bc49b2c466f7d8aae4f36be608dfdc92eb81b4 100644 (file)
--- a/headers.c
+++ b/headers.c
@@ -189,7 +189,7 @@ void mutt_edit_headers (const char *editor,
        else
          strfcpy (path, p, sizeof (path));
        mutt_expand_path (path, sizeof (path));
-       if ((body = mutt_make_attach (path)))
+       if ((body = mutt_make_file_attach (path)))
        {
          body->description = safe_strdup (q);
          for (parts = msg->content; parts->next; parts = parts->next) ;
diff --git a/help.c b/help.c
index fa79b4ce5b9e3210ae4e610d903a8312b684cd13..d1a29a916386202bbdf8339a017040d7858059cf 100644 (file)
--- a/help.c
+++ b/help.c
@@ -84,11 +84,11 @@ mutt_compile_help (char *buf, size_t buflen, int menu, struct mapping_t *items)
   return buf;
 }
 
-static void print_macro (FILE *f, const char *macro)
+static int print_macro (FILE *f, int maxchar, const char *macro)
 {
   int i;
 
-  for (i = 0; *macro && i < COLS - 34; macro++, i++)
+  for (i = 0; *macro && i < maxchar; macro++, i++)
   {
     switch (*macro)
     {
@@ -113,6 +113,25 @@ static void print_macro (FILE *f, const char *macro)
        break;
     }
   }
+  return (i);
+}
+
+static int pad (FILE *f, int col, int i)
+{
+  char fmt[8];
+
+  if (i < col)
+  {
+    snprintf (fmt, sizeof(fmt), "%%-%ds", col - i);
+    fprintf (f, fmt, "");
+    i = col;
+  }
+  else
+  {
+    fputc (' ', f);
+    ++i;
+  }
+  return (i);
 }
 
 static void dump_menu (FILE *f, int menu)
@@ -120,24 +139,51 @@ static void dump_menu (FILE *f, int menu)
   struct keymap_t *map;
   struct binding_t *b;
   char buf[SHORT_STRING];
+  int col;
 
   /* browse through the keymap table */
   for (map = Keymaps[menu]; map; map = map->next)
   {
-    km_expand_key (buf, sizeof (buf), map);
-
-    if (map->op == OP_MACRO)
-    {
-      fprintf (f, "%s\t%-20s\t", buf, "macro");
-      print_macro (f, map->macro);
-      fputc ('\n', f);
-    }
-    else if (map->op != OP_NULL)
+    if (map->op != OP_NULL)
     {
-      b = help_lookupFunction (map->op, menu);
-      fprintf (f, "%s\t%-20s\t%s\n", buf,
-             b ? b->name : "UNKNOWN",
+      km_expand_key (buf, sizeof (buf), map);
+      fputs (buf, f);
+      col = pad (f, 12, strlen (buf));
+
+      if (map->op == OP_MACRO)
+      {
+       if (map->descr == NULL)
+       {
+         fputs ("macro ", f);
+         col = pad (f, 35, col + 6);
+         print_macro (f, COLS - col, map->macro);
+       }
+       else
+       {
+         fputs ("macro: ", f);
+         col += 7;
+         if (strlen (map->macro) < (34 - col))
+         {
+           col += print_macro (f, 34 - col, map->macro);
+           col = pad (f, 35, col);
+         }
+         else
+         {
+           if (col < 31)
+             col += print_macro (f, 31 - col, map->macro);
+           fputs ("... ", f);
+           col += 4;
+         }
+         print_macro (f, COLS - col, map->descr);
+       }
+       fputc ('\n', f);
+      }
+      else
+      {
+       b = help_lookupFunction (map->op, menu);
+       fprintf (f, "%-22s %s\n", b ? b->name : "UNKNOWN",
              b ? HelpStrings[b->op] : "ERROR: please report this bug");
+      }
     }
   }
 }
@@ -161,7 +207,7 @@ static void dump_unbound (FILE *f,
   {
     if (! is_bound (map, funcs[i].op) &&
        (!aux || ! is_bound (aux, funcs[i].op)))
-      fprintf (f, "%s\t\t%s\n", funcs[i].name, HelpStrings[funcs[i].op]);
+      fprintf (f, "%-35s%s\n", funcs[i].name, HelpStrings[funcs[i].op]);
   }
 }
 
diff --git a/history.c b/history.c
new file mode 100644 (file)
index 0000000..53fe089
--- /dev/null
+++ b/history.c
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 1996-8 Michael R. Elkins <me@cs.hmc.edu>
+ * 
+ *     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.
+ */ 
+
+#include "mutt.h"
+#include "history.h"
+
+/* global vars used for the string-history routines */
+
+struct history
+{
+  char **hist;
+  short cur;
+  short last;
+}; 
+
+static struct history History[HC_LAST];
+static int OldSize = 0;
+
+static void init_history (struct history *h)
+{
+  int i;
+
+  if(OldSize)
+  {
+    if (h->hist)
+    {
+      for (i = 0 ; i < OldSize ; i ++)
+       safe_free ((void **) &h->hist[i]);
+      safe_free ((void **) &h->hist);
+    }
+  }
+  
+  if (HistSize)
+    h->hist = safe_calloc (HistSize, sizeof (char *));
+  
+  h->cur = 0;
+  h->last = 0;
+}
+
+void mutt_init_history(void)
+{
+  history_class_t hclass;
+  
+  for(hclass = HC_FIRST; hclass < HC_LAST; hclass++)
+    init_history(&History[hclass]);
+
+  OldSize = HistSize;
+}
+  
+void mutt_history_add (history_class_t hclass, const char *s)
+{
+  int prev;
+  struct history *h = &History[hclass];
+  
+  if (!HistSize)
+    return; /* disabled */
+
+  if (*s)
+  {
+    prev = h->last - 1;
+    if (prev < 0) prev = HistSize - 1;
+    if (!h->hist[prev] || strcmp (h->hist[prev], s) != 0)
+    {
+      safe_free ((void **) &h->hist[h->last]);
+      h->hist[h->last++] = safe_strdup (s);
+      if (h->last > HistSize - 1)
+       h->last = 0;
+    }
+  }
+  h->cur = h->last; /* reset to the last entry */
+}
+
+char *mutt_history_next (history_class_t hclass)
+{
+  int next;
+  struct history *h = &History[hclass];
+  
+  if (!HistSize)
+    return (""); /* disabled */
+
+  next = h->cur + 1;
+  if (next > h->last - 1)
+    next = 0;
+  if (h->hist[next])
+    h->cur = next;
+  return (h->hist[h->cur] ? h->hist[h->cur] : "");
+}
+
+char *mutt_history_prev (history_class_t hclass)
+{
+  int prev;
+  struct history *h = &History[hclass];
+
+  if (!HistSize)
+    return (""); /* disabled */
+
+  prev = h->cur - 1;
+  if (prev < 0)
+  {
+    prev = h->last - 1;
+    if (prev < 0)
+    {
+      prev = HistSize - 1;
+      while (prev > 0 && h->hist[prev] == NULL)
+       prev--;
+    }
+  }
+  if (h->hist[prev])
+    h->cur = prev;
+  return (h->hist[h->cur] ? h->hist[h->cur] : "");
+}
diff --git a/history.h b/history.h
new file mode 100644 (file)
index 0000000..94af71d
--- /dev/null
+++ b/history.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 1996-8 Michael R. Elkins <me@cs.hmc.edu>
+ * 
+ *     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.
+ */ 
+
+#ifndef _HISTORY_H
+#define _HISTORY_H
+
+enum history_class
+{
+  HC_CMD,
+  HC_ALIAS,
+  HC_COMMAND,
+  HC_FILE,
+  HC_OTHER,
+  HC_LAST
+};
+
+#define HC_FIRST HC_CMD
+
+typedef enum history_class history_class_t;
+
+void mutt_init_history(void);
+void mutt_history_add(history_class_t, const char *);
+char *mutt_history_next(history_class_t);
+char *mutt_history_prev(history_class_t);
+
+#endif
diff --git a/hook.c b/hook.c
index be7e516eab53f61bd55434f905a819e4af5fa705..259c2352f986ba08bb622ebbe954cf0ce147fbec 100644 (file)
--- a/hook.c
+++ b/hook.c
@@ -84,7 +84,11 @@ int mutt_parse_hook (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *err)
     memset (&pattern, 0, sizeof (pattern));
     pattern.data = safe_strdup (path);
   }
-  else if (DefaultHook)
+  else if (DefaultHook
+#ifdef _PGPPATH
+      && !(data & M_PGPHOOK)
+#endif /* _PGPPATH */
+      )
   {
     char tmp[HUGE_STRING];
 
@@ -148,7 +152,11 @@ int mutt_parse_hook (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *err)
   else
   {
     rx = safe_malloc (sizeof (regex_t));
+#ifdef _PGPPATH
+    if ((rc = REGCOMP (rx, pattern.data, ((data & M_PGPHOOK) ? REG_ICASE : 0))) != 0)
+#else
     if ((rc = REGCOMP (rx, pattern.data, 0)) != 0)
+#endif /* _PGPPATH */
     {
       regerror (rc, rx, err->data, err->dsize);
       regfree (rx);
@@ -188,6 +196,10 @@ void mutt_folder_hook (char *path)
   err.dsize = sizeof (buf);
   memset (&token, 0, sizeof (token));
   for (; tmp; tmp = tmp->next)
+  {
+    if(!tmp->command)
+      continue;
+
     if (tmp->type & M_FOLDERHOOK)
     {
       if ((regexec (tmp->rx.rx, path, 0, NULL, 0) == 0) ^ tmp->rx.not)
@@ -201,6 +213,7 @@ void mutt_folder_hook (char *path)
        }
       }
     }
+  }
   FREE (&token.data);
 }
 
@@ -227,6 +240,10 @@ void mutt_send_hook (HEADER *hdr)
   err.dsize = sizeof (buf);
   memset (&token, 0, sizeof (token));
   for (hook = Hooks; hook; hook = hook->next)
+  {
+    if(!hook->command)
+      continue;
+
     if (hook->type & M_SENDHOOK)
       if ((mutt_pattern_exec (hook->pattern, 0, NULL, hdr) > 0) ^ hook->rx.not)
        if (mutt_parse_rc_line (hook->command, &token, &err) != 0)
@@ -236,6 +253,7 @@ void mutt_send_hook (HEADER *hdr)
          sleep (1);
          return;
        }
+  }
   FREE (&token.data);
 }
 
@@ -246,12 +264,17 @@ mutt_addr_hook (char *path, size_t pathlen, int type, CONTEXT *ctx, HEADER *hdr)
 
   /* determine if a matching hook exists */
   for (hook = Hooks; hook; hook = hook->next)
+  {
+    if(!hook->command)
+      continue;
+
     if (hook->type & type)
       if ((mutt_pattern_exec (hook->pattern, 0, ctx, hdr) > 0) ^ hook->rx.not)
       {
        mutt_make_string (path, pathlen, hook->command, ctx, hdr);
        return 0;
       }
+  }
 
   return -1;
 }
@@ -306,3 +329,19 @@ void mutt_select_fcc (char *path, size_t pathlen, HEADER *hdr)
   }
   mutt_pretty_mailbox (path);
 }
+
+#ifdef _PGPPATH
+char *mutt_pgp_hook (ADDRESS *adr)
+{
+  HOOK *tmp = Hooks;
+
+  for (; tmp; tmp = tmp->next)
+  {
+    if ((tmp->type & M_PGPHOOK) && ((adr->mailbox && 
+        regexec (tmp->rx.rx, adr->mailbox, 0, NULL, 0) == 0) ^ tmp->rx.not))
+      return (tmp->command);
+  }
+  return (NULL);
+}
+#endif /* _PGPPATH */
+
diff --git a/imap.c b/imap.c
index 872e019b16b0237bb936f227b5276bb1ded71929..34440247d507ba874a5b21d59f7accb325235f2d 100644 (file)
--- a/imap.c
+++ b/imap.c
@@ -21,6 +21,7 @@
 #include "mx.h"
 #include "mailbox.h"
 #include "globals.h"
+#include "mutt_socket.h"
 
 #include <unistd.h>
 #include <netinet/in.h>
@@ -47,30 +48,18 @@ enum
   IMAP_NEW_MAIL,
   IMAP_EXPUNGE,
   IMAP_BYE,
-  IMAP_OK_FAIL,
-  IMAP_OPEN_NEW
+  IMAP_OK_FAIL
 };
 
 typedef struct
 {
-  char *server;
-  int uses;
-  int fd;
-  char inbuf[LONG_STRING];
-  int bufpos;
-  int available;
-} CONNECTION;
-
-typedef struct
-{
-  int index;
+  unsigned int index;
   char *path;
 } IMAP_CACHE;
 
 typedef struct
 {
   short status;
-  unsigned short sequence;
   unsigned short newMailCount;
   char *mailbox;
   short xxx;
@@ -80,92 +69,35 @@ typedef struct
 
 #define CTX_DATA ((IMAP_DATA *) ctx->data)
 
-static CONNECTION *Connections = NULL;
-static int NumConnections = 0;
-
-/* simple read buffering to speed things up. */
-static int imap_readchar (CONNECTION *conn, char *c)
-{
-  if (conn->bufpos >= conn->available)
-  {
-    conn->available = read (conn->fd, conn->inbuf, sizeof(LONG_STRING));
-    conn->bufpos = 0;
-    if (conn->available <= 0)
-      return conn->available; /* returns 0 for EOF or -1 for other error */
-  }
-  *c = conn->inbuf[conn->bufpos];
-  conn->bufpos++;
-  return 1;
-}
-
-static int imap_read_line (char *buf, size_t buflen, CONNECTION *conn)
+/* Linked list to hold header information while downloading message
+ * headers
+ */
+typedef struct imap_header_info
 {
-  char ch;
-  int i;
+  unsigned int read : 1;
+  unsigned int old : 1;
+  unsigned int deleted : 1;
+  unsigned int flagged : 1;
+  unsigned int replied : 1;
+  unsigned int changed : 1;
 
-  for (i = 0; i < buflen; i++)
-  {
-    if (imap_readchar (conn, &ch) != 1)
-      return (-1);
-    if (ch == '\n')
-      break;
-    buf[i] = ch;
-  }
-  buf[i-1] = 0;
-  return (i + 1);
-}
+  time_t received;
+  long content_length;
+  struct imap_header_info *next;
+} IMAP_HEADER_INFO;
 
-static int imap_read_line_d (char *buf, size_t buflen, CONNECTION *conn)
-{
-  int r = imap_read_line (buf, buflen, conn);
-  dprint (1,(debugfile,"imap_read_line_d():%s\n", buf));
-  return r;
-}
 
-static void imap_make_sequence (char *buf, size_t buflen, CONTEXT *ctx)
+static void imap_make_sequence (char *buf, size_t buflen)
 {
-  snprintf (buf, buflen, "a%04d", CTX_DATA->sequence++);
+  static int sequence = 0;
+  
+  snprintf (buf, buflen, "a%04d", sequence++);
 }
 
-static int imap_write (CONNECTION *conn, const char *buf)
-{
-  dprint (1,(debugfile,"imap_write():%s", buf));
-  return (write (conn->fd, buf, strlen (buf)));
-}
 
 static void imap_error (const char *where, const char *msg)
 {
-  dprint (1, (debugfile, "imap_error(): unexpected response in %s: %s\n", where, msg));
-}
-
-static CONNECTION *imap_select_connection (char *host, int flags)
-{
-  int x;
-
-  if (flags != IMAP_OPEN_NEW)
-  {
-    for (x = 0; x < NumConnections; x++)
-    {
-      if (!strcmp (host, Connections[x].server))
-       return &Connections[x];
-    }
-  }
-  if (NumConnections == 0)
-  {
-    NumConnections = 1;
-    Connections = (CONNECTION *) safe_malloc (sizeof (CONNECTION));
-  }
-  else
-  {
-    NumConnections++;
-    safe_realloc ((void *)Connections, sizeof (CONNECTION) * NumConnections);
-  }
-  Connections[NumConnections - 1].bufpos = 0;
-  Connections[NumConnections - 1].available = 0;
-  Connections[NumConnections - 1].uses = 0;
-  Connections[NumConnections - 1].server = safe_strdup (host);
-
-  return &Connections[NumConnections - 1];
+  mutt_error ("imap_error(): unexpected response in %s: %s\n", where, msg);
 }
 
 /* date is of the form: DD-MMM-YYYY HH:MM:SS +ZZzz */
@@ -216,7 +148,7 @@ static time_t imap_parse_date (char *s)
   return (mutt_mktime (&t, 0) + tz);
 }
 
-static int imap_parse_fetch (HEADER *h, char *s)
+static int imap_parse_fetch (IMAP_HEADER_INFO *h, char *s)
 {
   char tmp[SHORT_STRING];
   char *ptmp;
@@ -278,11 +210,11 @@ static int imap_parse_fetch (HEADER *h, char *s)
          while (isdigit (*s))
            *ptmp++ = *s++;
          *ptmp = 0;
-         h->content->length += atoi (tmp);
+         h->content_length += atoi (tmp);
        }
        else if (*s == ')')
          s++; /* end of request */
-       else
+       else if (*s)
        {
          /* got something i don't understand */
          imap_error ("imap_parse_fetch()", s);
@@ -334,7 +266,7 @@ static int imap_read_bytes (FILE *fp, CONNECTION *conn, long bytes)
 
   for (pos = 0; pos < bytes; )
   {
-    len = imap_read_line (buf, sizeof (buf), conn);
+    len = mutt_socket_read_line (buf, sizeof (buf), conn);
     if (len < 0)
       return (-1);
     pos += len;
@@ -426,102 +358,168 @@ static int imap_handle_untagged (CONTEXT *ctx, char *s)
   return 0;
 }
 
-static int imap_read_header (CONTEXT *ctx, int msgno)
+/*
+ * Changed to read many headers instead of just one. It will return the
+ * msgno of the last message read. It will return a value other than
+ * msgend if mail comes in while downloading headers (in theory).
+ */
+static int imap_read_headers (CONTEXT *ctx, int msgbegin, int msgend)
 {
-  char buf[LONG_STRING];
+  char buf[LONG_STRING],fetchbuf[LONG_STRING];
   FILE *fp;
   char tempfile[_POSIX_PATH_MAX];
   char seq[8];
-  char *pc;
+  char *pc,*fpc,*hdr;
   char *pn;
+  long ploc;
   long bytes = 0;
+  int msgno,fetchlast;
+  IMAP_HEADER_INFO *h0,*h,*htemp;
 
-  ctx->hdrs[ctx->msgcount]->index = ctx->msgcount;
+  fetchlast = 0;
 
+  /*
+   * We now download all of the headers into one file. This should be
+   * faster on most systems.
+   */
   mutt_mktemp (tempfile);
   if (!(fp = safe_fopen (tempfile, "w+")))
   {
     return (-1);
   }
 
-  imap_make_sequence (seq, sizeof (seq), ctx);
-  snprintf (buf, sizeof (buf), "%s FETCH %d RFC822.HEADER\r\n", seq, msgno + 1);
-  imap_write (CTX_DATA->conn, buf);
-
-  do
+  h0=safe_malloc(sizeof(IMAP_HEADER_INFO));
+  h=h0;
+  for (msgno=msgbegin; msgno <= msgend ; msgno++)
   {
-    if (imap_read_line_d (buf, sizeof (buf), CTX_DATA->conn) < 0)
+    snprintf (buf, sizeof (buf), "Fetching message headers... [%d/%d]", 
+      msgno + 1, msgend + 1);
+    mutt_message (buf);
+
+    if (msgno + 1 > fetchlast)
     {
-      return (-1);
+      imap_make_sequence (seq, sizeof (seq));
+      /*
+       * Make one request for everything. This makes fetching headers an
+       * order of magnitude faster if you have a large mailbox.
+       *
+       * If we get more messages while doing this, we make another
+       * request for all the new messages.
+       */
+      snprintf (buf, sizeof (buf), "%s FETCH %d:%d (FLAGS INTERNALDATE RFC822.SIZE BODY.PEEK[HEADER.FIELDS (DATE FROM SUBJECT TO CC MESSAGE-ID REFERENCES CONTENT-TYPE IN-REPLY-TO REPLY-TO)])\r\n", seq, msgno + 1, msgend + 1);
+      mutt_socket_write (CTX_DATA->conn, buf);
+      fetchlast = msgend + 1;
     }
 
-    if (buf[0] == '*')
+    do
     {
-      pc = buf;
-      pc = imap_next_word (pc);
-      pc = imap_next_word (pc);
-      if (strncasecmp ("FETCH", pc, 5) == 0)
+      if (mutt_socket_read_line_d (buf, sizeof (buf), CTX_DATA->conn) < 0)
       {
-       if (!(pc = strchr (pc, '{')))
-       {
-         imap_error ("imap_read_header()", buf);
-         return (-1);
-       }
-       pc++;
-       pn = pc;
-       while (isdigit (*pc))
-         pc++;
-       *pc = 0;
-       bytes = atoi (pn);
+        return (-1);
+      }
 
-       imap_read_bytes (fp, CTX_DATA->conn, bytes);
+      if (buf[0] == '*')
+      {
+        pc = buf;
+        pc = imap_next_word (pc);
+        pc = imap_next_word (pc);
+        if (strncasecmp ("FETCH", pc, 5) == 0)
+        {
+          if (!(pc = strchr (pc, '(')))
+          {
+            imap_error ("imap_read_headers()", buf);
+            return (-1);
+          }
+          pc++;
+          fpc=fetchbuf;
+          while (*pc != '\0' && *pc != ')')
+          {
+            hdr=strstr(pc,"BODY");
+            strncpy(fpc,pc,hdr-pc);
+            fpc += hdr-pc;
+            *fpc = '\0';
+            pc=hdr;
+            /* get some number of bytes */
+            if (!(pc = strchr (pc, '{')))
+            {
+              imap_error ("imap_read_headers()", buf);
+              return (-1);
+            }
+            pc++;
+            pn = pc;
+            while (isdigit (*pc))
+              pc++;
+            *pc = 0;
+            bytes = atoi (pn);
+
+            imap_read_bytes (fp, CTX_DATA->conn, bytes);
+            if (mutt_socket_read_line_d (buf, sizeof (buf), CTX_DATA->conn) < 0)
+            {
+              return (-1);
+            }
+            pc = buf;
+          }
+        }
+        else if (imap_handle_untagged (ctx, buf) != 0)
+          return (-1);
       }
-      else if (imap_handle_untagged (ctx, buf) != 0)
-         return (-1);
     }
-  }
-  while (strncmp (seq, buf, SEQLEN) != 0);
-
-  rewind (fp);
-  ctx->hdrs[msgno]->env = mutt_read_rfc822_header (fp, ctx->hdrs[msgno]);
+    while ((msgno + 1) >= fetchlast && strncmp (seq, buf, SEQLEN) != 0);
 
-/* subtract the header length; the total message size will be added to this */
-  ctx->hdrs[msgno]->content->length = -bytes;
+    h->content_length = -bytes;
+    if (imap_parse_fetch (h, fetchbuf) == -1)
+      return (-1);
 
-  fclose (fp);
-  unlink (tempfile);
+    /* subtract the header length; the total message size will be
+       added to this */
 
-  /* get the status of this message */
-  imap_make_sequence (seq, sizeof (seq), ctx);
-  snprintf (buf, sizeof (buf), "%s FETCH %d FAST\r\n", seq, msgno + 1);
-  imap_write (CTX_DATA->conn, buf);
-  do
-  {
-    if (imap_read_line_d (buf, sizeof (buf), CTX_DATA->conn) < 0)
-      break;
-    if (buf[0] == '*')
+    /* in case we get new mail while fetching the headers */
+    if (((IMAP_DATA *) ctx->data)->status == IMAP_NEW_MAIL)
     {
-      pc = buf;
-      pc = imap_next_word (pc);
-      pc = imap_next_word (pc);
-      if (strncasecmp ("FETCH", pc, 5) == 0)
-      {
-       if (!(pc = strchr (pc, '(')))
-       {
-         imap_error ("imap_read_header()", buf);
-         return (-1);
-       }
-       if (imap_parse_fetch (ctx->hdrs[msgno], pc + 1) != 0)
-         return (-1);
-      }
-      else if (imap_handle_untagged (ctx, buf) != 0)
-       return (-1);
+      msgend = ((IMAP_DATA *) ctx->data)->newMailCount - 1;
+      while ((msgend + 1) > ctx->hdrmax)
+        mx_alloc_memory (ctx);
+      ((IMAP_DATA *) ctx->data)->status = 0;
     }
+
+    h->next=safe_malloc(sizeof(IMAP_HEADER_INFO));
+    h=h->next;
   }
-  while (strncmp (seq, buf, SEQLEN) != 0)
-    ;
 
-  return 0;
+  rewind(fp);
+  h=h0;
+
+  /*
+   * Now that we have all the header information, we can tell mutt about
+   * it.
+   */
+  ploc=0;
+  for (msgno = msgbegin; msgno <= msgend;msgno++)
+  {
+    ctx->hdrs[ctx->msgcount] = mutt_new_header ();
+    ctx->hdrs[ctx->msgcount]->index = ctx->msgcount;
+
+    ctx->hdrs[msgno]->env = mutt_read_rfc822_header (fp, ctx->hdrs[msgno]);
+    ploc=ftell(fp);
+    ctx->hdrs[msgno]->read = h->read;
+    ctx->hdrs[msgno]->old = h->old;
+    ctx->hdrs[msgno]->deleted = h->deleted;
+    ctx->hdrs[msgno]->flagged = h->flagged;
+    ctx->hdrs[msgno]->replied = h->replied;
+    ctx->hdrs[msgno]->changed = h->changed;
+    ctx->hdrs[msgno]->received = h->received;
+    ctx->hdrs[msgno]->content->length = h->content_length;
+
+    mx_update_context(ctx); /* increments ->msgcount */
+
+    htemp=h;
+    h=h->next;
+    safe_free((void **) &htemp);
+  }
+  fclose(fp);
+  unlink(tempfile);
+
+  return (msgend);
 }
 
 static int imap_exec (char *buf, size_t buflen,
@@ -529,11 +527,11 @@ static int imap_exec (char *buf, size_t buflen,
 {
   int count;
 
-  imap_write (CTX_DATA->conn, cmd);
+  mutt_socket_write (CTX_DATA->conn, cmd);
 
   do
   {
-    if (imap_read_line_d (buf, buflen, CTX_DATA->conn) < 0)
+    if (mutt_socket_read_line_d (buf, buflen, CTX_DATA->conn) < 0)
       return (-1);
 
     if (buf[0] == '*' && imap_handle_untagged (ctx, buf) != 0)
@@ -546,7 +544,6 @@ static int imap_exec (char *buf, size_t buflen,
     /* read new mail messages */
 
     dprint (1, (debugfile, "imap_exec(): new mail detected\n"));
-    mutt_message ("Fetching headers for new mail...");
 
     CTX_DATA->status = 0;
 
@@ -554,23 +551,7 @@ static int imap_exec (char *buf, size_t buflen,
     while (count > ctx->hdrmax)
       mx_alloc_memory (ctx);
 
-    while (ctx->msgcount < count)
-    {
-      ctx->hdrs[ctx->msgcount] = mutt_new_header ();
-      imap_read_header (ctx, ctx->msgcount);
-      mx_update_context (ctx); /* incremements ->msgcount */
-      
-      /* check to make sure that new mail hasn't arrived in the middle of
-       * checking for new mail (sigh)
-       */
-      if (CTX_DATA->status == IMAP_NEW_MAIL)
-      {
-       count = CTX_DATA->newMailCount;
-       while (count > ctx->hdrmax)
-         mx_alloc_memory (ctx);
-       CTX_DATA->status = 0;
-      }
-    }
+    count=imap_read_headers (ctx, ctx->msgcount, count - 1) + 1;
 
     mutt_clear_error ();
   }
@@ -593,8 +574,30 @@ static int imap_exec (char *buf, size_t buflen,
   return 0;
 }
 
+static int imap_parse_path (char *path, char *host, size_t hlen, char **mbox)
+{
+  int n;
+  char *pc;
+
+  pc = path;
+  if (*pc != '{')
+    return (-1);
+  pc++;
+  n = 0;
+  while (*pc && *pc != '}' && (n < hlen-1))
+    host[n++] = *pc++;
+  host[n] = 0;
+  if (!*pc)
+    return (-1);
+  pc++;
+
+  *mbox = pc;
+  return 0;
+}
+
 static int imap_open_connection (CONTEXT *ctx, CONNECTION *conn)
 {
+  char *portnum, *hostname;
   struct sockaddr_in sin;
   struct hostent *he;
   char buf[LONG_STRING];
@@ -602,40 +605,19 @@ static int imap_open_connection (CONTEXT *ctx, CONNECTION *conn)
   char pass[SHORT_STRING];
   char seq[16];
 
-  if (!ImapUser)
-  {
-    strfcpy (user, Username, sizeof (user));
-    if (mutt_get_field ("IMAP Username: ", user, sizeof (user), 0) != 0 ||
-        !user[0])
-    {
-      user[0] = 0;
-      return (-1);
-    }
-  }
-  else
-    strfcpy (user, ImapUser, sizeof (user));
-
-  if (!ImapPass)
-  {
-    pass[0]=0;
-    snprintf (buf, sizeof (buf), "Password for %s@%s: ", user, conn->server);
-    if (mutt_get_field (buf, pass, sizeof (pass), M_PASS) != 0 ||
-        !pass[0])
-    {
-      return (-1);
-    }
-  }
-  else
-    strfcpy (pass, ImapPass, sizeof (pass));
-
   memset (&sin, 0, sizeof (sin));
-  sin.sin_port = htons (IMAP_PORT);
+  hostname = safe_strdup(conn->server);
+  portnum = strrchr(hostname, ':');
+  if(portnum) { *portnum=0; portnum++; }
+  sin.sin_port = htons (portnum ? atoi(portnum) : IMAP_PORT);
   sin.sin_family = AF_INET;
-  if ((he = gethostbyname (conn->server)) == NULL)
+  if ((he = gethostbyname (hostname)) == NULL)
   {
+    safe_free((void*)&hostname);
     mutt_perror (conn->server);
     return (-1);
   }
+  safe_free((void*)&hostname);
   memcpy (&sin.sin_addr, he->h_addr_list[0], he->h_length);
 
   if ((conn->fd = socket (AF_INET, SOCK_STREAM, IPPROTO_IP)) < 0)
@@ -652,34 +634,60 @@ static int imap_open_connection (CONTEXT *ctx, CONNECTION *conn)
     close (conn->fd);
   }
 
-  if (imap_read_line_d (buf, sizeof (buf), conn) < 0)
+  if (mutt_socket_read_line_d (buf, sizeof (buf), conn) < 0)
   {
     close (conn->fd);
     return (-1);
   }
 
-  if (strncmp ("* OK", buf, 4) != 0)
+  if (strncmp ("* OK", buf, 4) == 0)
   {
-    imap_error ("imap_open_connection()", buf);
-    close (conn->fd);
-    return (-1);
-  }
+    if (!ImapUser)
+    {
+      strfcpy (user, NONULL(Username), sizeof (user));
+      if (mutt_get_field ("IMAP Username: ", user, sizeof (user), 0) != 0 ||
+         !user[0])
+      {
+       user[0] = 0;
+       return (-1);
+      }
+    }
+    else
+      strfcpy (user, ImapUser, sizeof (user));
 
-  mutt_message ("Logging in...");
-  /* sequence numbers are currently context dependent, so just make one
-   * up for this first access to the server */
-  strcpy (seq, "l0000");
-  snprintf (buf, sizeof (buf), "%s LOGIN %s %s\r\n", seq, user, pass);
-  if (imap_exec (buf, sizeof (buf), ctx, seq, buf, 0) != 0)
+    if (!ImapPass)
+    {
+      pass[0]=0;
+      snprintf (buf, sizeof (buf), "Password for %s@%s: ", user, conn->server);
+      if (mutt_get_field (buf, pass, sizeof (pass), M_PASS) != 0 ||
+         !pass[0])
+      {
+       return (-1);
+      }
+    }
+    else
+      strfcpy (pass, ImapPass, sizeof (pass));
+
+    mutt_message ("Logging in...");
+    imap_make_sequence (seq, sizeof (seq));
+    snprintf (buf, sizeof (buf), "%s LOGIN %s %s\r\n", seq, user, pass);
+    if (imap_exec (buf, sizeof (buf), ctx, seq, buf, 0) != 0)
+      {
+       imap_error ("imap_open_connection()", buf);
+       return (-1);
+      }
+    /* If they have a successful login, we may as well cache the user/password. */
+    if (!ImapUser)
+      ImapUser = safe_strdup (user);
+    if (!ImapPass)
+      ImapPass = safe_strdup (pass);
+  }
+  else if (strncmp ("* PREAUTH", buf, 9) != 0)
   {
     imap_error ("imap_open_connection()", buf);
+    close (conn->fd);
     return (-1);
   }
-  /* If they have a successful login, we may as well cache the user/password. */
-  if (!ImapUser)
-    ImapUser = safe_strdup (user);
-  if (!ImapPass)
-    ImapPass = safe_strdup (pass);
 
   return 0;
 }
@@ -691,29 +699,20 @@ int imap_open_mailbox (CONTEXT *ctx)
   char bufout[LONG_STRING];
   char host[SHORT_STRING];
   char seq[16];
+  char *pc = NULL;
   int count = 0;
   int n;
-  char *pc;
+
+  if (imap_parse_path (ctx->path, host, sizeof (host), &pc))
+    return (-1);
 
   /* create IMAP-specific state struct */
   ctx->data = safe_malloc (sizeof (IMAP_DATA));
   memset (ctx->data, 0, sizeof (IMAP_DATA));
 
-  pc = ctx->path;
-  if (*pc != '{')
-    return (-1);
-  pc++;
-  n = 0;
-  while (*pc && *pc != '}')
-    host[n++] = *pc++;
-  host[n] = 0;
-  if (!*pc)
-    return (-1);
-  pc++;
-
   CTX_DATA->mailbox = safe_strdup (pc);
 
-  conn = imap_select_connection (host, IMAP_OPEN_NEW);
+  conn = mutt_socket_select_connection (host, IMAP_PORT, M_NEW_SOCKET);
   CTX_DATA->conn = conn;
 
   if (conn->uses == 0)
@@ -722,13 +721,13 @@ int imap_open_mailbox (CONTEXT *ctx)
   conn->uses++;
 
   mutt_message ("Selecting %s...", CTX_DATA->mailbox);
-  imap_make_sequence (seq, sizeof (seq), ctx);
+  imap_make_sequence (seq, sizeof (seq));
   snprintf (bufout, sizeof (bufout), "%s SELECT %s\r\n", seq, CTX_DATA->mailbox);
-  imap_write (CTX_DATA->conn, bufout);
+  mutt_socket_write (CTX_DATA->conn, bufout);
 
   do
   {
-    if (imap_read_line_d (buf, sizeof (buf), CTX_DATA->conn) < 0)
+    if (mutt_socket_read_line_d (buf, sizeof (buf), CTX_DATA->conn) < 0)
       break;
 
     if (buf[0] == '*')
@@ -756,32 +755,8 @@ int imap_open_mailbox (CONTEXT *ctx)
   ctx->hdrmax = count;
   ctx->hdrs = safe_malloc (count * sizeof (HEADER *));
   ctx->v2r = safe_malloc (count * sizeof (int));
-  for (ctx->msgcount = 0; ctx->msgcount < count; )
-  {
-    snprintf (buf, sizeof (buf), "Fetching message headers... [%d/%d]", 
-      ctx->msgcount + 1, count);
-    mutt_message (buf);
-    ctx->hdrs[ctx->msgcount] = mutt_new_header ();
-
-    /* `count' can get modified if new mail arrives while fetching the
-     * header for this message
-     */
-    if (imap_read_header (ctx, ctx->msgcount) != 0)
-    {
-      mx_fastclose_mailbox (ctx);
-      return (-1);
-    }
-    mx_update_context (ctx); /* increments ->msgcount */
-
-    /* in case we get new mail while fetching the headers */
-    if (CTX_DATA->status == IMAP_NEW_MAIL)
-    {
-      count = CTX_DATA->newMailCount;
-      while (count > ctx->hdrmax)
-       mx_alloc_memory (ctx);
-      CTX_DATA->status = 0;
-    }
-  }
+  ctx->msgcount = 0;
+  count=imap_read_headers (ctx, 0, count - 1) + 1;
 
   return 0;
 }
@@ -791,7 +766,7 @@ static int imap_create_mailbox (CONTEXT *ctx)
   char seq[8];
   char buf[LONG_STRING];
 
-  imap_make_sequence (seq, sizeof (seq), ctx);
+  imap_make_sequence (seq, sizeof (seq));
   snprintf (buf, sizeof (buf), "%s CREATE %s\r\n", seq, CTX_DATA->mailbox);
       
   if (imap_exec (buf, sizeof (buf), ctx, seq, buf, 0) != 0)
@@ -808,28 +783,19 @@ int imap_open_mailbox_append (CONTEXT *ctx)
   char host[SHORT_STRING];
   char buf[LONG_STRING];
   char seq[16];
-  int n;
   char *pc;
 
+  if (imap_parse_path (ctx->path, host, sizeof (host), &pc))
+    return (-1);
+
   /* create IMAP-specific state struct */
   ctx->data = safe_malloc (sizeof (IMAP_DATA));
   memset (ctx->data, 0, sizeof (IMAP_DATA));
-
-  pc = ctx->path;
-  if (*pc != '{')
-    return (-1);
-  pc++;
-  n = 0;
-  while (*pc && *pc != '}')
-    host[n++] = *pc++;
-  host[n] = 0;
-  if (!*pc)
-    return (-1);
-  pc++;
+  ctx->magic = M_IMAP;
 
   CTX_DATA->mailbox = pc;
 
-  conn = imap_select_connection (host, 0);
+  conn = mutt_socket_select_connection (host, IMAP_PORT, 0);
   CTX_DATA->conn = conn;
 
   if (conn->uses == 0)
@@ -839,7 +805,7 @@ int imap_open_mailbox_append (CONTEXT *ctx)
 
   /* check mailbox existance */
 
-  imap_make_sequence (seq, sizeof (seq), ctx);
+  imap_make_sequence (seq, sizeof (seq));
   snprintf (buf, sizeof (buf), "%s STATUS %s (UIDVALIDITY)\r\n", seq, 
       CTX_DATA->mailbox);
       
@@ -865,6 +831,7 @@ int imap_fetch_message (MESSAGE *msg, CONTEXT *ctx, int msgno)
   char *pc;
   char *pn;
   long bytes;
+  int pos,len,onbody=0;
   IMAP_CACHE *cache;
 
   /* see if we already have the message in our cache */
@@ -886,7 +853,7 @@ int imap_fetch_message (MESSAGE *msg, CONTEXT *ctx, int msgno)
     {
       /* clear the previous entry */
       unlink (cache->path);
-      free (cache->path);
+      FREE (&cache->path);
     }
   }
 
@@ -901,13 +868,13 @@ int imap_fetch_message (MESSAGE *msg, CONTEXT *ctx, int msgno)
     return (-1);
   }
 
-  imap_make_sequence (seq, sizeof (seq), ctx);
+  imap_make_sequence (seq, sizeof (seq));
   snprintf (buf, sizeof (buf), "%s FETCH %d RFC822\r\n", seq,
            ctx->hdrs[msgno]->index + 1);
-  imap_write (CTX_DATA->conn, buf);
+  mutt_socket_write (CTX_DATA->conn, buf);
   do
   {
-    if (imap_read_line (buf, sizeof (buf), CTX_DATA->conn) < 0)
+    if (mutt_socket_read_line (buf, sizeof (buf), CTX_DATA->conn) < 0)
     {
       return (-1);
     }
@@ -930,7 +897,25 @@ int imap_fetch_message (MESSAGE *msg, CONTEXT *ctx, int msgno)
          pc++;
        *pc = 0;
        bytes = atoi (pn);
-       imap_read_bytes (msg->fp, CTX_DATA->conn, bytes);
+       for (pos = 0; pos < bytes; )
+       {
+         len = mutt_socket_read_line (buf, sizeof (buf), CTX_DATA->conn);
+         if (len < 0)
+           return (-1);
+         pos += len;
+         fputs (buf, msg->fp);
+         fputs ("\n", msg->fp);
+         if (! onbody && len == 2)
+         {
+           /*
+            * This is the first time we really know how long the full
+            * header is. We must set it now, or mutt will not display
+            * the message properly
+            */
+           ctx->hdrs[msgno]->content->offset=ftell(msg->fp);
+           onbody=1;
+         }
+       }
       }
       else if (imap_handle_untagged (ctx, buf) != 0)
        return (-1);
@@ -947,35 +932,47 @@ int imap_fetch_message (MESSAGE *msg, CONTEXT *ctx, int msgno)
   return 0;
 }
 
+static void
+flush_buffer(char *buf, size_t *len, CONNECTION *conn)
+{
+  buf[*len] = '\0';
+  mutt_socket_write(conn, buf);
+  *len = 0;
+}
+
 int imap_append_message (CONTEXT *ctx, MESSAGE *msg)
 {
   FILE *fp;
-  struct stat s;
   char seq[8];
   char buf[LONG_STRING];
-
-  if (stat (msg->path, &s) == -1)
+  size_t len;
+  int c, last;
+  
+  if ((fp = fopen (msg->path, "r")) == NULL)
   {
     mutt_perror (msg->path);
     return (-1);
   }
 
-  if ((fp = safe_fopen (msg->path, "r")) == NULL)
+  for(last = EOF, len = 0; (c = fgetc(fp)) != EOF; last = c)
   {
-    mutt_perror (msg->path);
-    return (-1);
-  }
+    if(c == '\n' && last != '\r')
+      len++;
 
+    len++;
+  }
+  rewind(fp);
+  
   mutt_message ("Sending APPEND command ...");
-  imap_make_sequence (seq, sizeof (seq), ctx);
+  imap_make_sequence (seq, sizeof (seq));
   snprintf (buf, sizeof (buf), "%s APPEND %s {%d}\r\n", seq, 
-      CTX_DATA->mailbox, s.st_size);
+      CTX_DATA->mailbox, len);
 
-  imap_write (CTX_DATA->conn, buf);
+  mutt_socket_write (CTX_DATA->conn, buf);
 
   do 
   {
-    if (imap_read_line_d (buf, sizeof (buf), CTX_DATA->conn) < 0)
+    if (mutt_socket_read_line_d (buf, sizeof (buf), CTX_DATA->conn) < 0)
     {
       fclose (fp);
       return (-1);
@@ -1005,16 +1002,28 @@ int imap_append_message (CONTEXT *ctx, MESSAGE *msg)
   }
 
   mutt_message ("Uploading message ...");
-  while (fgets (buf, sizeof (buf), fp) != NULL)
+
+  for(last = EOF, len = 0; (c = fgetc(fp)) != EOF; last = c)
   {
-    imap_write (CTX_DATA->conn, buf);
+    if(c == '\n' && last != '\r')
+      buf[len++] = '\r';
+
+    buf[len++] = c;
+
+    if(len > sizeof(buf) - 3)
+      flush_buffer(buf, &len, CTX_DATA->conn);
   }
-  imap_write (CTX_DATA->conn, "\r\n");
+  
+  if(len)
+    flush_buffer(buf, &len, CTX_DATA->conn);
+
+    
+  mutt_socket_write (CTX_DATA->conn, "\r\n");
   fclose (fp);
 
   do
   {
-    if (imap_read_line_d (buf, sizeof (buf), CTX_DATA->conn) < 0)
+    if (mutt_socket_read_line_d (buf, sizeof (buf), CTX_DATA->conn) < 0)
       return (-1);
 
     if (buf[0] == '*' && imap_handle_untagged (ctx, buf) != 0)
@@ -1043,23 +1052,24 @@ int imap_close_connection (CONTEXT *ctx)
   char buf[LONG_STRING];
   char seq[8];
 
+  dprint (1, (debugfile, "imap_close_connection(): closing connection\n"));
   /* if the server didn't shut down on us, close the connection gracefully */
   if (CTX_DATA->status != IMAP_BYE)
   {
     mutt_message ("Closing connection to IMAP server...");
-    imap_make_sequence (seq, sizeof (seq), ctx);
+    imap_make_sequence (seq, sizeof (seq));
     snprintf (buf, sizeof (buf), "%s LOGOUT\r\n", seq);
-    imap_write (CTX_DATA->conn, buf);
+    mutt_socket_write (CTX_DATA->conn, buf);
     do
     {
-      if (imap_read_line_d (buf, sizeof (buf), CTX_DATA->conn) < 0)
+      if (mutt_socket_read_line_d (buf, sizeof (buf), CTX_DATA->conn) < 0)
        break;
     }
     while (strncmp (seq, buf, SEQLEN) != 0);
     mutt_clear_error ();
   }
   close (CTX_DATA->conn->fd);
-  CTX_DATA->conn->uses--;
+  CTX_DATA->conn->uses = 0;
   return 0;
 }
 
@@ -1090,7 +1100,7 @@ int imap_sync_mailbox (CONTEXT *ctx)
       mutt_remove_trailing_ws (tmp);
 
       if (!*tmp) continue; /* imapd doesn't like empty flags. */
-      imap_make_sequence (seq, sizeof (seq), ctx);
+      imap_make_sequence (seq, sizeof (seq));
       snprintf (buf, sizeof (buf), "%s STORE %d FLAGS.SILENT (%s)\r\n", seq, 
        ctx->hdrs[n]->index + 1, tmp);
       if (imap_exec (buf, sizeof (buf), ctx, seq, buf, 0) != 0)
@@ -1103,7 +1113,7 @@ int imap_sync_mailbox (CONTEXT *ctx)
 
   mutt_message ("Expunging messages from server...");
   CTX_DATA->status = IMAP_EXPUNGE;
-  imap_make_sequence (seq, sizeof (seq), ctx);
+  imap_make_sequence (seq, sizeof (seq));
   snprintf (buf, sizeof (buf), "%s EXPUNGE\r\n", seq);
   if (imap_exec (buf, sizeof (buf), ctx, seq, buf, 0) != 0)
   {
@@ -1131,7 +1141,9 @@ void imap_fastclose_mailbox (CONTEXT *ctx)
   /* Check to see if the mailbox is actually open */
   if (!ctx->data)
     return;
-  imap_close_connection (ctx);
+  CTX_DATA->conn->uses--;
+  if ((CTX_DATA->conn->uses == 0) || (CTX_DATA->status == IMAP_BYE))
+    imap_close_connection (ctx);
   for (i = 0; i < IMAP_CACHE_LEN; i++)
   {
     if (CTX_DATA->cache[i].path)
@@ -1151,7 +1163,7 @@ int imap_close_mailbox (CONTEXT *ctx)
 
   /* tell the server to commit changes */
   mutt_message ("Closing mailbox...");
-  imap_make_sequence (seq, sizeof (seq), ctx);
+  imap_make_sequence (seq, sizeof (seq));
   snprintf (buf, sizeof (buf), "%s CLOSE\r\n", seq);
   if (imap_exec (buf, sizeof (buf), ctx, seq, buf, 0) != 0)
   {
@@ -1176,7 +1188,7 @@ int imap_check_mailbox (CONTEXT *ctx, int *index_hint)
     checktime=k;
   }
 
-  imap_make_sequence (seq, sizeof (seq), ctx);
+  imap_make_sequence (seq, sizeof (seq));
   snprintf (buf, sizeof (buf), "%s NOOP\r\n", seq);
   if (imap_exec (buf, sizeof (buf), ctx, seq, buf, 0) != 0)
   {
@@ -1186,3 +1198,78 @@ int imap_check_mailbox (CONTEXT *ctx, int *index_hint)
 
   return (msgcount != ctx->msgcount);
 }
+
+int imap_buffy_check (char *path)
+{
+  CONNECTION *conn;
+  char host[SHORT_STRING];
+  char buf[LONG_STRING];
+  char seq[8];
+  char *mbox;
+  char *s;
+  char recent = FALSE;
+
+  if (imap_parse_path (path, host, sizeof (host), &mbox))
+    return -1;
+
+  conn = mutt_socket_select_connection (host, IMAP_PORT, 0);
+
+  /* Currently, we don't open a connection to check, but we'll check
+   * over an existing connection */
+  if (conn->uses == 0)
+      return (-1);
+  conn->uses++;
+
+  imap_make_sequence (seq, sizeof (seq));
+  snprintf (buf, sizeof (buf), "%s STATUS %s (RECENT)\r\n", seq, mbox);
+
+  mutt_socket_write (conn, buf);
+
+  do 
+  {
+    if (mutt_socket_read_line_d (buf, sizeof (buf), conn) < 0)
+    {
+      return (-1);
+    }
+
+    /* BUG: We don't handle other untagged messages here.  This is
+     * actually because of a more general problem in that this
+     * connection is being used for a different mailbox, and all
+     * untagged messages we don't handle here (ie, STATUS) need to be
+     * sent to imap_handle_untagged() but with the CONTEXT of the
+     * currently selected mailbox.  The same is broken in the APPEND
+     * stuff above.
+     */
+/*    if (buf[0] == '*' && imap_handle_untagged (ctx, buf) != 0) */
+    if (buf[0] == '*')
+    {
+      s = imap_next_word (buf);
+      if (strncasecmp ("STATUS", s, 6) == 0)
+      {
+       s = imap_next_word (s);
+       if (strncmp (mbox, s, strlen (mbox)) == 0)
+       {
+         s = imap_next_word (s);
+         s = imap_next_word (s);
+         if (isdigit (*s))
+         {
+           if (*s != '0')
+           {
+             dprint (1, (debugfile, "New mail in %s\n", path));
+             recent = TRUE;
+           }
+         }
+       }
+      }
+      else
+      {
+       mutt_error ("BUG! Untagged IMAP Response during BUFFY Check");
+      }
+    }
+  }
+  while ((strncmp (buf, seq, SEQLEN) != 0));
+
+  conn->uses--;
+
+  return recent;
+}
diff --git a/imap.h b/imap.h
index ce18c723f443dc638c0f0a9e03d8bc409bcd7355..d7c1357c612e83fd7b5acb0692fe25c7fbffa1d2 100644 (file)
--- a/imap.h
+++ b/imap.h
@@ -26,5 +26,6 @@ extern int imap_open_mailbox (CONTEXT *ctx);
 extern int imap_open_mailbox_append (CONTEXT *ctx);
 extern int imap_sync_mailbox (CONTEXT *ctx);
 extern void imap_fastclose_mailbox (CONTEXT *ctx);
+extern int imap_buffy_check (char *path);
 
 #endif
diff --git a/init.c b/init.c
index d4ae189773be80bae1abf97e5788477796e086c0..95cdee93f9f7e98858f547e1904cdac9bbca40fe 100644 (file)
--- a/init.c
+++ b/init.c
  */ 
 
 #include "mutt.h"
+#include "mapping.h"
 #include "mutt_curses.h"
 #include "mutt_regex.h"
-
+#include "history.h"
 
 
 #ifdef _PGPPATH
@@ -168,9 +169,9 @@ int mutt_extract_token (BUFFER *dest, BUFFER *tok, int flags)
          add_char (dest, '\033');
          break;
        default:
-         if (isdigit (ch) &&
-             isdigit (*tok->dptr) &&
-             isdigit (*(tok->dptr + 1)))
+         if (isdigit ((unsigned char) ch) &&
+             isdigit ((unsigned char) *tok->dptr) &&
+             isdigit ((unsigned char) *(tok->dptr + 1)))
          {
 
            add_char (dest, (ch << 6) + (*tok->dptr << 3) + *(tok->dptr + 1) - 3504);
@@ -187,7 +188,7 @@ int mutt_extract_token (BUFFER *dest, BUFFER *tok, int flags)
        add_char (dest, ch);
       else if (ch == '[')
        add_char (dest, '\033');
-      else if (isalpha (ch))
+      else if (isalpha ((unsigned char) ch))
        add_char (dest, toupper (ch) - '@');
       else
       {
@@ -252,7 +253,7 @@ int mutt_extract_token (BUFFER *dest, BUFFER *tok, int flags)
        FREE (&expn.data);
       }
     }
-    else if (ch == '$' && (!qc || qc == '"') && (*tok->dptr == '{' || isalpha (*tok->dptr)))
+    else if (ch == '$' && (!qc || qc == '"') && (*tok->dptr == '{' || isalpha ((unsigned char) *tok->dptr)))
     {
       char *env, *var;
 
@@ -267,7 +268,7 @@ int mutt_extract_token (BUFFER *dest, BUFFER *tok, int flags)
       }
       else
       {
-       for (pc = tok->dptr; isalpha (*pc) || *pc == '_'; pc++)
+       for (pc = tok->dptr; isalpha ((unsigned char) *pc) || *pc == '_'; pc++)
          ;
        var = mutt_substrdup (tok->dptr, pc);
        tok->dptr = pc;
@@ -629,18 +630,36 @@ static void mutt_restore_default (struct option_t *p)
     case DT_RX:
       {
        REGEXP *pp = (REGEXP *) p->data;
+       int flags = 0;
+
        FREE (&pp->pattern);
+       if (pp->rx)
+       {
+         regfree (pp->rx);
+         FREE (&pp->rx);
+       }
        if (p->init)
        {
-         if (pp->rx)
-           regfree (pp->rx);
-         else
-           pp->rx = safe_calloc (1, sizeof (regex_t));
+         char *s = (char *) p->init;
+
+         pp->rx = safe_calloc (1, sizeof (regex_t));
          pp->pattern = safe_strdup ((char *) p->init);
-         if (REGCOMP (pp->rx, pp->pattern, mutt_which_case (pp->pattern)) != 0)
+         if (strcmp (p->option, "alternates") == 0)
+           flags |= REG_ICASE;
+         else if (strcmp (p->option, "mask") != 0)
+           flags |= mutt_which_case ((const char *) p->init);
+         if (strcmp (p->option, "mask") == 0 && *s == '!')
+         {
+           s++;
+           pp->not = 1;
+         }
+         if (REGCOMP (pp->rx, s, flags) != 0)
          {
            fprintf (stderr, "mutt_restore_default: error in regexp: %s\n",
                     pp->pattern);
+           FREE (&pp->pattern);
+           regfree (pp->rx);
+           FREE (&pp->rx);
          }
        }
       }
@@ -794,15 +813,27 @@ static int parse_set (BUFFER *tmp, BUFFER *s, unsigned long data, BUFFER *err)
 
       if (!ptr->pattern || strcmp (ptr->pattern, tmp->data) != 0)
       {
+       int not = 0;
+
        /* $alternates is case-insensitive,
           $mask is case-sensitive */
        if (strcmp (MuttVars[idx].option, "alternates") == 0)
          flags |= REG_ICASE;
        else if (strcmp (MuttVars[idx].option, "mask") != 0)
          flags |= mutt_which_case (tmp->data);
-       
+
+       p = tmp->data;
+       if (strcmp (MuttVars[idx].option, "mask") == 0)
+       {
+         if (*p == '!')
+         {
+           not = 1;
+           p++;
+         }
+       }
+         
        rx = (regex_t *) safe_malloc (sizeof (regex_t));
-       if ((e = REGCOMP (rx, tmp->data, flags)) != 0)
+       if ((e = REGCOMP (rx, p, flags)) != 0)
        {
          regerror (e, rx, err->data, err->dsize);
          regfree (rx);
@@ -820,6 +851,7 @@ static int parse_set (BUFFER *tmp, BUFFER *s, unsigned long data, BUFFER *err)
 
        ptr->pattern = safe_strdup (tmp->data);
        ptr->rx = rx;
+       ptr->not = not;
 
        /* $reply_regexp requires special treatment */
        if (Context && Context->msgcount &&
@@ -1158,12 +1190,12 @@ int mutt_command_complete (char *buffer, size_t len, int pos)
   strncpy (cmd, buffer, pos);
   pt = cmd;
   pt[pos] = 0;
-  while (!isspace (*pt))
+  while (!isspace ((unsigned char) *pt))
     pt++;
   *pt = 0;
 
   pt = buffer + pos;
-  while ((pt > buffer) && !isspace (*pt))
+  while ((pt > buffer) && !isspace ((unsigned char) *pt))
     pt--;
   if (pt == buffer) /* complete cmd */
   {
@@ -1174,16 +1206,46 @@ int mutt_command_complete (char *buffer, size_t len, int pos)
       return 0;
     strncpy (buffer, completed, len);
   }
-  else if (!strncasecmp (cmd, "set", 3)
-          || !strncasecmp (cmd, "unset", 5)
-          || !strncasecmp (cmd, "toggle", 6))
+  else if (!strcasecmp (cmd, "set")
+          || !strcasecmp (cmd, "unset")
+          || !strcasecmp (cmd, "reset")
+          || !strcasecmp (cmd, "toggle"))
   {            /* complete variables */
+    char *prefixes[] = { "no", "inv", "?", "&", 0 };
+    int  prefix_index;
+    char tmpbuffer[STRING];
+    int  prefix_len;
+
+    /* remember if the command is set to decide whether we want to attempt the
+     * prefixes */
+    int  cmd_is_set = !strcasecmp (cmd, "set"); 
+    
     pt++;
     if (*pt == 0)
       return 0;
     strncpy (cmd, pt, sizeof (cmd));
     for (num = 0; MuttVars[num].option; num++)
       candidate (completed, cmd, MuttVars[num].option, sizeof (completed));
+  
+    if ( cmd_is_set ) {
+      /* loop through all the possible prefixes (no, inv, ...) */
+      for ( prefix_index = 0; prefixes[prefix_index]; prefix_index++ )
+      {
+        prefix_len = strlen(prefixes[prefix_index]);
+        strncpy( tmpbuffer, prefixes[prefix_index], sizeof(tmpbuffer) );
+  
+        /* if the current option is prepended with the prefix */
+        if ( !strncasecmp(cmd, tmpbuffer, prefix_len )) {
+          for (num = 0; MuttVars[num].option; num++) {
+            strncpy( &tmpbuffer[prefix_len], 
+                     MuttVars[num].option, 
+                     sizeof(tmpbuffer) - prefix_len );
+            candidate (completed, cmd, tmpbuffer, sizeof (completed));
+          }
+        }
+      }
+    }
+
     if (completed[0] == 0)
       return 0;
     strncpy (pt, completed, buffer + len - pt);
@@ -1224,8 +1286,8 @@ static void start_debug (void)
   /* rotate the old debug logs */
   for (i=3; i>=0; i--)
   {
-    snprintf (buf, sizeof(buf), "%s/.muttdebug%d", Homedir, i);
-    snprintf (buf2, sizeof(buf2), "%s/.muttdebug%d", Homedir, i+1);
+    snprintf (buf, sizeof(buf), "%s/.muttdebug%d", NONULL(Homedir), i);
+    snprintf (buf2, sizeof(buf2), "%s/.muttdebug%d", NONULL(Homedir), i+1);
     rename (buf, buf2);
   }
   if ((debugfile = safe_fopen(buf, "w")) != NULL)
@@ -1332,12 +1394,8 @@ void mutt_init (int skip_sys_rc, LIST *commands)
   else
 #endif /* DOMAIN */
   {
-# ifdef HIDDEN_HOST
-    Fqdn = safe_strdup (DOMAIN);
-# else
-    Fqdn = safe_malloc (strlen (DOMAIN) + strlen (Hostname) + 2);
-    sprintf (Fqdn, "%s.%s", Hostname, DOMAIN);
-# endif /* HIDDEN_HOST */
+    Fqdn = safe_malloc (strlen (DOMAIN) + strlen (NONULL(Hostname)) + 2);
+    sprintf (Fqdn, "%s.%s", NONULL(Hostname), DOMAIN);
   }
 
   if ((p = getenv ("MAIL")))
@@ -1345,9 +1403,9 @@ void mutt_init (int skip_sys_rc, LIST *commands)
   else
   {
 #ifdef HOMESPOOL
-    snprintf (buffer, sizeof (buffer), "%s/%s", Homedir, MAILPATH);
+    snprintf (buffer, sizeof (buffer), "%s/%s", NONULL(Homedir), MAILPATH);
 #else
-    snprintf (buffer, sizeof (buffer), "%s/%s", MAILPATH, Username);
+    snprintf (buffer, sizeof (buffer), "%s/%s", MAILPATH, NONULL(Username));
 #endif
     Spoolfile = safe_strdup (buffer);
   }
@@ -1376,9 +1434,9 @@ void mutt_init (int skip_sys_rc, LIST *commands)
   }
   else
   {
-    snprintf (buffer, sizeof (buffer), "%s/.pgp/pubring.pgp", Homedir);
+    snprintf (buffer, sizeof (buffer), "%s/.pgp/pubring.pgp", NONULL(Homedir));
     PgpV2Pubring = safe_strdup (buffer);
-    snprintf (buffer, sizeof (buffer), "%s/.pgp/secring.pgp", Homedir);
+    snprintf (buffer, sizeof (buffer), "%s/.pgp/secring.pgp", NONULL(Homedir));
     PgpV2Secring = safe_strdup (buffer);
   }
 #endif
@@ -1394,9 +1452,9 @@ void mutt_init (int skip_sys_rc, LIST *commands)
   }
   else
   {
-    snprintf (buffer, sizeof (buffer), "%s/.pgp/pubring.pkr", Homedir);
+    snprintf (buffer, sizeof (buffer), "%s/.pgp/pubring.pkr", NONULL(Homedir));
     PgpV3Pubring = safe_strdup (buffer);
-    snprintf (buffer, sizeof (buffer), "%s/.pgp/secring.skr", Homedir);
+    snprintf (buffer, sizeof (buffer), "%s/.pgp/secring.skr", NONULL(Homedir));
     PgpV3Secring = safe_strdup (buffer);
   }
 #endif
@@ -1447,9 +1505,9 @@ void mutt_init (int skip_sys_rc, LIST *commands)
 
   if (!Muttrc)
   {
-    snprintf (buffer, sizeof (buffer), "%s/.muttrc-%s", Homedir, VERSION);
+    snprintf (buffer, sizeof (buffer), "%s/.muttrc-%s", NONULL(Homedir), VERSION);
     if (access (buffer, F_OK) == -1)
-      snprintf (buffer, sizeof (buffer), "%s/.muttrc", Homedir);
+      snprintf (buffer, sizeof (buffer), "%s/.muttrc", NONULL(Homedir));
     default_rc = 1;
     Muttrc = safe_strdup (buffer);
   }
@@ -1461,7 +1519,7 @@ void mutt_init (int skip_sys_rc, LIST *commands)
     Muttrc = safe_strdup (buffer);
   }
   FREE (&AliasFile);
-  AliasFile = safe_strdup (Muttrc);
+  AliasFile = safe_strdup (NONULL(Muttrc));
 
   /* Process the global rc file if it exists and the user hasn't explicity
      requested not to via "-n".  */
diff --git a/init.h b/init.h
index 452b4988b1f02240d2395dfeb627983703dfd5a0..397a8237a98ff8d6202857c34c07e8111cbdff2e 100644 (file)
--- a/init.h
+++ b/init.h
@@ -77,6 +77,9 @@ struct option_t MuttVars[] = {
   { "ascii_chars",     DT_BOOL, R_BOTH, OPTASCIICHARS, 0 },
   { "askbcc",          DT_BOOL, R_NONE, OPTASKBCC, 0 },
   { "askcc",           DT_BOOL, R_NONE, OPTASKCC, 0 },
+  { "attach_format",   DT_STR,  R_NONE, UL &AttachFormat, UL "%u%D%t%2n %T%.40d%> [%.7m/%.10M, %.6e, %s] " },
+  { "attach_split",    DT_BOOL, R_NONE, OPTATTACHSPLIT, 1 },
+  { "attach_sep",      DT_STR,  R_NONE, UL &AttachSep, UL "\n" },
   { "attribution",     DT_STR,  R_NONE, UL &Attribution, UL "On %d, %n wrote:" },
   { "autoedit",                DT_BOOL, R_NONE, OPTAUTOEDIT, 0 },
   { "auto_tag",                DT_BOOL, R_NONE, OPTAUTOTAG, 0 },
@@ -96,7 +99,6 @@ struct option_t MuttVars[] = {
   { "edit_headers",    DT_BOOL, R_NONE, OPTEDITHDRS, 0 },
   { "edit_hdrs",       DT_SYN,  R_NONE, UL "edit_headers", 0 },
   { "editor",          DT_PATH, R_NONE, UL &Editor, 0 },
-  { "empty_to",                DT_STR,  R_NONE, UL &EmptyTo, UL "undisclosed-recipients" },
   { "escape",          DT_STR,  R_NONE, UL &EscChar, UL "~" },
   { "fast_reply",      DT_BOOL, R_NONE, OPTFASTREPLY, 0 },
   { "fcc_attach",      DT_BOOL, R_NONE, OPTFCCATTACH, 1 },
@@ -114,6 +116,7 @@ struct option_t MuttVars[] = {
   { "hdrs",            DT_BOOL, R_NONE, OPTHDRS, 1 },
   { "header",          DT_BOOL, R_NONE, OPTHEADER, 0 },
   { "help",            DT_BOOL, R_BOTH, OPTHELP, 1 },
+  { "hidden_host",     DT_BOOL, R_NONE, OPTHIDDENHOST, 0 },
   { "history",         DT_NUM,  R_NONE, UL &HistSize, 10 },
   { "hostname",                DT_STR,  R_NONE, UL &Fqdn, 0 },
 #ifdef USE_IMAP
@@ -133,7 +136,7 @@ struct option_t MuttVars[] = {
   { "mailcap_path",    DT_STR,  R_NONE, UL &MailcapPath, 0 },
   { "mark_old",                DT_BOOL, R_BOTH, OPTMARKOLD, 1 },
   { "markers",         DT_BOOL, R_PAGER, OPTMARKERS, 1 },
-  { "mask",            DT_RX,   R_NONE, UL &Mask, UL "^(\\.\\.$|[^.])" },
+  { "mask",            DT_RX,   R_NONE, UL &Mask, UL "!^\\.[^.]" },
   { "mbox",            DT_PATH, R_BOTH, UL &Inbox, UL "~/mbox" },
   { "mbox_type",       DT_MAGIC,R_NONE, UL &DefaultMagic, M_MBOX },
   { "metoo",           DT_BOOL, R_NONE, OPTMETOO, 0 },
@@ -263,6 +266,7 @@ struct option_t MuttVars[] = {
   { "wait_key",                DT_BOOL, R_NONE, OPTWAITKEY, 1 },
   { "wrap_search",     DT_BOOL, R_NONE, OPTWRAPSEARCH, 1 },
   { "write_inc",       DT_NUM,  R_NONE, UL &WriteInc, 10 },
+  { "write_bcc",       DT_BOOL, R_NONE, OPTWRITEBCC, 1},
   { NULL }
 };
 
@@ -335,6 +339,9 @@ struct command_t Commands[] = {
   { "mbox-hook",       mutt_parse_hook,        M_MBOXHOOK },
   { "mono",            mutt_parse_mono,        0 },
   { "my_hdr",          parse_my_hdr,           0 },
+#ifdef _PGPPATH
+  { "pgp-hook",                mutt_parse_hook,        M_PGPHOOK },
+#endif /* _PGPPATH */
   { "push",            mutt_parse_push,        0 },
   { "reset",           parse_set,              M_SET_RESET },
   { "save-hook",       mutt_parse_hook,        M_SAVEHOOK },
@@ -344,8 +351,10 @@ struct command_t Commands[] = {
   { "source",          parse_source,           0 },
   { "toggle",          parse_set,              M_SET_INV },
   { "unalias",         parse_unalias,          0 },
+  { "unhdr_order",     parse_unlist,           UL &HeaderOrderList },
   { "unignore",                parse_unignore,         0 },
   { "unlists",         parse_unlist,           UL &MailLists },
+  { "unmono",          mutt_parse_unmono,      0 },
   { "unmy_hdr",                parse_unmy_hdr,         0 },
   { "unscore",         mutt_parse_unscore,     0 },
   { "unset",           parse_set,              M_SET_UNSET },
index 0eebfd3200a2b63cbc09317b1f9fb00d294eed82..b3f8c0e3964995592fe3c60fc8ff1c5908fe86cd 100644 (file)
--- a/keymap.c
+++ b/keymap.c
@@ -97,10 +97,10 @@ static int parsekeys (char *s, keycode_t *d, int max)
       s += strlen (s);
       *d = n;
     }
-    else if (tolower (*s) == 'f' && isdigit (s[1]))
+    else if (tolower (*s) == 'f' && isdigit ((unsigned char) s[1]))
     {
       n = 0;
-      for (s++; isdigit (*s) ; s++)
+      for (s++; isdigit ((unsigned char) *s) ; s++)
       {
        n *= 10;
        n += *s - '0';
@@ -122,7 +122,7 @@ static int parsekeys (char *s, keycode_t *d, int max)
 /* insert a key sequence into the specified map.  the map is sorted by ASCII
  * value (lowest to highest)
  */
-void km_bindkey (char *s, int menu, int op, char *macro)
+void km_bind (char *s, int menu, int op, char *macro, char *descr)
 {
   struct keymap_t *map, *tmp, *last = NULL, *next;
   keycode_t buf[MAX_SEQ];
@@ -133,6 +133,7 @@ void km_bindkey (char *s, int menu, int op, char *macro)
   map = allocKeys (len, buf);
   map->op = op;
   map->macro = safe_strdup (macro);
+  map->descr = safe_strdup (descr);
 
   tmp = Keymaps[menu];
 
@@ -145,10 +146,10 @@ void km_bindkey (char *s, int menu, int op, char *macro)
       {
        len = tmp->eq;
        next = tmp->next;
-       if (tmp->macro)
-         free (tmp->macro);
-       free (tmp->keys);
-       free (tmp);
+       FREE (&tmp->macro);
+       FREE (&tmp->keys);
+       FREE (&tmp->descr);
+       FREE (&tmp);
        tmp = next;
       }
       while (tmp && len >= pos);
@@ -183,6 +184,11 @@ void km_bindkey (char *s, int menu, int op, char *macro)
     Keymaps[menu] = map;
 }
 
+void km_bindkey (char *s, int menu, int op)
+{
+  km_bind (s, menu, op, NULL, NULL);
+}
+
 static void push_string (char *s)
 {
   char *pp, *p = s + strlen (s) - 1;
@@ -292,7 +298,7 @@ static void create_bindings (struct binding_t *map, int menu)
 
   for (i = 0 ; map[i].name ; i++)
     if (map[i].seq)
-      km_bindkey (map[i].seq, menu, map[i].op, NULL);
+      km_bindkey (map[i].seq, menu, map[i].op);
 }
 
 char *km_keyname (int c)
@@ -395,68 +401,72 @@ void km_init (void)
   /* bindings for the line editor */
   create_bindings (OpEditor, MENU_EDITOR);
   
-  km_bindkey ("<up>", MENU_EDITOR, OP_EDITOR_HISTORY_UP, NULL);
-  km_bindkey ("<down>", MENU_EDITOR, OP_EDITOR_HISTORY_DOWN, NULL);
-  km_bindkey ("<left>", MENU_EDITOR, OP_EDITOR_BACKWARD_CHAR, NULL);
-  km_bindkey ("<right>", MENU_EDITOR, OP_EDITOR_FORWARD_CHAR, NULL);
-  km_bindkey ("<home>", MENU_EDITOR, OP_EDITOR_BOL, NULL);
-  km_bindkey ("<end>", MENU_EDITOR, OP_EDITOR_EOL, NULL);
-  km_bindkey ("<backspace>", MENU_EDITOR, OP_EDITOR_BACKSPACE, NULL);
-  km_bindkey ("<delete>", MENU_EDITOR, OP_EDITOR_BACKSPACE, NULL);
-  km_bindkey ("\177", MENU_EDITOR, OP_EDITOR_BACKSPACE, NULL);
+  km_bindkey ("<up>", MENU_EDITOR, OP_EDITOR_HISTORY_UP);
+  km_bindkey ("<down>", MENU_EDITOR, OP_EDITOR_HISTORY_DOWN);
+  km_bindkey ("<left>", MENU_EDITOR, OP_EDITOR_BACKWARD_CHAR);
+  km_bindkey ("<right>", MENU_EDITOR, OP_EDITOR_FORWARD_CHAR);
+  km_bindkey ("<home>", MENU_EDITOR, OP_EDITOR_BOL);
+  km_bindkey ("<end>", MENU_EDITOR, OP_EDITOR_EOL);
+  km_bindkey ("<backspace>", MENU_EDITOR, OP_EDITOR_BACKSPACE);
+  km_bindkey ("<delete>", MENU_EDITOR, OP_EDITOR_BACKSPACE);
+  km_bindkey ("\177", MENU_EDITOR, OP_EDITOR_BACKSPACE);
   
   /* generic menu keymap */
   create_bindings (OpGeneric, MENU_GENERIC);
   
-  km_bindkey ("<home>", MENU_GENERIC, OP_FIRST_ENTRY, NULL);
-  km_bindkey ("<end>", MENU_GENERIC, OP_LAST_ENTRY, NULL);
-  km_bindkey ("<pagedown>", MENU_GENERIC, OP_NEXT_PAGE, NULL);
-  km_bindkey ("<pageup>", MENU_GENERIC, OP_PREV_PAGE, NULL);
-  km_bindkey ("<right>", MENU_GENERIC, OP_NEXT_PAGE, NULL);
-  km_bindkey ("<left>", MENU_GENERIC, OP_PREV_PAGE, NULL);
-  km_bindkey ("<up>", MENU_GENERIC, OP_PREV_ENTRY, NULL);
-  km_bindkey ("<down>", MENU_GENERIC, OP_NEXT_ENTRY, NULL);
-  km_bindkey ("1", MENU_GENERIC, OP_JUMP, NULL);
-  km_bindkey ("2", MENU_GENERIC, OP_JUMP, NULL);
-  km_bindkey ("3", MENU_GENERIC, OP_JUMP, NULL);
-  km_bindkey ("4", MENU_GENERIC, OP_JUMP, NULL);
-  km_bindkey ("5", MENU_GENERIC, OP_JUMP, NULL);
-  km_bindkey ("6", MENU_GENERIC, OP_JUMP, NULL);
-  km_bindkey ("7", MENU_GENERIC, OP_JUMP, NULL);
-  km_bindkey ("8", MENU_GENERIC, OP_JUMP, NULL);
-  km_bindkey ("9", MENU_GENERIC, OP_JUMP, NULL);
+  km_bindkey ("<home>", MENU_GENERIC, OP_FIRST_ENTRY);
+  km_bindkey ("<end>", MENU_GENERIC, OP_LAST_ENTRY);
+  km_bindkey ("<pagedown>", MENU_GENERIC, OP_NEXT_PAGE);
+  km_bindkey ("<pageup>", MENU_GENERIC, OP_PREV_PAGE);
+  km_bindkey ("<right>", MENU_GENERIC, OP_NEXT_PAGE);
+  km_bindkey ("<left>", MENU_GENERIC, OP_PREV_PAGE);
+  km_bindkey ("<up>", MENU_GENERIC, OP_PREV_ENTRY);
+  km_bindkey ("<down>", MENU_GENERIC, OP_NEXT_ENTRY);
+  km_bindkey ("1", MENU_GENERIC, OP_JUMP);
+  km_bindkey ("2", MENU_GENERIC, OP_JUMP);
+  km_bindkey ("3", MENU_GENERIC, OP_JUMP);
+  km_bindkey ("4", MENU_GENERIC, OP_JUMP);
+  km_bindkey ("5", MENU_GENERIC, OP_JUMP);
+  km_bindkey ("6", MENU_GENERIC, OP_JUMP);
+  km_bindkey ("7", MENU_GENERIC, OP_JUMP);
+  km_bindkey ("8", MENU_GENERIC, OP_JUMP);
+  km_bindkey ("9", MENU_GENERIC, OP_JUMP);
 
   /* Miscellaneous extra bindings */
   
-  km_bindkey (" ", MENU_MAIN, OP_DISPLAY_MESSAGE, NULL);
-  km_bindkey ("<up>", MENU_MAIN, OP_MAIN_PREV_UNDELETED, NULL);
-  km_bindkey ("<down>", MENU_MAIN, OP_MAIN_NEXT_UNDELETED, NULL);
-  km_bindkey ("J", MENU_MAIN, OP_NEXT_ENTRY, NULL);
-  km_bindkey ("K", MENU_MAIN, OP_PREV_ENTRY, NULL);
-  km_bindkey ("x", MENU_MAIN, OP_EXIT, NULL);
-
-  km_bindkey ("x", MENU_PAGER, OP_PAGER_EXIT, NULL);
-  km_bindkey ("q", MENU_PAGER, OP_PAGER_EXIT, NULL);
-  km_bindkey ("<backspace>", MENU_PAGER, OP_PREV_LINE, NULL);
-  km_bindkey ("<pagedown>", MENU_PAGER, OP_NEXT_PAGE, NULL);
-  km_bindkey ("<pageup>", MENU_PAGER, OP_PREV_PAGE, NULL);
-  km_bindkey ("<up>", MENU_PAGER, OP_MAIN_PREV_UNDELETED, NULL);
-  km_bindkey ("<right>", MENU_PAGER, OP_MAIN_NEXT_UNDELETED, NULL);
-  km_bindkey ("<down>", MENU_PAGER, OP_MAIN_NEXT_UNDELETED, NULL);
-  km_bindkey ("<left>", MENU_PAGER, OP_MAIN_PREV_UNDELETED, NULL);
-  km_bindkey ("<home>", MENU_PAGER, OP_PAGER_TOP, NULL);
-  km_bindkey ("<end>", MENU_PAGER, OP_PAGER_BOTTOM, NULL);
-  km_bindkey ("1", MENU_PAGER, OP_JUMP, NULL);
-  km_bindkey ("2", MENU_PAGER, OP_JUMP, NULL);
-  km_bindkey ("3", MENU_PAGER, OP_JUMP, NULL);
-  km_bindkey ("4", MENU_PAGER, OP_JUMP, NULL);
-  km_bindkey ("5", MENU_PAGER, OP_JUMP, NULL);
-  km_bindkey ("6", MENU_PAGER, OP_JUMP, NULL);
-  km_bindkey ("7", MENU_PAGER, OP_JUMP, NULL);
-  km_bindkey ("8", MENU_PAGER, OP_JUMP, NULL);
-  km_bindkey ("9", MENU_PAGER, OP_JUMP, NULL);
-
-  km_bindkey ("<return>", MENU_ALIAS, OP_TAG, NULL);
+  km_bindkey (" ", MENU_MAIN, OP_DISPLAY_MESSAGE);
+  km_bindkey ("<up>", MENU_MAIN, OP_MAIN_PREV_UNDELETED);
+  km_bindkey ("<down>", MENU_MAIN, OP_MAIN_NEXT_UNDELETED);
+  km_bindkey ("J", MENU_MAIN, OP_NEXT_ENTRY);
+  km_bindkey ("K", MENU_MAIN, OP_PREV_ENTRY);
+  km_bindkey ("x", MENU_MAIN, OP_EXIT);
+
+  km_bindkey ("x", MENU_PAGER, OP_PAGER_EXIT);
+  km_bindkey ("q", MENU_PAGER, OP_PAGER_EXIT);
+  km_bindkey ("<backspace>", MENU_PAGER, OP_PREV_LINE);
+  km_bindkey ("<pagedown>", MENU_PAGER, OP_NEXT_PAGE);
+  km_bindkey ("<pageup>", MENU_PAGER, OP_PREV_PAGE);
+  km_bindkey ("<up>", MENU_PAGER, OP_MAIN_PREV_UNDELETED);
+  km_bindkey ("<right>", MENU_PAGER, OP_MAIN_NEXT_UNDELETED);
+  km_bindkey ("<down>", MENU_PAGER, OP_MAIN_NEXT_UNDELETED);
+  km_bindkey ("<left>", MENU_PAGER, OP_MAIN_PREV_UNDELETED);
+  km_bindkey ("<home>", MENU_PAGER, OP_PAGER_TOP);
+  km_bindkey ("<end>", MENU_PAGER, OP_PAGER_BOTTOM);
+  km_bindkey ("1", MENU_PAGER, OP_JUMP);
+  km_bindkey ("2", MENU_PAGER, OP_JUMP);
+  km_bindkey ("3", MENU_PAGER, OP_JUMP);
+  km_bindkey ("4", MENU_PAGER, OP_JUMP);
+  km_bindkey ("5", MENU_PAGER, OP_JUMP);
+  km_bindkey ("6", MENU_PAGER, OP_JUMP);
+  km_bindkey ("7", MENU_PAGER, OP_JUMP);
+  km_bindkey ("8", MENU_PAGER, OP_JUMP);
+  km_bindkey ("9", MENU_PAGER, OP_JUMP);
+
+  km_bindkey ("<return>", MENU_ALIAS, OP_TAG);
+
+  /* edit-to (default "t") hides generic tag-entry in Compose menu
+     This will bind tag-entry to  "T" in the Compose menu */
+  km_bindkey ("T", MENU_COMPOSE, OP_TAG);
 }
 
 void km_error_key (int menu)
@@ -528,7 +538,7 @@ try_bind (char *key, int menu, char *func, struct binding_t *bindings)
   for (i = 0; bindings[i].name; i++)
     if (strcmp (func, bindings[i].name) == 0)
     {
-      km_bindkey (key, menu, bindings[i].op, NULL);
+      km_bindkey (key, menu, bindings[i].op);
       return (0);
     }
   return (-1);
@@ -588,7 +598,7 @@ int mutt_parse_bind (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *err)
     r = -1;
   }
   else if (strcasecmp ("noop", buf->data) == 0)
-    km_bindkey (key, menu, OP_NULL, NULL); /* the `unbind' command */
+    km_bindkey (key, menu, OP_NULL); /* the `unbind' command */
   else
   {
     /* First check the "generic" list of commands */
@@ -608,10 +618,11 @@ int mutt_parse_bind (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *err)
   return (r);
 }
 
-/* macro <menu> <key> <macro> */
+/* macro <menu> <key> <macro> <description> */
 int mutt_parse_macro (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *err)
 {
   int menu, r = -1;
+  char *seq = NULL;
   char *key;
 
   if ((key = parse_keymap (&menu, s, err)) == NULL)
@@ -623,14 +634,30 @@ int mutt_parse_macro (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *err)
   {
     strfcpy (err->data, "macro: empty key sequence", err->dsize);
   }
-  else if (MoreArgs (s))
-  {
-    strfcpy (err->data, "macro: too many arguments", err->dsize);
-  }
   else
   {
-    km_bindkey (key, menu, OP_MACRO, buf->data);
-    r = 0;
+    if (MoreArgs (s))
+    {
+      seq = strdup (buf->data);
+      mutt_extract_token (buf, s, M_TOKEN_CONDENSE);
+
+      if (MoreArgs (s))
+      {
+       strfcpy (err->data, "macro: too many arguments", err->dsize);
+      }
+      else
+      {
+       km_bind (key, menu, OP_MACRO, seq, buf->data);
+       r = 0;
+      }
+
+      FREE (&seq);
+    }
+    else
+    {
+      km_bind (key, menu, OP_MACRO, buf->data, NULL);
+      r = 0;
+    }
   }
   FREE (&key);
   return (r);
index 580bc2ba9b5863d0c7ddb4882caca2b51c40d556..7ec44a5c9b081d7d0ffd25ca7a467711a0aa3fa8 100644 (file)
--- a/keymap.h
+++ b/keymap.h
 /* type for key storage, the rest of mutt works fine with int type */
 typedef short keycode_t;
 
-void km_bindkey (char *, int, int, char *);
+void km_bind (char *, int, int, char *, char *);
+void km_bindkey (char *, int, int);
 int km_dokey (int);
 
 /* entry in the keymap tree */
 struct keymap_t
 {
   char *macro;           /* macro expansion (op == OP_MACRO) */
+  char *descr;           /* description of a macro for the help menu */
   struct keymap_t *next; /* next key in map */
   short op;              /* operation to perform */
   short eq;              /* number of leading keys equal to next entry */
diff --git a/lib.c b/lib.c
index 3c14bc68284b1c44a21b88b921ccfae9543b437d..2134c5a9e892225325e4435ab36f7a0f1498683e 100644 (file)
--- a/lib.c
+++ b/lib.c
@@ -19,6 +19,8 @@
 #include "mutt.h"
 #include "mutt_curses.h"
 #include "mime.h"
+#include "mailbox.h"
+#include "mx.h"
 
 #include <string.h>
 #include <ctype.h>
@@ -63,6 +65,7 @@ void mutt_free_body (BODY **p)
       unlink (b->filename);
     safe_free ((void **) &b->filename);
     safe_free ((void **) &b->content);
+    safe_free ((void **) &b->xtype);
     safe_free ((void **) &b->subtype);
     safe_free ((void **) &b->description);
     safe_free ((void **) &b->form_name);
@@ -194,7 +197,7 @@ char *mutt_expand_path (char *s, size_t slen)
   if (*s == '~')
   {
     if (*(s + 1) == '/' || *(s + 1) == 0)
-      snprintf (p, sizeof (p), "%s%s", Homedir, s + 1);
+      snprintf (p, sizeof (p), "%s%s", NONULL(Homedir), s + 1);
     else
     {
       struct passwd *pw;
@@ -468,7 +471,7 @@ void mutt_tabs_to_spaces (char *s)
 
 void mutt_mktemp (char *s)
 {
-  snprintf (s, _POSIX_PATH_MAX, "%s/mutt-%s-%d-%d", NONULL (Tempdir), Hostname, (int) getpid (), Counter++);
+  snprintf (s, _POSIX_PATH_MAX, "%s/mutt-%s-%d-%d", NONULL (Tempdir), NONULL(Hostname), (int) getpid (), Counter++);
   unlink (s);
 }
 
@@ -510,7 +513,7 @@ void mutt_free_alias (ALIAS **p)
     *p = (*p)->next;
     safe_free ((void **) &t->name);
     rfc822_free_address (&t->addr);
-    free (t);
+    safe_free ((void **) &t);
   }
 }
 
@@ -543,7 +546,7 @@ void mutt_pretty_mailbox (char *s)
     *s++ = '=';
     strcpy (s, s + len);
   }
-  else if (strncmp (s, Homedir, (len = strlen (Homedir))) == 0 &&
+  else if (strncmp (s, NONULL(Homedir), (len = strlen (NONULL(Homedir)))) == 0 &&
           s[len] == '/')
   {
     *s++ = '~';
@@ -642,13 +645,32 @@ void mutt_expand_fmt (char *dest, size_t destlen, const char *fmt, const char *s
     snprintf (dest, destlen, "%s '%s'", fmt, src);
 }
 
+int safe_open (const char *path, int flags)
+{
+  struct stat osb, nsb;
+  int fd;
+
+  if ((fd = open (path, flags, 0600)) < 0)
+    return fd;
+
+  /* make sure the file is not symlink */
+  if (lstat (path, &osb) < 0 || fstat (fd, &nsb) < 0 ||
+      osb.st_dev != nsb.st_dev || osb.st_ino != nsb.st_ino ||
+      osb.st_rdev != nsb.st_rdev)
+  {
+    dprint (1, (debugfile, "safe_open(): %s is a symlink!\n", path));
+    close (fd);
+    return (-1);
+  }
+
+  return (fd);
+}
+
 /* when opening files for writing, make sure the file doesn't already exist
  * to avoid race conditions.
  */
 FILE *safe_fopen (const char *path, const char *mode)
 {
-  struct stat osb, nsb;
-
   if (mode[0] == 'w')
   {
     int fd;
@@ -659,18 +681,8 @@ FILE *safe_fopen (const char *path, const char *mode)
     else
       flags |= O_WRONLY;
 
-    if ((fd = open (path, flags, 0600)) < 0)
-      return NULL;
-
-    /* make sure the file is not symlink */
-    if (lstat (path, &osb) < 0 || fstat (fd, &nsb) < 0 ||
-       osb.st_dev != nsb.st_dev || osb.st_ino != nsb.st_ino ||
-       osb.st_rdev != nsb.st_rdev)
-    {
-      dprint (1, (debugfile, "safe_fopen():%s is a symlink!\n", path));
-      close (fd);
+    if ((fd = safe_open (path, flags)) < 0)
       return (NULL);
-    }
 
     return (fdopen (fd, mode));
   }
@@ -772,6 +784,19 @@ void mutt_safe_path (char *s, size_t l, ADDRESS *a)
       *p = '_';
 }
 
+static char safe_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+@{}._-:%";
+
+void mutt_sanitize_filename(char *f)
+{
+  if(!f) return;
+
+  for(; *f; f++)
+  {
+    if(!strchr(safe_chars, *f))
+      *f = '_';
+  }
+}
+
 /* Read a line from ``fp'' into the dynamically allocated ``s'',
  * increasing ``s'' if necessary. The ending "\n" or "\r\n" is removed.
  * If a line ends with "\", this char and the linefeed is removed,
@@ -792,7 +817,7 @@ char *mutt_read_line (char *s, size_t *size, FILE *fp, int *line)
   {
     if (fgets (s + offset, *size - offset, fp) == NULL)
     {
-      free (s);
+      safe_free ((void **) &s);
       return NULL;
     }
     if ((ch = strchr (s + offset, '\n')) != NULL)
@@ -877,7 +902,7 @@ void mutt_FormatString (char *dest,         /* output buffer */
        cp = prefix;
        count = 0;
        while (count < sizeof (prefix) &&
-              (isdigit (*src) || *src == '.' || *src == '-'))
+              (isdigit ((unsigned char) *src) || *src == '.' || *src == '-'))
        {
          *cp++ = *src++;
          count++;
@@ -972,10 +997,7 @@ void mutt_FormatString (char *dest,                /* output buffer */
        src = callback (buf, sizeof (buf), ch, src, prefix, ifstring, elsestring, data, flags);
 
        if ((len = strlen (buf)) + wlen > destlen)
-       {
-         if ((len = destlen - wlen) < 0)
-           len = 0;
-       }
+         len = (destlen - wlen > 0) ? (destlen - wlen) : 0;
        memcpy (wptr, buf, len);
        wptr += len;
        wlen += len;
@@ -1046,7 +1068,7 @@ FILE *mutt_open_read (const char *path, pid_t *thepid)
     s[len - 1] = 0;
     endwin ();
     *thepid = mutt_create_filter (s, NULL, &f, NULL);
-    free (s);
+    safe_free ((void **) &s);
   }
   else
   {
@@ -1055,3 +1077,55 @@ FILE *mutt_open_read (const char *path, pid_t *thepid)
   }
   return (f);
 }
+
+/* returns 1 if OK to proceed, 0 to abort */
+int mutt_save_confirm (const char *s, struct stat *st)
+{
+  char tmp[_POSIX_PATH_MAX];
+  int ret = 1;
+  int magic = 0;
+
+  magic = mx_get_magic (s);
+
+  if (stat (s, st) != -1)
+  {
+    if (magic == -1)
+    {
+      mutt_error ("%s is not a mailbox!", s);
+      return 0;
+    }
+
+    if (option (OPTCONFIRMAPPEND))
+    {
+      snprintf (tmp, sizeof (tmp), "Append messages to %s?", s);
+      if (mutt_yesorno (tmp, 1) < 1)
+       ret = 0;
+    }
+  }
+  else
+  {
+    if (magic != M_IMAP)
+    {
+      st->st_mtime = 0;
+      st->st_atime = 0;
+
+      if (errno == ENOENT)
+      {
+       if (option (OPTCONFIRMCREATE))
+       {
+         snprintf (tmp, sizeof (tmp), "Create %s?", s);
+         if (mutt_yesorno (tmp, 1) < 1)
+           ret = 0;
+       }
+      }
+      else
+      {
+       mutt_perror (s);
+       return 0;
+      }
+    }
+  }
+
+  CLEARLINE (LINES-1);
+  return (ret);
+}
index 44b227ce7537beefd9ab01dab835e47944746d0f..66e74738288b69616592a3c286402c7213b800e4 100644 (file)
--- a/mailbox.h
+++ b/mailbox.h
@@ -57,3 +57,7 @@ int mx_close_message (MESSAGE **msg);
 int mx_get_magic (const char *);
 int mx_set_magic (const char *);
 int mx_check_mailbox (CONTEXT *, int *);
+#ifdef USE_IMAP
+int mx_is_imap (const char *);
+#endif
+
diff --git a/main.c b/main.c
index c0e2177a61eb30ca9e4c77c573205b5f6ac6d9e0..b6b45aaa9cfd5c4fd6ea93f0c1f0f2c4801885b1 100644 (file)
--- a/main.c
+++ b/main.c
@@ -126,11 +126,6 @@ static void show_version (void)
 #endif
 
   puts (
-#ifdef HIDDEN_HOST
-       "+HIDDEN_HOST  "
-#else
-       "-HIDDEN_HOST  "
-#endif
 
 #ifdef HOMESPOOL
        "+HOMESPOOL  "
@@ -251,7 +246,7 @@ static void show_version (void)
 
 
 
-  puts ("\nMail bug reports along with this output to <mutt-dev@cs.hmc.edu>.");
+  puts ("\nMail bug reports along with this output to <mutt-dev@mutt.org>.");
 
   exit (0);
 }
@@ -312,34 +307,21 @@ int main (int argc, char **argv)
   extern char *optarg;
   extern int optind;
 
-  mutt_error = mutt_nocurses_error;
+  /* sanity check against stupid administrators */
+  
+  if(getegid() != getgid())
+  {
+    fprintf(stderr, "%s: I don't want to run with privileges!\n",
+           argv[0]);
+    exit(1);
+  }
 
+
+  mutt_error = mutt_nocurses_error;
   SRAND (time (NULL));
   setlocale (LC_CTYPE, "");
   umask (077);
 
-#ifdef USE_SETGID
-  /* Determine the user's default gid and the gid to use for locking the spool
-   * mailbox on those systems which require setgid "mail" to write to the
-   * directory.  This function also resets the gid to "normal" since the
-   * effective gid will be "mail" when we start (Mutt attempts to run
-   * non-setgid whenever possible to reduce the possibility of security holes).
-   */
-
-  /* Get the default gid for the user */
-  UserGid = getgid ();
-
-  /* it is assumed that we are setgid to the correct gid to begin with */
-  MailGid = getegid ();
-
-  /* reset the effective gid to the normal gid */
-  if (SETEGID (UserGid) != 0)
-  {
-    perror ("setegid");
-    exit (0);
-  }
-#endif
-
   memset (Options, 0, sizeof (Options));
 
   while ((i = getopt (argc, argv, "a:b:F:f:c:d:e:H:s:i:hm:npRvxyzZ")) != EOF)
@@ -553,7 +535,7 @@ int main (int argc, char **argv)
            mutt_endwin (NULL);
          perror (tempfile);
          fclose (fin);
-         free (tempfile);
+         FREE (&tempfile);
          exit (1);
        }
 
@@ -573,11 +555,11 @@ int main (int argc, char **argv)
       {
        if (a)
        {
-         a->next = mutt_make_attach (t->data);
+         a->next = mutt_make_file_attach (t->data);
          a = a->next;
        }
        else
-         msg->content = a = mutt_make_attach (t->data);
+         msg->content = a = mutt_make_file_attach (t->data);
        if (!a)
        {
          if (!option (OPTNOCURSES))
@@ -620,7 +602,7 @@ int main (int argc, char **argv)
     }
 
     if (!folder[0])
-      strfcpy (folder, Spoolfile, sizeof (folder));
+      strfcpy (folder, NONULL(Spoolfile), sizeof (folder));
     mutt_expand_path (folder, sizeof (folder));
 
     if (flags & M_IGNORE)
@@ -645,7 +627,17 @@ int main (int argc, char **argv)
 
     if ((Context = mx_open_mailbox (folder, ((flags & M_RO) || option (OPTREADONLY)) ? M_READONLY : 0, NULL)) != NULL)
     {
-      mutt_index_menu ();
+      int close = mutt_index_menu (0);
+
+      if (Context)
+      {
+       if (close == OP_QUIT) 
+         mx_close_mailbox (Context);
+       else
+         mx_fastclose_mailbox (Context);
+      }
+
+      safe_free ((void **)&Context);
       mutt_endwin (NULL);
     }
     else
diff --git a/mbox.c b/mbox.c
index 0e3211f4762a35ff86fbf1007957fe55fb051c87..edae95fd198b4f9498f29a1c789926c209da1b58 100644 (file)
--- a/mbox.c
+++ b/mbox.c
@@ -40,60 +40,6 @@ struct m_update_t
   long body;
 };
 
-#ifdef USE_DOTLOCK
-/*
- * Determine whether or not to use a dotlock to lock the indicated file.
- * On some systems, the spool directory is not world-writable.  If it is
- * group-writable, we might need to be setgid() to write the lock.  If not
- * group-writable, then we assume that fcntl() locking is enough and skip
- * the dotlocking.
- *
- * return values:
- *     2       need to be setgid to dotlock
- *     1       can use a dotlock
- *     0       don't use a dotlock
- *     -1      error
- */
-static int can_dotlock (const char *path)
-{
-  char tmp[_POSIX_PATH_MAX];
-  char *p;
-#ifdef USE_SETGID
-  struct stat sb;
-#endif
-
-  strfcpy (tmp, path, sizeof (tmp));
-  if ((p = strrchr (tmp, '/')))
-    *p = 0;
-  else
-    strfcpy (tmp, ".", sizeof (tmp)); /* use current directory */
-
-  if (access (tmp, W_OK) == 0) return 1;
-
-#ifdef USE_SETGID
-  if (stat (tmp, &sb) == 0)
-  {
-    if ((sb.st_mode & S_IWGRP) == S_IWGRP)
-    {
-      /* can dotlock, but need to be setgid */
-      if (sb.st_gid == MailGid)
-       return (2);
-      else
-      {
-       mutt_error ("Need to be running setgid %d to lock mailbox!", sb.st_gid);
-       return (-1);
-      }
-    }
-  }
-#endif
-
-  if (mutt_yesorno ("Can't dotlock mailbox, continue anyway?", 0) == 1)
-    return 0;
-
-  return (-1);
-}
-#endif
-
 /* parameters:
  * ctx - context to lock
  * excl - exclusive lock?
@@ -101,36 +47,15 @@ static int can_dotlock (const char *path)
  */
 int mbox_lock_mailbox (CONTEXT *ctx, int excl, int retry)
 {
-  int r = 0;
-
-#ifdef USE_DOTLOCK
-  r = can_dotlock (ctx->path);
-
-  if (r == -1)
-    return (-1);
-#ifdef USE_SETGID
-  else if (r == 2)
-  {
-    /* need to be setgid to lock the mailbox */
-    if (SETEGID (MailGid) != 0)
-    {
-      mutt_perror ("setegid");
-      return (-1);
-    }
+  int r;
 
-    ctx->setgid = 1;
-  }
-#endif /* USE_SETGID */
-#endif /* USE_DOTLOCK */
+  /* XXX - Currently, we force dotlocking.
+   * Use dotlock -t here.
+   */
 
-  if ((r = mx_lock_file (ctx->path, fileno (ctx->fp), excl, r, retry)) == 0)
+  if ((r = mx_lock_file (ctx->path, fileno (ctx->fp), excl, 1, retry)) == 0)
     ctx->locked = 1;
 
-#ifdef USE_SETGID
-  if (ctx->setgid)
-    SETEGID (UserGid);
-#endif
-
   return (r);
 }
 
@@ -140,21 +65,8 @@ void mbox_unlock_mailbox (CONTEXT *ctx)
   {
     fflush (ctx->fp);
 
-#ifdef USE_SETGID
-    if (ctx->setgid)
-      SETEGID (MailGid);
-#endif /* USE_SETGID */
-
     mx_unlock_file (ctx->path, fileno (ctx->fp));
     ctx->locked = 0;
-
-#ifdef USE_SETGID
-    if (ctx->setgid)
-    {
-      SETEGID (UserGid);
-      ctx->setgid = 0;
-    }
-#endif
   }
 }
 
@@ -915,7 +827,7 @@ int mbox_sync_mailbox (CONTEXT *ctx)
     char savefile[_POSIX_PATH_MAX];
     
     snprintf (savefile, sizeof (savefile), "%s/mutt.%s-%s-%d",
-             NONULL (Tempdir), Username, Hostname, getpid ());
+             NONULL (Tempdir), NONULL(Username), NONULL(Hostname), getpid ());
     rename (tempfile, savefile);
     mutt_unblock_signals ();
     mx_fastclose_mailbox (ctx);
@@ -987,21 +899,7 @@ bail:  /* Come here in case of disaster */
 /* close a mailbox opened in write-mode */
 int mbox_close_mailbox (CONTEXT *ctx)
 {
-#ifdef USE_SETGID
-  if (ctx->setgid)
-    SETEGID (MailGid);
-#endif
-
   mx_unlock_file (ctx->path, fileno (ctx->fp));
-
-#ifdef USE_SETGID
-  if (ctx->setgid)
-  {
-    SETEGID (UserGid);
-    ctx->setgid = 0;
-  }
-#endif
-
   mutt_unblock_signals ();
   mx_fastclose_mailbox (ctx);
   return 0;
diff --git a/menu.c b/menu.c
index f582a1eba157da53672ae7dbcc05005fc33232d4..734a031265a63f727d2cc369847dd5b2c1d8574a 100644 (file)
--- a/menu.c
+++ b/menu.c
@@ -23,8 +23,6 @@
 #include <string.h>
 #include <stdlib.h>
 
-#define M_MODEFMT "-- Mutt: %s"
-
 static void print_enriched_string (int attr, unsigned char *s, int do_color)
 {
   while (*s)
@@ -555,6 +553,8 @@ MUTTMENU *mutt_new_menu (void)
 {
   MUTTMENU *p = (MUTTMENU *) safe_calloc (1, sizeof (MUTTMENU));
 
+  p->current = 0;
+  p->top = 0;
   p->offset = 1;
   p->redraw = REDRAW_FULL;
   p->pagelen = PAGELEN;
@@ -574,14 +574,16 @@ void mutt_menuDestroy (MUTTMENU **p)
 static int menu_search (MUTTMENU *menu, int op)
 {
   int r;
-  int searchDir = (menu->searchDir == M_SEARCH_UP) ? -1 : 1;
+  int searchDir;
   regex_t re;
   char buf[SHORT_STRING];
 
   if (op != OP_SEARCH_NEXT && op != OP_SEARCH_OPPOSITE)
   {
     strfcpy (buf, menu->searchBuf ? menu->searchBuf : "", sizeof (buf));
-    if (mutt_get_field ("Search for: ", buf, sizeof (buf), M_CLEAR) != 0 || !buf[0])
+    if (mutt_get_field ((op == OP_SEARCH) ? "Search for: " : 
+                                            "Reverse search for: ",
+                        buf, sizeof (buf), M_CLEAR) != 0 || !buf[0])
       return (-1);
     safe_free ((void **) &menu->searchBuf);
     menu->searchBuf = safe_strdup (buf);
@@ -594,11 +596,12 @@ static int menu_search (MUTTMENU *menu, int op)
       mutt_error ("No search pattern.");
       return (-1);
     }
-
-    if (op == OP_SEARCH_OPPOSITE)
-      searchDir = -searchDir;
   }
 
+  searchDir = (menu->searchDir == M_SEARCH_UP) ? -1 : 1;
+  if (op == OP_SEARCH_OPPOSITE)
+    searchDir = -searchDir;
+
   if ((r = REGCOMP (&re, menu->searchBuf, REG_NOSUB | mutt_which_case (menu->searchBuf))) != 0)
   {
     regerror (r, &re, buf, sizeof (buf));
diff --git a/mh.c b/mh.c
index ce724f3ecf820c7c8ef2b1d30565197542c11ed2..3ea7f1581f48e35541f15a045fab2b07bc5a44fa 100644 (file)
--- a/mh.c
+++ b/mh.c
@@ -324,7 +324,7 @@ int mh_valid_message (const char *s)
 {
   for (; *s; s++)
   {
-    if (!isdigit (*s))
+    if (!isdigit ((unsigned char) *s))
       return 0;
   }
   return 1;
@@ -452,7 +452,7 @@ void maildir_create_filename (const char *path, HEADER *hdr, char *msg, char *fu
   FOREVER
   {
     snprintf (msg, _POSIX_PATH_MAX, "%s/%ld.%d_%d.%s%s",
-             subdir, time (NULL), getpid (), Counter++, Hostname, suffix);
+             subdir, time (NULL), getpid (), Counter++, NONULL(Hostname), suffix);
     snprintf (full, _POSIX_PATH_MAX, "%s/%s", path, msg);
     if (stat (full, &sb) == -1 && errno == ENOENT) return;
   }
diff --git a/mime.h b/mime.h
index 662bae1c3871b9094aacd1d8db6a62e044a4ce5e..5dd307016f32d56fb312dc5cefb01298842a47fd 100644 (file)
--- a/mime.h
+++ b/mime.h
@@ -24,6 +24,7 @@ enum
   TYPEAPPLICATION,
   TYPEIMAGE,
   TYPEMESSAGE,
+  TYPEMODEL,
   TYPEMULTIPART,
   TYPETEXT,
   TYPEVIDEO
@@ -53,8 +54,8 @@ extern int Index_hex[];
 extern int Index_64[];
 extern char Base64_chars[];
 
-#define hexval(c) Index_hex[(int)(c)]
-#define base64val(c) Index_64[(int)(c)]
+#define hexval(c) Index_hex[(unsigned int)(c)]
+#define base64val(c) Index_64[(unsigned int)(c)]
 
 #define is_multipart(x) \
     ((x)->type == TYPEMULTIPART \
@@ -64,5 +65,5 @@ extern char Base64_chars[];
 extern const char *BodyTypes[];
 extern const char *BodyEncodings[];
 
-#define TYPE(X) BodyTypes[(X)]
+#define TYPE(X) ((X->type == TYPEOTHER) && (X->xtype != NULL) ? X->xtype : BodyTypes[(X->type)])
 #define ENCODING(X) BodyEncodings[(X)]
diff --git a/mutt.h b/mutt.h
index 4620764d955b6f74ce5750882b203a7550264670..2b7bc5f6939c1e2d87671fecf3421b4e843d6cc5 100644 (file)
--- a/mutt.h
+++ b/mutt.h
 
 #include <stdio.h>
 #include <sys/types.h>
+#include <sys/stat.h>
 #include <time.h>
 #include <limits.h>
 #include <stdarg.h>
 
+#ifndef _POSIX_PATH_MAX
+#include <posix1_lim.h>
+#endif
+
 #include "rfc822.h"
 #include "hash.h"
 
@@ -93,7 +98,8 @@ typedef enum
   M_FORMAT_FORCESUBJ   = (1<<0), /* print the subject even if unchanged */
   M_FORMAT_TREE                = (1<<1), /* draw the thread tree */
   M_FORMAT_MAKEPRINT   = (1<<2), /* make sure that all chars are printable */
-  M_FORMAT_OPTIONAL    = (1<<3)
+  M_FORMAT_OPTIONAL    = (1<<3),
+  M_FORMAT_STAT_FILE   = (1<<4)  /* used by mutt_attach_fmt */
 } format_flag;
 
 /* types for mutt_add_hook() */
@@ -102,6 +108,7 @@ typedef enum
 #define M_SENDHOOK     (1<<2)
 #define M_FCCHOOK      (1<<3)
 #define M_SAVEHOOK     (1<<4)
+#define M_PGPHOOK      (1<<5)
 
 /* tree characters for linearize_tree and print_enriched_string */
 #define M_TREE_LLCORNER                1
@@ -170,6 +177,9 @@ enum
   M_PRINT,
   M_AUTOVIEW,
 
+  /* options for socket code */
+  M_NEW_SOCKET,
+
   /* Options for mutt_save_attachment */
   M_SAVE_APPEND
 };
@@ -219,23 +229,67 @@ enum
 /* boolean vars */
 enum
 {
-  OPTPROMPTAFTER,
-  OPTSTATUSONTOP,
   OPTALLOW8BIT,
-  OPTASCIICHARS,
-  OPTMETOO,
-  OPTEDITHDRS,
   OPTARROWCURSOR,
+  OPTASCIICHARS,
+  OPTASKBCC,
   OPTASKCC,
+  OPTATTACHSPLIT,
+  OPTAUTOEDIT,
+  OPTAUTOTAG,
+  OPTBEEP,
+  OPTBEEPNEW,
+  OPTCHECKNEW,
+  OPTCONFIRMAPPEND,
+  OPTCONFIRMCREATE,
+  OPTEDITHDRS,
+  OPTFASTREPLY,
+  OPTFCCATTACH,
+  OPTFOLLOWUPTO,
+  OPTFORCENAME,
+  OPTFORWDECODE,
+  OPTFORWQUOTE,
+  OPTHDRS,
   OPTHEADER,
+  OPTHELP,
+  OPTHIDDENHOST,
+  OPTIGNORELISTREPLYTO,
+  OPTMARKERS,
+  OPTMARKOLD,
+  OPTMENUSCROLL,       /* scroll menu instead of implicit next-page */
+  OPTMETAKEY,          /* interpret ALT-x as ESC-x */
+  OPTMETOO,
+  OPTMIMEFORWDECODE,
+  OPTPAGERSTOP,
+  OPTPIPEDECODE,
+  OPTPIPESPLIT,
+  OPTPOPDELETE,
+  OPTPROMPTAFTER,
+  OPTREADONLY,
+  OPTRESOLVE,
   OPTREVALIAS,
   OPTREVNAME,
-  OPTFORCENAME,
+  OPTSAVEADDRESS,
   OPTSAVEEMPTY,
-  OPTPAGERSTOP,
+  OPTSAVENAME,
   OPTSIGDASHES,
-  OPTASKBCC,
-  OPTAUTOEDIT,
+  OPTSORTRE,
+  OPTSTATUSONTOP,
+  OPTSTRICTTHREADS,
+  OPTSUSPEND,
+  OPTTHOROUGHSRC,
+  OPTTILDE,
+  OPTUSE8BITMIME,
+  OPTUSEDOMAIN,
+  OPTUSEFROM,
+  OPTWAITKEY,
+  OPTWEED,
+  OPTWRAP,
+  OPTWRAPSEARCH,
+  OPTWRITEBCC,         /* write out a bcc header? */
+  
+  /* PGP options */
+  
 #ifdef _PGPPATH
   OPTPGPAUTOSIGN,
   OPTPGPAUTOENCRYPT,
@@ -245,44 +299,9 @@ enum
   OPTPGPENCRYPTSELF,
   OPTPGPSTRICTENC,
 #endif
-  OPTMARKOLD,
-  OPTCONFIRMCREATE,
-  OPTCONFIRMAPPEND,
-  OPTPOPDELETE,
-  OPTSAVENAME,
-  OPTTHOROUGHSRC,
-  OPTTILDE,
-  OPTMARKERS,
-  OPTFCCATTACH,
-  OPTPIPESPLIT,
-  OPTPIPEDECODE,
-  OPTREADONLY,
-  OPTRESOLVE,
-  OPTSTRICTTHREADS,
-  OPTAUTOTAG,
-  OPTBEEP,
-  OPTHELP,
-  OPTHDRS,
-  OPTWEED,
-  OPTWRAP,
-  OPTCHECKNEW,
-  OPTFASTREPLY,
-  OPTWAITKEY,
-  OPTWRAPSEARCH,
-  OPTIGNORELISTREPLYTO,
-  OPTSAVEADDRESS,
-  OPTSUSPEND,
-  OPTSORTRE,
-  OPTUSEDOMAIN,
-  OPTUSEFROM,
-  OPTUSE8BITMIME,
-  OPTFORWDECODE,
-  OPTMIMEFORWDECODE,
-  OPTFORWQUOTE,
-  OPTBEEPNEW,
-  OPTFOLLOWUPTO,
-  OPTMENUSCROLL,       /* scroll menu instead of implicit next-page */
-  OPTMETAKEY,          /* interpret ALT-x as ESC-x */
+
+  /* pseudo options */
+
   OPTAUXSORT,          /* (pseudo) using auxillary sort function */
   OPTFORCEREFRESH,     /* (pseudo) refresh even during macros */
   OPTLOCALES,          /* (pseudo) set if user has valid locale definition */
@@ -392,6 +411,7 @@ typedef struct content
 
 typedef struct body
 {
+  char *xtype;                 /* content-type if x-unknown */
   char *subtype;                /* content-type subtype */
   PARAMETER *parameter;         /* parameters of the content-type */
   char *description;            /* content-description */
@@ -420,6 +440,10 @@ typedef struct body
   struct body *parts;           /* parts of a multipart or message/rfc822 */
   struct header *hdr;          /* header information for message/rfc822 */
 
+  time_t stamp;                        /* time stamp of last
+                                * encoding update.
+                                */
+  
   unsigned int type : 3;        /* content-type primary type */
   unsigned int encoding : 3;    /* content-transfer-encoding */
   unsigned int disposition : 2; /* content-disposition */
@@ -546,7 +570,6 @@ typedef struct
   int msgnotreadyet;           /* which msg "new" in pager, -1 if none */
 #ifdef USE_IMAP
   void *data;                  /* driver specific data */
-  int fd;
 #endif /* USE_IMAP */
 
   short magic;                 /* mailbox type */
@@ -566,6 +589,7 @@ typedef struct attachptr
   BODY *content;
   char *tree;
   int level;
+  int num;
 } ATTACHPTR;
 
 typedef struct
index e30da6978b71d2d3e4641d14705f81bbb2f24191..fdbaf77e7a6b987a4a9afcdc866913aac00aaebb 100644 (file)
@@ -31,6 +31,8 @@
 #define REDRAW_FULL            (1<<5)
 #define REDRAW_BODY            (1<<6)
 
+#define M_MODEFMT "-- Mutt: %s"
+
 typedef struct menu_t
 {
   char *title;   /* the title of this menu */
diff --git a/mutt_socket.h b/mutt_socket.h
new file mode 100644 (file)
index 0000000..b3d5303
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 1998 Brandon Long <blong@fiction.net>
+ * 
+ *     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.
+ */ 
+
+#ifndef _MUTT_SOCKET_H_
+#define _MUTT_SOCKET_H_ 1
+
+typedef struct
+{
+  char *server;
+  int port;
+  int uses;
+  int fd;
+  char inbuf[LONG_STRING];
+  int bufpos;
+  int available;
+} CONNECTION;
+
+int mutt_socket_readchar (CONNECTION *conn, char *c);
+int mutt_socket_read_line (char *buf, size_t buflen, CONNECTION *conn);
+int mutt_socket_read_line_d (char *buf, size_t buflen, CONNECTION *conn);
+int mutt_socket_write (CONNECTION *conn, const char *buf);
+CONNECTION *mutt_socket_select_connection (char *host, int port, int flags);
+
+#endif /* _MUTT_SOCKET_H_ */
diff --git a/mx.c b/mx.c
index 8147a64efe98d2b2a893ef0d1a2a3e23fb453bcb..aaf1c45a9838e39cd2751f69218d2a6b2b7e4a6f 100644 (file)
--- a/mx.c
+++ b/mx.c
 #include "buffy.h"
 #endif
 
+#ifdef USE_DOTLOCK
+#include "dotlock.h"
+#endif
+
 #include <dirent.h>
 #include <fcntl.h>
 #include <sys/file.h>
 #define S_ISLNK(x) (((x) & S_IFMT) == S_IFLNK ? 1 : 0)
 #endif
 
-#define mutt_is_spool(s)  (strcmp (Spoolfile, s) == 0)
-
-#define MAXLOCKATTEMPT 5
+#define mutt_is_spool(s)  (strcmp (NONULL(Spoolfile), s) == 0)
 
 #ifdef USE_DOTLOCK
 /* parameters: 
  * path - file to lock
  * retry - should retry if unable to lock?
  */
-static int dotlock_file (const char *path, int retry)
-{
-  const char *pathptr = path;
-  char lockfile[_POSIX_PATH_MAX];
-  char nfslockfile[_POSIX_PATH_MAX];
-  char realpath[_POSIX_PATH_MAX];
-  struct stat sb;
-  size_t prev_size = 0;
-  int count = 0;
-  int attempt = 0;
-  int fd;
 
-  /* if the file is a symlink, find the real file to which it refers */
-  FOREVER
-  {
-    dprint(2,(debugfile,"dotlock_file(): locking %s\n", pathptr));
+#ifdef DL_STANDALONE
 
-    if (lstat (pathptr, &sb) != 0)
-    {
-      mutt_perror (pathptr);
-      return (-1);
-    }
+static int invoke_dotlock(const char *path, int flags, int retry)
+{
+  char cmd[LONG_STRING + _POSIX_PATH_MAX];
+  char r[SHORT_STRING];
+  
+  if(flags & DL_FL_RETRY)
+    snprintf(r, sizeof(r), "-r %d ", retry ? MAXLOCKATTEMPT : 0);
+  
+  snprintf(cmd, sizeof(cmd),
+          "%s %s%s%s%s%s%s",
+          DOTLOCK,
+          flags & DL_FL_TRY ? "-t " : "",
+          flags & DL_FL_UNLOCK ? "-u " : "",
+          flags & DL_FL_USEPRIV ? "-p " : "",
+          flags & DL_FL_FORCE ? "-f " : "",
+          flags & DL_FL_RETRY ? r : "",
+          path);
+
+  return mutt_system(cmd);
+}
 
-    if (S_ISLNK (sb.st_mode))
-    {
-      char linkfile[_POSIX_PATH_MAX];
-      char linkpath[_POSIX_PATH_MAX];
+#else 
 
-      if ((count = readlink (pathptr, linkfile, sizeof (linkfile))) == -1)
-      {
-       mutt_perror (path);
-       return (-1);
-      }
-      linkfile[count] = 0; /* readlink() does not NUL terminate the string! */
-      mutt_expand_link (linkpath, pathptr, linkfile);
-      strfcpy (realpath, linkpath, sizeof (realpath));
-      pathptr = realpath;
-    }
-    else
-      break;
-  }
-
-  snprintf (nfslockfile, sizeof (nfslockfile), "%s.%s.%d", pathptr, Hostname, (int) getpid ());
-  snprintf (lockfile, sizeof (lockfile), "%s.lock", pathptr);
-  unlink (nfslockfile);
+#define invoke_dotlock dotlock_invoke
 
-  while ((fd = open (nfslockfile, O_WRONLY | O_EXCL | O_CREAT, 0)) < 0)
-    if (errno != EAGAIN)
-    {
-      mutt_perror ("cannot open NFS lock file!");
-      return (-1);
-    }
+#endif
 
-  close (fd);
+static int dotlock_file (const char *path, int retry)
+{
+  int r;
+  int flags = DL_FL_USEPRIV | DL_FL_RETRY;
+  
+  if(retry) retry = 1;
 
-  count = 0;
-  FOREVER
+retry_lock:
+  mutt_clear_error();
+  if((r = invoke_dotlock(path, flags, retry)) == DL_EX_EXIST)
   {
-    link (nfslockfile, lockfile);
-    if (stat (nfslockfile, &sb) != 0)
-    {
-      mutt_perror ("stat");
-      return (-1);
-    }
-
-    if (sb.st_nlink == 2)
-      break;
-    
-    if (stat (path, &sb) != 0)
-      sb.st_size = 0;
-
-    if (count == 0)
-      prev_size = sb.st_size;
+    char msg[LONG_STRING];
 
-    /* only try to remove the lock if the file is not changing */
-    if (prev_size == sb.st_size && ++count >= retry ? MAXLOCKATTEMPT : 0)
+    snprintf(msg, sizeof(msg), "Lock count exceeded, remove lock for %s?",
+            path);
+    if(retry && mutt_yesorno(msg, 1) == 1)
     {
-      if (retry && mutt_yesorno ("Lock count exceeded, remove lock?", 1) == 1)
-      {
-       unlink (lockfile);
-       count = 0;
-       attempt = 0;
-       continue;
-      }
-      else
-       return (-1);
+      flags |= DL_FL_FORCE;
+      retry--;
+      goto retry_lock;
     }
-
-    prev_size = sb.st_size;
-
-    mutt_message ("Waiting for lock attempt #%d...", ++attempt);
-    sleep (1);
   }
-
-  unlink (nfslockfile);
-
-  return 0;
+  return (r == DL_EX_OK ? 0 : -1);
 }
 
 static int undotlock_file (const char *path)
 {
-  const char *pathptr = path;
-  char lockfile[_POSIX_PATH_MAX];
-  char realpath[_POSIX_PATH_MAX];
-  struct stat sb;
-  int n;
-
-  FOREVER
-  {
-    dprint (2,(debugfile,"undotlock: unlocking %s\n",path));
-
-    if (lstat (pathptr, &sb) != 0)
-    {
-      mutt_perror (pathptr);
-      return (-1);
-    }
-
-    if (S_ISLNK (sb.st_mode))
-    {
-      char linkfile[_POSIX_PATH_MAX];
-      char linkpath[_POSIX_PATH_MAX];
-
-      if ((n = readlink (pathptr, linkfile, sizeof (linkfile))) == -1)
-      {
-       mutt_perror (pathptr);
-       return (-1);
-      }
-      linkfile[n] = 0; /* readlink() does not NUL terminate the string! */
-      mutt_expand_link (linkpath, pathptr, linkfile);
-      strfcpy (realpath, linkpath, sizeof (realpath));
-      pathptr = realpath;
-      continue;
-    }
-    else
-      break;
-  }
-
-  snprintf (lockfile, sizeof (lockfile), "%s.lock", pathptr);
-  unlink (lockfile);
-  return 0;
+  return (invoke_dotlock(path, DL_FL_USEPRIV | DL_FL_UNLOCK, 0) == DL_EX_OK ? 
+         0 : -1);
 }
+
 #endif /* USE_DOTLOCK */
 
 /* Args:
@@ -248,7 +170,7 @@ int mx_lock_file (const char *path, int fd, int excl, int dot, int timeout)
       prev_sb = sb;
 
     /* only unlock file if it is unchanged */
-    if (prev_sb.st_size == sb.st_size && ++count >= timeout?MAXLOCKATTEMPT:0)
+    if (prev_sb.st_size == sb.st_size && ++count >= (timeout?MAXLOCKATTEMPT:0))
     {
       if (timeout)
        mutt_error ("Timeout exceeded while attempting fcntl lock!");
@@ -282,7 +204,7 @@ int mx_lock_file (const char *path, int fd, int excl, int dot, int timeout)
       prev_sb=sb;
 
     /* only unlock file if it is unchanged */
-    if (prev_sb.st_size == sb.st_size && ++count >= timeout?MAXLOCKATTEMPT:0)
+    if (prev_sb.st_size == sb.st_size && ++count >= (timeout?MAXLOCKATTEMPT:0))
     {
       if (timeout)
        mutt_error ("Timeout exceeded while attempting flock lock!");
@@ -370,7 +292,7 @@ FILE *mx_open_file_lock (const char *path, const char *mode)
 
 #ifdef USE_IMAP
 
-static int mx_is_imap(const char *p)
+int mx_is_imap(const char *p)
 {
   return p && (*p == '{');
 }
@@ -393,7 +315,6 @@ int mx_get_magic (const char *path)
   {
     dprint (1, (debugfile, "mx_get_magic(): unable to stat %s: %s (errno %d).\n",
                path, strerror (errno), errno));
-    mutt_perror (path);
     return (-1);
   }
 
@@ -483,7 +404,7 @@ static int mx_open_mailbox_append (CONTEXT *ctx)
 
 #ifdef USE_IMAP
   
-  if(mx_is_imap(ctx))  
+  if(mx_is_imap(ctx->path))  
     return imap_open_mailbox_append (ctx);
 
 #endif
@@ -632,19 +553,22 @@ CONTEXT *mx_open_mailbox (const char *path, int flags, CONTEXT *pctx)
     return ctx;
   }
 
-  switch (ctx->magic = mx_get_magic (path))
-  {
-    case 0:
-      mutt_error ("%s is not a mailbox.", path);
-      /* fall through */
+  ctx->magic = mx_get_magic (path);
+  
+  if(ctx->magic == 0)
+    mutt_error ("%s is not a mailbox.", path);
 
-    case -1:
-      mx_fastclose_mailbox (ctx);
-      if (!pctx)
-       free (ctx);
-      return (NULL);
+  if(ctx->magic == -1)
+    mutt_perror(path);
+  
+  if(ctx->magic <= 0)
+  {
+    mx_fastclose_mailbox (ctx);
+    if (!pctx)
+      FREE (&ctx);
+    return (NULL);
   }
-
+  
   /* if the user has a `push' command in their .muttrc, or in a folder-hook,
    * it will cause the progress messages not to be displayed because
    * mutt_refresh() will think we are in the middle of a macro.  so set a
@@ -817,7 +741,7 @@ int mx_close_mailbox (CONTEXT *ctx)
     }
     else
     {
-      strfcpy (mbox, Inbox, sizeof (mbox));
+      strfcpy (mbox, NONULL(Inbox), sizeof (mbox));
       isSpool = mutt_is_spool (ctx->path) && !mutt_is_spool (mbox);
     }
     mutt_expand_path (mbox, sizeof (mbox));
@@ -895,7 +819,7 @@ int mx_close_mailbox (CONTEXT *ctx)
 
   if (ctx->msgcount == ctx->deleted &&
       (ctx->magic == M_MMDF || ctx->magic == M_MBOX) &&
-      strcmp (ctx->path, Spoolfile) != 0 && !option (OPTSAVEEMPTY))
+      !mutt_is_spool(ctx->path) && !option (OPTSAVEEMPTY))
     unlink (ctx->path);
 
   mx_fastclose_mailbox (ctx);
@@ -963,7 +887,7 @@ int mx_sync_mailbox (CONTEXT *ctx)
 
     if (ctx->msgcount == ctx->deleted &&
        (ctx->magic == M_MBOX || ctx->magic == M_MMDF) &&
-       strcmp (ctx->path, Spoolfile) != 0 && !option (OPTSAVEEMPTY))
+       !mutt_is_spool(ctx->path) && !option (OPTSAVEEMPTY))
     {
       unlink (ctx->path);
       mx_fastclose_mailbox (ctx);
@@ -1056,7 +980,7 @@ int mh_open_new_message (MESSAGE *msg, CONTEXT *dest, HEADER *hdr)
       cp = de->d_name;
       while (*cp)
       {
-       if (!isdigit (*cp))
+       if (!isdigit ((unsigned char) *cp))
          break;
        cp++;
       }
@@ -1162,7 +1086,7 @@ MESSAGE *mx_open_new_message (CONTEXT *dest, HEADER *hdr, int flags)
     if (dest->magic == M_MMDF)
       fputs (MMDF_SEP, msg->fp);
 
-    if ((msg->magic != M_MAILDIR) && (msg->magic != M_IMAP) && 
+    if ((msg->magic != M_MAILDIR) && ((msg->magic != M_MH) && msg->magic != M_IMAP) && 
        (flags & M_ADD_FROM))
     {
       if (hdr)
@@ -1181,7 +1105,7 @@ MESSAGE *mx_open_new_message (CONTEXT *dest, HEADER *hdr, int flags)
       else
        t = time (NULL);
 
-      fprintf (msg->fp, "From %s %s", p ? p->mailbox : Username, ctime (&t));
+      fprintf (msg->fp, "From %s %s", p ? p->mailbox : NONULL(Username), ctime (&t));
     }
   }
   else
@@ -1417,8 +1341,7 @@ MESSAGE *mx_open_message (CONTEXT *ctx, int msgno)
          mutt_perror (path);
          dprint (1, (debugfile, "mx_open_message: fopen: %s: %s (errno %d).\n",
                      path, strerror (errno), errno));
-         free (msg);
-         msg = NULL;
+         FREE (&msg);
        }
       }
       break;
@@ -1426,17 +1349,14 @@ MESSAGE *mx_open_message (CONTEXT *ctx, int msgno)
 #ifdef USE_IMAP
     case M_IMAP:
       if (imap_fetch_message (msg, ctx, msgno) != 0)
-      {
-       free (msg);
-       msg = NULL;
-      }
+       FREE (&msg);
       break;
 #endif /* USE_IMAP */
 
     default:
 
       dprint (1, (debugfile, "mx_open_message(): function not implemented for mailbox type %d.\n", ctx->magic));
-      safe_free ((void **) &msg);
+      FREE (&msg);
       break;
   }
   return (msg);
@@ -1483,8 +1403,7 @@ int mx_close_message (MESSAGE **msg)
       break;
   }
 
-  free (*msg);
-  *msg = NULL;
+  FREE (msg);
   return (r);
 }
 
diff --git a/mx.h b/mx.h
index f03c590863a5c12b2fe941a3eca6f0576ee1cc6c..a430f1d81373435317e17e661f7d19e98b870f20 100644 (file)
--- a/mx.h
+++ b/mx.h
@@ -34,6 +34,7 @@ enum
 WHERE short DefaultMagic INITVAL (M_MBOX);
 
 #define MMDF_SEP "\001\001\001\001\n"
+#define MAXLOCKATTEMPT 5
 
 int mbox_sync_mailbox (CONTEXT *);
 int mbox_open_mailbox (CONTEXT *);
diff --git a/pager.c b/pager.c
index 02fd2c79025f976616d672eacac57362e8671735..3109dcfb989e0c4cf0e24b1a8a518c7f90d1f147 100644 (file)
--- a/pager.c
+++ b/pager.c
@@ -21,6 +21,7 @@
 #include "mutt_regex.h"
 #include "keymap.h"
 #include "mutt_menu.h"
+#include "mapping.h"
 #include "sort.h"
 #include "pager.h"
 #include "attach.h"
@@ -1247,7 +1248,8 @@ upNLines (int nlines, struct line_t *info, int cur, int hiding)
    is there so that we can do operations on the current message without the
    need to pop back out to the main-menu.  */
 int 
-mutt_pager (const char *banner, const char *fname, int do_color, pager_t *extra)
+mutt_pager (const char *banner, const char *fname, int do_color, pager_t *extra,
+            const char *attach_msg_status /* invoked while attaching a message */)
 {
   static char searchbuf[STRING];
   char buffer[LONG_STRING];
@@ -1482,7 +1484,11 @@ mutt_pager (const char *banner, const char *fname, int do_color, pager_t *extra)
       menu_redraw_current (index);
 
       /* print out the index status bar */
-      menu_status_line (buffer, sizeof (buffer), index, Status);
+      if (*attach_msg_status)
+        snprintf (buffer, sizeof (buffer), M_MODEFMT, attach_msg_status);
+      else
+       menu_status_line (buffer, sizeof (buffer), index, NONULL(Status));
       move (indexoffset + (option (OPTSTATUSONTOP) ? 0 : (indexlen - 1)), 0);
       SETCOLOR (MT_COLOR_STATUS);
       printw ("%-*.*s", COLS, COLS, buffer);
@@ -1876,7 +1882,7 @@ mutt_pager (const char *banner, const char *fname, int do_color, pager_t *extra)
        {
          ch = -1;
          rc = OP_MAIN_NEXT_UNDELETED;
-       };
+       }
        break;
 
       case OP_DELETE_THREAD:
@@ -2050,7 +2056,7 @@ mutt_pager (const char *banner, const char *fname, int do_color, pager_t *extra)
       case OP_SAVE:
        if (IsAttach (extra))
        {
-         mutt_save_attachment_list (extra->fp, 0, extra->bdy);
+         mutt_save_attachment_list (extra->fp, 0, extra->bdy, extra->hdr);
          break;
        }
        /* fall through */
diff --git a/pager.h b/pager.h
index bc3fab23caf2227815063a2ea934c46ea955655f..b218addcb2853f7010894d9c6c0e1e8db04113cd 100644 (file)
--- a/pager.h
+++ b/pager.h
@@ -25,4 +25,4 @@ typedef struct
 } pager_t;
 
 int mutt_do_pager (const char *, const char *, int, pager_t *);
-int mutt_pager (const char *, const char *, int, pager_t *);
+int mutt_pager (const char *, const char *, int, pager_t *, const char *);
diff --git a/parse.c b/parse.c
index 3ae7f9442ffd45328e63e83aa4cf953cf804cc01..d1ab50a833d22b3b0a4cf74efca0b89c9a5d1bac 100644 (file)
--- a/parse.c
+++ b/parse.c
@@ -245,8 +245,7 @@ int mutt_check_mime_type (const char *s)
 static void parse_content_type (char *s, BODY *ct)
 {
   char *pc;
-  char buffer[SHORT_STRING];
-  short i = 0;
+  char *subtype;
 
   safe_free((void **)&ct->subtype);
   mutt_free_parameter(&ct->parameter);
@@ -265,21 +264,23 @@ static void parse_content_type (char *s, BODY *ct)
   }
   
   /* Now get the subtype */
-  if ((pc = strchr(s, '/')))
+  if ((subtype = strchr(s, '/')))
   {
-    *pc++ = 0;
-    while (*pc && !ISSPACE (*pc) && *pc != ';')
-    {
-      buffer[i++] = *pc;
-      pc++;
-    }
-    buffer[i] = 0;
-    ct->subtype = safe_strdup (buffer);
+    *subtype++ = '\0';
+    for(pc = subtype; *pc && !ISSPACE(*pc) && *pc != ';'; pc++)
+      ;
+    *pc = '\0';
+    ct->subtype = safe_strdup (subtype);
   }
 
   /* Finally, get the major type */
   ct->type = mutt_check_mime_type (s);
 
+  if (ct->type == TYPEOTHER)
+  {
+    ct->xtype = safe_strdup (s);
+  }
+
   if (ct->subtype == NULL)
   {
     /* Some older non-MIME mailers (i.e., mailtool, elm) have a content-type
@@ -293,6 +294,8 @@ static void parse_content_type (char *s, BODY *ct)
       ct->subtype = safe_strdup ("rfc822");
     else if (ct->type == TYPEOTHER)
     {
+      char buffer[SHORT_STRING];
+
       ct->type = TYPEAPPLICATION;
       snprintf (buffer, sizeof (buffer), "x-%s", s);
       ct->subtype = safe_strdup (buffer);
@@ -300,6 +303,7 @@ static void parse_content_type (char *s, BODY *ct)
     else
       ct->subtype = safe_strdup ("x-unknown");
   }
+
 }
 
 static void parse_content_disposition (char *s, BODY *ct)
@@ -394,7 +398,7 @@ BODY *mutt_read_mime_header (FILE *fp, int digest)
   else if (p->type == TYPEMESSAGE && !p->subtype)
     p->subtype = safe_strdup ("rfc822");
 
-  free (line);
+  FREE (&line);
 
   return (p);
 }
@@ -665,7 +669,7 @@ static time_t parse_date (char *s, HEADER *h)
     switch (count)
     {
       case 0: /* day of the month */
-       if (!isdigit (*t))
+       if (!isdigit ((unsigned char) *t))
          return (-1);
        tm.tm_mday = atoi (t);
        if (tm.tm_mday > 31)
@@ -708,8 +712,8 @@ static time_t parse_date (char *s, HEADER *h)
        if (*ptz == '+' || *ptz == '-')
        {
          if (ptz[1] && ptz[2] && ptz[3] && ptz[4]
-             && isdigit (ptz[1]) && isdigit (ptz[2])
-             && isdigit (ptz[3]) && isdigit (ptz[4]))
+             && isdigit ((unsigned char) ptz[1]) && isdigit ((unsigned char) ptz[2])
+             && isdigit ((unsigned char) ptz[3]) && isdigit ((unsigned char) ptz[4]))
          {
            zhours = (ptz[1] - '0') * 10 + (ptz[2] - '0');
            zminutes = (ptz[3] - '0') * 10 + (ptz[4] - '0');
@@ -1167,7 +1171,7 @@ ENVELOPE *mutt_read_rfc822_header (FILE *f, HEADER *hdr)
     loc = ftell (f);
   }
 
-  free (line);
+  FREE (&line);
 
   if (hdr)
   {
diff --git a/patch.slang-1.2.2.keypad.1 b/patch.slang-1.2.2.keypad.1
new file mode 100644 (file)
index 0000000..93df4d7
--- /dev/null
@@ -0,0 +1,76 @@
+diff -ur slang.old/src/slcurses.c slang/src/slcurses.c
+--- slang.old/src/slcurses.c   Fri Apr 24 09:16:46 1998
++++ slang/src/slcurses.c       Sat Jul  4 07:30:31 1998
+@@ -134,7 +134,10 @@
+              }
+            else if (ch == 0xFFFF) return ERR;
+            SLang_ungetkey (ch);
+-           return SLkp_getkey ();
++           if ((ch = SLkp_getkey ()) != SL_KEY_ERR)
++             return ch;
++           else
++             return SLang_getkey ();
+         }
+       return SLang_getkey ();
+      }
+diff -ur slang.old/src/slkeymap.c slang/src/slkeymap.c
+--- slang.old/src/slkeymap.c   Fri Apr 24 09:16:47 1998
++++ slang/src/slkeymap.c       Sat Jul  4 07:41:42 1998
+@@ -343,6 +343,8 @@
+ SLang_Key_Type *SLang_do_key(SLKeyMap_List_Type *kml, int (*getkey)(void))
+ {
++   unsigned char SLang_Undo_Buffer [SL_MAX_INPUT_BUFFER_LEN];
++   int SLang_Undo_Len = 0;
+    register SLang_Key_Type *key, *next, *kmax;
+    unsigned int len;
+    unsigned char input_ch;
+@@ -356,6 +358,7 @@
+      return NULL;
+    input_ch = (unsigned char) SLang_Last_Key_Char;
++   SLang_Undo_Buffer [SLang_Undo_Len++] = input_ch;
+    key = (SLang_Key_Type *) &((kml->keymap)[input_ch]);
+@@ -372,7 +375,11 @@
+       key = kml->keymap + input_ch;
+       if (key->type == 0)
++      {
++        if (getkey == (int (*)(void)) SLang_getkey)
++          SLang_ungetkey_string (SLang_Undo_Buffer, SLang_Undo_Len);
+         return NULL;
++      }
+      }
+    /* It appears to be a prefix character in a key sequence. */
+@@ -385,6 +392,7 @@
+      {
+       SLang_Key_TimeOut_Flag = 1;
+       SLang_Last_Key_Char = (*getkey)();
++      SLang_Undo_Buffer [SLang_Undo_Len++] = (unsigned char) SLang_Last_Key_Char;
+       SLang_Key_TimeOut_Flag = 0;
+       len++;
+@@ -458,6 +466,8 @@
+       kmax = next;
+      }
++   if (getkey == (int (*)(void)) SLang_getkey)
++     SLang_ungetkey_string (SLang_Undo_Buffer, SLang_Undo_Len);
+    return NULL;
+ }
+diff -ur slang.old/src/slkeypad.c slang/src/slkeypad.c
+--- slang.old/src/slkeypad.c   Fri Apr 24 09:16:47 1998
++++ slang/src/slkeypad.c       Sat Jul  4 07:30:31 1998
+@@ -110,7 +110,7 @@
+    key = SLang_do_key (Keymap_List, (int (*)(void)) SLang_getkey);
+    if ((key == NULL) || (key->type != SLKEY_F_KEYSYM))
+      {
+-      SLang_flush_input ();
++      /* SLang_flush_input (); */
+       return SL_KEY_ERR;
+      }
index 0435ac76f64664ee8b5c682292532de353518f69..2b6d857c86fd613fa82ee62cfb9daf8991bf1d53 100644 (file)
--- a/pattern.c
+++ b/pattern.c
@@ -108,7 +108,7 @@ int mutt_which_case (const char *s)
 {
   while (*s)
   {
-    if (isalpha (*s) && isupper (*s))
+    if (isalpha ((unsigned char) *s) && isupper ((unsigned char) *s))
       return 0; /* case-sensitive */
     s++;
   }
@@ -242,14 +242,17 @@ int eat_regexp (pattern_t *pat, BUFFER *s, BUFFER *err)
 int eat_range (pattern_t *pat, BUFFER *s, BUFFER *err)
 {
   char *tmp;
-
+  int do_exclusive = 0;
+  
+  if (*s->dptr == '<')
+    do_exclusive = 1;
   if ((*s->dptr != '-') && (*s->dptr != '<'))
   {
     /* range minimum */
     if (*s->dptr == '>')
     {
       pat->max = M_MAXRANGE;
-      pat->min = strtol (s->dptr + 1, &tmp, 0);
+      pat->min = strtol (s->dptr + 1, &tmp, 0) + 1; /* exclusive range */
     }
     else
       pat->min = strtol (s->dptr, &tmp, 0);
@@ -283,7 +286,7 @@ int eat_range (pattern_t *pat, BUFFER *s, BUFFER *err)
     tmp = s->dptr;
   }
   
-  if (isdigit (*tmp))
+  if (isdigit ((unsigned char) *tmp))
   {
     /* range maximum */
     pat->max = strtol (tmp, &tmp, 0);
@@ -297,6 +300,8 @@ int eat_range (pattern_t *pat, BUFFER *s, BUFFER *err)
       pat->max *= 1048576;
       tmp++;
     }
+    if (do_exclusive)
+      (pat->max)--;
   }
   else
     pat->max = M_MAXRANGE;
@@ -792,7 +797,7 @@ mutt_pattern_exec (struct pattern_t *pat, pattern_exec_flag flags, CONTEXT *ctx,
       return (pat->not ^ (h->score >= pat->min && (pat->max == M_MAXRANGE ||
                                                   h->score <= pat->max)));
     case M_SIZE:
-      return (pat->not ^ (h->content->length > pat->min && (pat->max == M_MAXRANGE || h->content->length < pat->max)));
+      return (pat->not ^ (h->content->length >= pat->min && (pat->max == M_MAXRANGE || h->content->length <= pat->max)));
     case M_REFERENCE:
       return (pat->not ^ match_reference (pat->rx, h->env->references));
     case M_ADDRESS:
@@ -865,7 +870,7 @@ void mutt_check_simple (char *s, size_t len, const char *simple)
   }
 }
 
-int mutt_pattern_func (int op, char *prompt, HEADER *hdr)
+int mutt_pattern_func (int op, char *prompt)
 {
   pattern_t *pat;
   char buf[LONG_STRING] = "", *simple, error[STRING];
diff --git a/pgp.c b/pgp.c
index 36e4497bcaae508466fe180b7b9e998cf82bb6d9..28c1fac8ce6a1ae0f021526d9325b4be1dd842b2 100644 (file)
--- a/pgp.c
+++ b/pgp.c
@@ -1110,7 +1110,7 @@ BODY *pgp_sign_message (BODY *a)
  */
 char *pgp_findKeys (ADDRESS *to, ADDRESS *cc, ADDRESS *bcc)
 {
-  char *key, *keylist = NULL;
+  char *key, *keyID, *keylist = NULL;
   size_t keylist_size = 0;
   size_t keylist_used = 0;
   ADDRESS *tmp = NULL;
@@ -1145,9 +1145,17 @@ char *pgp_findKeys (ADDRESS *to, ADDRESS *cc, ADDRESS *bcc)
 
   for (p = tmp; p ; p = p->next)
   {
-    if ((k_info = ki_getkeybyaddr (pgp, p, db, KEYFLAG_CANENCRYPT)) == NULL)
+    char buf[LONG_STRING];
+
+    k_info = NULL;
+    if ((keyID = mutt_pgp_hook (p)) != NULL)
+    {
+      snprintf (buf, sizeof (buf), "Use keyID = \"%s\" for %s?", keyID, p->mailbox);
+      if (mutt_yesorno (buf, M_YES) == M_YES)
+       k_info = ki_getkeybystr (pgp, keyID, db, KEYFLAG_CANENCRYPT);
+    }
+    if (k_info == NULL && (k_info = ki_getkeybyaddr (pgp, p, db, KEYFLAG_CANENCRYPT)) == NULL)
     {
-      char buf[LONG_STRING];
       snprintf (buf, sizeof (buf), "Enter keyID for %s: ", p->mailbox);
       
       if ((key = pgp_ask_for_key (pgp, db, buf, p->mailbox,
index cbd53c1ceec17e773e294421fc144c3d456b8833..c3499ea6a4680c32d43f79e2886b9f8d202fed11 100644 (file)
@@ -542,8 +542,6 @@ static KEYINFO *pgp_parse_keyinfo(unsigned char *buff, size_t l)
 static int pgp_parse_pgp2_sig(unsigned char *buff, size_t l, KEYINFO *p)
 {
   unsigned char sigtype;
-  unsigned char pkalg;
-  unsigned char hashalg;
   long sig_gen_time;
   unsigned long signerid;
   size_t j;
@@ -564,9 +562,6 @@ static int pgp_parse_pgp2_sig(unsigned char *buff, size_t l, KEYINFO *p)
   for(i = 0; i < 4; i++)
     signerid = (signerid << 8) + buff[j++];
   
-  pkalg = buff[j++];
-  hashalg = buff[j++];
-  
   if(sigtype == 0x20 || sigtype == 0x28)
     p->flags |= KEYFLAG_REVOKED;
   
@@ -621,9 +616,9 @@ static int pgp_parse_pgp3_sig(unsigned char *buff, size_t l, KEYINFO *p)
        if(!--ml) break;
       }
       
-      ml -= skl;
-      if(ml < 0)
+      if((int) ml - (int) skl < 0)
        break;
+      ml -= skl;
       
       nextone = j + skl;
       skt = buff[j++];
@@ -795,6 +790,9 @@ static KEYINFO *pgp_read_keyring(const char *fname)
       case PT_NAME:
       {
        char *chr;
+       
+       if(!addr) break;
+       
        chr = safe_malloc(l);
        memcpy(chr, buff + 1, l - 1);
        chr[l-1] = '\0';
@@ -835,13 +833,21 @@ KEYINFO *pgp_read_secring(struct pgp_vinfo *pgp)
 void pgp_close_keydb (KEYINFO **ki)
 {
   KEYINFO *tmp, *k = *ki;
-  LIST *q;
+  PGPUID *uid;
+  LIST *p, *q;
   
   while (k)
   {
     if (k->keyid) safe_free ((void **)&k->keyid);
-    for(q = k->address; q; q = q-> next)
+    for(q = k->address; q; q = p)
+    {
+      uid = (PGPUID *) q->data;
+      p = q->next;
+
+      safe_free((void **)&uid->addr);
       safe_free((void **)&q->data);
+      safe_free((void **)&q);
+    }
     tmp = k;
     k = k->next;
     safe_free ((void **)&tmp);
diff --git a/pop.c b/pop.c
index c3495a0481fc0e36c70c52f068ea8fa6d4081541..76e7fd501a0d279826f017e0bdff9e2590a27d80 100644 (file)
--- a/pop.c
+++ b/pop.c
@@ -62,7 +62,9 @@ static int getPass (void)
   if (!PopPass)
   {
     char tmp[SHORT_STRING];
-    if (mutt_get_password ("POP Password: ", tmp, sizeof (tmp)) != 0)
+    tmp[0] = '\0';
+    if (mutt_get_password ("POP Password: ", tmp, sizeof (tmp)) != 0
+       || *tmp == '\0')
       return 0;
     PopPass = safe_strdup (tmp);
   }
@@ -104,10 +106,10 @@ void mutt_fetchPopMail (void)
   sin.sin_family = AF_INET;
   sin.sin_port = htons (PopPort);
 
-  if ((n = inet_addr (PopHost)) == -1)
+  if ((n = inet_addr (NONULL(PopHost))) == -1)
   {
     /* Must be a DNS name */
-    if ((he = gethostbyname (PopHost)) == NULL)
+    if ((he = gethostbyname (NONULL(PopHost))) == NULL)
     {
       mutt_error ("Could not find address for host %s.", PopHost);
       return;
@@ -135,7 +137,7 @@ void mutt_fetchPopMail (void)
     goto finish;
   }
 
-  sprintf (buffer, "user %s\r\n", PopUser);
+  snprintf (buffer, sizeof(buffer), "user %s\r\n", PopUser);
   write (s, buffer, strlen (buffer));
 
   if (getLine (s, buffer, sizeof (buffer)) == -1)
@@ -148,7 +150,7 @@ void mutt_fetchPopMail (void)
     goto finish;
   }
   
-  sprintf (buffer, "pass %s\r\n", PopPass);
+  snprintf (buffer, sizeof(buffer), "pass %s\r\n", NONULL(PopPass));
   write (s, buffer, strlen (buffer));
   
   if (getLine (s, buffer, sizeof (buffer)) == -1)
@@ -156,7 +158,10 @@ void mutt_fetchPopMail (void)
 
   if (strncmp (buffer, "+OK", 3) != 0)
   {
-    PopPass[0] = 0; /* void the given password */
+    if(PopPass)
+      memset(PopPass, 0, strlen(PopPass));
+    
+    safe_free((void **) &PopPass); /* void the given password */
     mutt_remove_trailing_ws (buffer);
     mutt_error (buffer[0] ? buffer : "Server closed connection!");
     goto finish;
@@ -183,7 +188,7 @@ void mutt_fetchPopMail (void)
     goto finish;
   }
 
-  if (mx_open_mailbox (Spoolfile, M_APPEND, &ctx) == NULL)
+  if (mx_open_mailbox (NONULL(Spoolfile), M_APPEND, &ctx) == NULL)
     goto finish;
 
   snprintf (msgbuf, sizeof (msgbuf),
@@ -192,7 +197,7 @@ void mutt_fetchPopMail (void)
 
   for (i = 1 ; i <= msgs ; i++)
   {
-    sprintf (buffer, "retr %d\r\n", i);
+    snprintf (buffer, sizeof(buffer), "retr %d\r\n", i);
     write (s, buffer, strlen (buffer));
 
     if (getLine (s, buffer, sizeof (buffer)) == -1)
@@ -268,7 +273,7 @@ void mutt_fetchPopMail (void)
     if (option (OPTPOPDELETE))
     {
       /* delete the message on the server */
-      sprintf (buffer, "dele %d\r\n", i);
+      snprintf (buffer, sizeof(buffer), "dele %d\r\n", i);
       write (s, buffer, strlen (buffer));
 
       /* eat the server response */
index b8bf6cf862dd1efc5d65bdd920254ceb8fb2b6da..0ef74fbe8fe9bb5a0de8df46300434491f4f9630 100644 (file)
@@ -241,8 +241,12 @@ int mutt_get_postponed (CONTEXT *ctx, HEADER *hdr, HEADER **cur)
       file[0] = '\0';
       if (b->filename)
        strfcpy (file, b->filename, sizeof (file));
-      mutt_adv_mktemp (file);
-      if (mutt_save_attachment (msg->fp, b, file, 0) == -1)
+      else
+       /* avoid Content-Disposition: header with temporary filename */
+       b->use_disp = 0;
+
+      mutt_adv_mktemp (file, sizeof(file));
+      if (mutt_save_attachment (msg->fp, b, file, 0, NULL) == -1)
       {
        mutt_free_envelope (&hdr->env);
        mutt_free_body (&hdr->content);
@@ -255,6 +259,7 @@ int mutt_get_postponed (CONTEXT *ctx, HEADER *hdr, HEADER **cur)
       b->filename = safe_strdup (file);
       b->unlink = 1;
       mutt_free_body (&b->parts);
+      mutt_stamp_attachment(b);
       b = b->next;
     }
     h->content->parts = NULL;
@@ -262,7 +267,7 @@ int mutt_get_postponed (CONTEXT *ctx, HEADER *hdr, HEADER **cur)
   else
   {
     mutt_mktemp (file);
-    if (mutt_save_attachment (msg->fp, h->content, file, 0) == -1)
+    if (mutt_save_attachment (msg->fp, h->content, file, 0, NULL) == -1)
     {
       mutt_free_envelope (&hdr->env);
       mx_close_message (&msg);
@@ -270,7 +275,7 @@ int mutt_get_postponed (CONTEXT *ctx, HEADER *hdr, HEADER **cur)
       safe_free ((void **) &PostContext);
       return (-1);
     }
-    hdr->content = mutt_make_attach (file);
+    hdr->content = mutt_make_file_attach (file);
     hdr->content->use_disp = 0;        /* no content-disposition */
     hdr->content->unlink = 1;  /* delete when we are done */
   }
index 38a1ad29aa14f60fc0f4418d44f47fcc4793c094..808b009d51d5d23f7344649f51380da44e11e6c6 100644 (file)
--- a/protos.h
+++ b/protos.h
@@ -70,7 +70,8 @@ ADDRESS *mutt_expand_aliases (ADDRESS *);
 ADDRESS *mutt_parse_adrlist (ADDRESS *, const char *);
 
 BODY *mutt_dup_body (BODY *);
-BODY *mutt_make_attach (const char *);
+BODY *mutt_make_file_attach (const char *);
+BODY *mutt_make_message_attach (CONTEXT *, HEADER *, int);
 BODY *mutt_make_multipart (BODY *);
 BODY *mutt_new_body (void);
 BODY *mutt_parse_multipart (FILE *, const char *, long, int);
@@ -86,18 +87,34 @@ time_t mutt_local_tz (void);
 time_t mutt_mktime (struct tm *, int);
 time_t is_from (const char *, char *, size_t);
 
+const char *mutt_attach_fmt (
+       char *dest,
+       size_t destlen,
+       char op,
+       const char *src,
+       const char *prefix,
+       const char *ifstring,
+       const char *elsestring,
+       unsigned long data,
+       format_flag flags);
+
 char *mutt_expand_path (char *, size_t);
 char *mutt_find_hook (int, const char *);
 char *mutt_generate_boundary (void);
 char *mutt_gen_msgid (void);
 char *mutt_get_name (ADDRESS *);
 char *mutt_get_parameter (const char *, PARAMETER *);
+#ifdef _PGPPATH
+char *mutt_pgp_hook (ADDRESS *);
+#endif /* _PGPPATH */
 char *mutt_read_line (char *, size_t *, FILE *, int *);
 char *mutt_strlower (char *);
 char *mutt_skip_whitespace (char *);
 char *mutt_substrcpy (char *, const char *, const char *, size_t);
 char *mutt_substrdup (const char *, const char *);
 
+const char *mutt_fqdn(short);
+
 void mutt_add_child_pid (pid_t);
 void mutt_alias_menu (char *, size_t, ALIAS *);
 void mutt_block_signals (void);
@@ -128,8 +145,6 @@ void mutt_free_header (HEADER **);
 void mutt_free_parameter (PARAMETER **);
 void mutt_generate_header (char *, size_t, HEADER *, int);
 void mutt_help (int);
-void mutt_index_menu (void);
-void mutt_init_history (void);
 void mutt_linearize_tree (CONTEXT *, int);
 void mutt_make_help (char *, size_t, char *, int, int);
 void mutt_message (const char *, ...);
@@ -147,6 +162,7 @@ void mutt_remove_trailing_ws (char *);
 void mutt_query_exit (void);
 void mutt_query_menu (char *, size_t);
 void mutt_safe_path (char *s, size_t l, ADDRESS *a);
+void mutt_sanitize_filename (char *);
 void mutt_save_path (char *s, size_t l, ADDRESS *a);
 void mutt_score_message (HEADER *);
 void mutt_select_fcc (char *, size_t, HEADER *);
@@ -156,6 +172,7 @@ void mutt_set_flag (CONTEXT *, HEADER *, int, int);
 void mutt_shell_escape (void);
 void mutt_show_error (void);
 void mutt_signal_init (void);
+void mutt_stamp_attachment (BODY *a);
 void mutt_tabs_to_spaces (char *);
 void mutt_tag_set_flag (int, int);
 void mutt_unblock_signals (void);
@@ -187,15 +204,17 @@ int mutt_compose_attachment (BODY *a);
 int mutt_copy_bytes (FILE *, FILE *, size_t);
 int mutt_copy_stream (FILE *, FILE *);
 int mutt_decode_save_attachment (FILE *, BODY *, char *, int, int);
-int mutt_display_message (HEADER *h);
-int mutt_edit_attachment(BODY *, int);
+int mutt_display_message (HEADER *h, const char *);
+int mutt_edit_attachment(BODY *);
 int mutt_enter_fname (const char *, char *, size_t, int *, int);
 int mutt_enter_string (unsigned char *, size_t, int, int, int);
 int mutt_get_field (char *, char *, size_t, int);
 int mutt_get_password (char *, char *, size_t);
 int mutt_get_postponed (CONTEXT *, HEADER *, HEADER **);
+int mutt_index_menu (int);
 int mutt_is_autoview (char *);
 int mutt_is_mail_list (ADDRESS *);
+int mutt_is_message_type(int, const char *);
 int mutt_is_list_recipient (ADDRESS *a);
 int mutt_is_text_type (int, char *);
 int mutt_is_valid_mailbox (const char *);
@@ -208,16 +227,17 @@ int mutt_parse_hook (BUFFER *, BUFFER *, unsigned long, BUFFER *);
 int mutt_parse_macro (BUFFER *, BUFFER *, unsigned long, BUFFER *);
 int mutt_parse_mailboxes (BUFFER *, BUFFER *, unsigned long, BUFFER *);
 int mutt_parse_mono (BUFFER *, BUFFER *, unsigned long, BUFFER *);
+int mutt_parse_unmono (BUFFER *, BUFFER *, unsigned long, BUFFER *);
 int mutt_parse_push (BUFFER *, BUFFER *, unsigned long, BUFFER *);
 int mutt_parse_rc_line (/* const */ char *, BUFFER *, BUFFER *);
 int mutt_parse_score (BUFFER *, BUFFER *, unsigned long, BUFFER *);
 int mutt_parse_unscore (BUFFER *, BUFFER *, unsigned long, BUFFER *);
-int mutt_pattern_func (int, char *, HEADER *);
+int mutt_pattern_func (int, char *);
 int mutt_pipe_attachment (FILE *, BODY *, const char *, char *); 
 int mutt_pipe_message (HEADER *);
 int mutt_print_attachment (FILE *, BODY *);
 int mutt_query_complete (char *, size_t);
-int mutt_save_attachment (FILE *, BODY *, char *, int);
+int mutt_save_attachment (FILE *, BODY *, char *, int, HEADER *);
 int mutt_save_message (HEADER *, int, int, int *);
 int mutt_search_command (int, int);
 int mutt_send_menu (HEADER *, char *, size_t, HEADER *);
@@ -234,6 +254,7 @@ int mutt_write_rfc822_header (FILE *, ENVELOPE *, BODY *, int);
 int mutt_yesorno (const char *, int);
 void mutt_cache_index_colors(CONTEXT *);
 void mutt_set_header_color(CONTEXT *, HEADER *);
+int mutt_save_confirm (const char  *, struct stat *);
 
 int mh_valid_message (const char *);
 
@@ -248,6 +269,7 @@ void *safe_malloc (unsigned int);
 void safe_realloc (void **, size_t);
 void safe_free (void **);
 
+int safe_open (const char *, int);
 FILE *safe_fopen (const char *, const char *);
 
 ADDRESS *alias_reverse_lookup (ADDRESS *);
@@ -267,7 +289,7 @@ ADDRESS *alias_reverse_lookup (ADDRESS *);
        ((unsigned char)(c) >= 0xa0)))
 #endif
 
-#define new_pattern() calloc(1, sizeof (pattern_t))
+#define new_pattern() safe_calloc(1, sizeof (pattern_t))
 
 int mutt_pattern_exec (struct pattern_t *pat, pattern_exec_flag flags, CONTEXT *ctx, HEADER *h);
 pattern_t *mutt_pattern_comp (/* const */ char *s, int flags, BUFFER *err);
@@ -288,12 +310,6 @@ void mutt_pattern_free (pattern_t **pat);
 #define DRAND (double)rand
 #endif /* HAVE_SRAND48 */
 
-#ifdef HAVE_SETEGID
-#define SETEGID setegid
-#else
-#define SETEGID setgid
-#endif
-
 int getdnsdomainname (char *, size_t);
 
 /* According to SCO support, this is how to detect SCO */
diff --git a/query.c b/query.c
index b8cfe09ba78a40b3f316280034f300226ad8253b..d8ae80ae782208f6dee973f99e362b06e5b7e216 100644 (file)
--- a/query.c
+++ b/query.c
@@ -18,6 +18,7 @@
 
 #include "mutt.h"
 #include "mutt_menu.h"
+#include "mapping.h"
 #include "sort.h"
 
 #include <string.h>
diff --git a/reap.pl b/reap.pl
index 90e532bd0897ea4a5e4343d75b71f34a0a85990e..43b44646c603283698f5490ca972b32672ecbdb8 100755 (executable)
--- a/reap.pl
+++ b/reap.pl
@@ -1,4 +1,4 @@
-#!/usr/local/bin/perl
+#!/usr/bin/perl
 #
 # A small script to strip out any "illegal" PGP code to make sure it is
 # safe for International export.
index 670bf495b1d8180d9f9928029bf0206a6775dca2..cd16309d0db4bf7eba18fa3754946bc7a7c8ec68 100644 (file)
@@ -39,6 +39,7 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <sys/wait.h>
+#include <sys/stat.h>
 #include <string.h>
 #include <errno.h>
 
@@ -59,6 +60,7 @@ void mutt_update_tree (ATTACHPTR **idx, short idxlen)
 
   for (x = 0; x < idxlen; x++)
   {
+    idx[x]->num = x;
     if (2 * (idx[x]->level + 2) < sizeof (buf))
     {
       if (idx[x]->level)
@@ -118,9 +120,7 @@ ATTACHPTR **mutt_gen_attach_list (BODY *m,
       new->level = level;
 
       /* We don't support multipart messages in the compose menu yet */
-      if (!compose && m->type == TYPEMESSAGE &&
-         (!strcasecmp (m->subtype, "rfc822") ||
-          !strcasecmp (m->subtype, "news")) && is_multipart (m->parts))
+      if (!compose && mutt_is_message_type(m->type, m->subtype) && is_multipart (m->parts))
       {
        idx = mutt_gen_attach_list (m->parts, idx, idxlen, idxmax, level + 1, compose);
       }
@@ -133,32 +133,117 @@ ATTACHPTR **mutt_gen_attach_list (BODY *m,
   return (idx);
 }
 
+/* %D = deleted flag
+   %d = description
+   %e = MIME content-transfer-encoding
+   %f = filename
+   %t = tagged flag
+   %m = major MIME type
+   %M = MIME subtype
+   %n = attachment number
+   %s = size
+   %u = unlink */
+const char *mutt_attach_fmt (char *dest,
+    size_t destlen,
+    char op,
+    const char *src,
+    const char *prefix,
+    const char *ifstring,
+    const char *elsestring,
+    unsigned long data,
+    format_flag flags)
+{
+  char fmt[16];
+  ATTACHPTR *aptr = (ATTACHPTR *) data;
+
+  switch (op)
+  {
+    case 'd':
+      snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
+      if (aptr->content->description)
+      {
+       snprintf (dest, destlen, fmt, aptr->content->description);
+       break;
+      }
+      if (mutt_is_message_type(aptr->content->type, aptr->content->subtype) &&
+         MsgFmt && aptr->content->hdr)
+      {
+       char s[SHORT_STRING];
+       _mutt_make_string (s, sizeof (s), MsgFmt, NULL, aptr->content->hdr,
+           M_FORMAT_FORCESUBJ | M_FORMAT_MAKEPRINT);
+       if (*s)
+       {
+         snprintf (dest, destlen, fmt, s);
+         break;
+       }
+      }
+      if (!aptr->content->filename)
+      {
+       snprintf (dest, destlen, fmt, "<no description>");
+       break;
+      }
+      /* FALLS THROUGH TO 'f' */
+    case 'f':
+      snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
+      if (aptr->content->filename && *aptr->content->filename == '/')
+      {
+         char path[_POSIX_PATH_MAX];
+         
+         strfcpy (path, aptr->content->filename, sizeof (path));
+         mutt_pretty_mailbox (path);
+         snprintf (dest, destlen, fmt, path);
+      }
+      else
+         snprintf (dest, destlen, fmt, NONULL (aptr->content->filename));
+      break;
+    case 'D':
+      snprintf (dest, destlen, "%c", aptr->content->deleted ? 'D' : ' ');
+      break;
+    case 'e':
+      snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
+      snprintf (dest, destlen, fmt, ENCODING (aptr->content->encoding));
+      break;
+    case 'm':
+      snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
+      snprintf (dest, destlen, fmt, TYPE (aptr->content));
+      break;
+    case 'M':
+      snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
+      snprintf (dest, destlen, fmt, aptr->content->subtype);
+      break;
+    case 'n':
+      snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
+      snprintf (dest, destlen, fmt, aptr->num + 1);
+      break;
+    case 's':
+      if (flags & M_FORMAT_STAT_FILE)
+      {
+         struct stat st;
+
+         stat (aptr->content->filename, &st);
+         mutt_pretty_size (dest, destlen, st.st_size);
+      }
+      else
+         mutt_pretty_size (dest, destlen, aptr->content->length);
+      break;
+    case 't':
+      snprintf (dest, destlen, "%c", aptr->content->tagged ? '*' : ' ');
+      break;
+    case 'T':
+      snprintf (dest, destlen, "%s", NONULL (aptr->tree));
+      break;
+    case 'u':
+      snprintf (dest, destlen, "%c", aptr->content->unlink ? '-' : ' ');
+      break;
+    default:
+      *dest = 0;
+  }
+  return (src);
+}
+
 void attach_entry (char *b, size_t blen, MUTTMENU *menu, int num)
 {
-  char t[SHORT_STRING];
-  char s[SHORT_STRING];
-  char size[SHORT_STRING];
-  ATTACHPTR **idx = (ATTACHPTR **) menu->data;
-  BODY *m;
-
-  m = idx[num]->content;
-  s[0] = 0;
-  if (m->type == TYPEMESSAGE && (!strcasecmp ("rfc822", m->subtype) ||
-      !strcasecmp ("news", m->subtype)) && MsgFmt[0])
-    _mutt_make_string (s, sizeof (s), MsgFmt, NULL, m->hdr,
-                      M_FORMAT_FORCESUBJ | M_FORMAT_MAKEPRINT);
-
-  mutt_pretty_size (size, sizeof (size), m->length);
-  snprintf (t, sizeof (t), "[%.7s/%.10s, %.6s, %s]",
-           TYPE (m->type), m->subtype, ENCODING (m->encoding), size);
-  snprintf (b, blen, " %c%c %2d %-34.34s %s%s",
-           m->deleted ? 'D' : ' ',
-           m->tagged ? '*' : ' ',
-           num + 1,
-           t,
-           idx[num]->tree ? idx[num]->tree : "",
-           s[0] ? s : (m->description ? m->description :
-                       (m->filename ? m->filename : "<no description>")));
+  mutt_FormatString (b, blen, NONULL (AttachFormat), mutt_attach_fmt, (unsigned long) (((ATTACHPTR **)menu->data)[num]), 0);
 }
 
 int mutt_tag_attach (MUTTMENU *menu, int n)
@@ -166,35 +251,119 @@ int mutt_tag_attach (MUTTMENU *menu, int n)
   return (((ATTACHPTR **) menu->data)[n]->content->tagged = !((ATTACHPTR **) menu->data)[n]->content->tagged);
 }
 
-static void mutt_query_save_attachment (FILE *fp, BODY *body)
+int mutt_is_message_type (int type, const char *subtype)
 {
-  char buf[_POSIX_PATH_MAX], tfile[_POSIX_PATH_MAX];
+  if (type != TYPEMESSAGE)
+    return 0;
+
+  subtype = NONULL(subtype);
+  return (strcasecmp (subtype, "rfc822") == 0 || strcasecmp (subtype, "news") == 0);
+}
 
-  if (fp && body->filename)
+static int mutt_query_save_attachment (FILE *fp, BODY *body, HEADER *hdr)
+{
+  char buf[_POSIX_PATH_MAX], tfile[_POSIX_PATH_MAX];
+  int is_message;
+  
+  if (body->filename)
     strfcpy (buf, body->filename, sizeof (buf));
+  else if(body->hdr &&
+         body->encoding != ENCBASE64 &&
+         body->encoding != ENCQUOTEDPRINTABLE &&
+         mutt_is_message_type(body->type, body->subtype))
+    mutt_default_save(buf, sizeof(buf), body->hdr);
   else
     buf[0] = 0;
-  if (mutt_get_field ("Save to file: ", buf, sizeof (buf), M_FILE | M_CLEAR) != 0 || !buf[0])
-    return;
+  
+  if (mutt_get_field ("Save to file: ", buf, sizeof (buf), M_FILE | M_CLEAR) != 0 
+      || !buf[0])
+    return -1;
+
   mutt_expand_path (buf, sizeof (buf));
-  if (mutt_check_overwrite (body->filename, buf, tfile, sizeof (tfile), 0))
-    return;
+
+  is_message = (fp && 
+      body->hdr && 
+      body->encoding != ENCBASE64 && 
+      body->encoding != ENCQUOTEDPRINTABLE && 
+      mutt_is_message_type (body->type, body->subtype));
+  
+  if (is_message)
+  {
+    struct stat st;
+    
+    /* check to make sure that this file is really the one the user wants */
+    if (!mutt_save_confirm (buf, &st))
+    {
+      CLEARLINE (LINES-1);
+      return -1;
+    }
+    strfcpy(tfile, buf, sizeof(tfile));
+  }
+  else if (mutt_check_overwrite (body->filename, buf, tfile, sizeof (tfile), 0))
+    return -1;
+  
   mutt_message ("Saving...");
-  if (mutt_save_attachment (fp, body, tfile, 0) == 0)
+  if (mutt_save_attachment (fp, body, tfile, 0, (hdr || !is_message) ? hdr : body->hdr) == 0)
+  {
     mutt_message ("Attachment saved.");
+    return 0;
+  }
+  
+  return -1;
+  
 }
 
-void mutt_save_attachment_list (FILE *fp, int tag, BODY *top)
+void mutt_save_attachment_list (FILE *fp, int tag, BODY *top, HEADER *hdr)
 {
+  char buf[_POSIX_PATH_MAX], tfile[_POSIX_PATH_MAX];
+  int rc = 1;
+  FILE *fpout;
+
+  buf[0] = 0;
+
   for (; top; top = top->next)
   {
     if (!tag || top->tagged)
-      mutt_query_save_attachment (fp, top);
+    {
+      if (!option (OPTATTACHSPLIT))
+      {
+       if (!buf[0])
+       {
+         strfcpy (buf, NONULL (top->filename), sizeof (buf));
+         if (mutt_get_field ("Save to file: ", buf, sizeof (buf),
+                                   M_FILE | M_CLEAR) != 0 || !buf[0])
+           return;
+         mutt_expand_path (buf, sizeof (buf));
+         if (mutt_check_overwrite (top->filename, buf, tfile, sizeof (tfile), 0))
+           return;
+         rc = mutt_save_attachment (fp, top, tfile, 0, hdr);
+         if (rc == 0 && AttachSep && (fpout = fopen (tfile,"a")) != NULL)
+         {
+           fprintf(fpout, "%s", AttachSep);
+           fclose (fpout);
+         }
+       }
+       else
+       {
+         rc = mutt_save_attachment (fp, top, tfile, M_SAVE_APPEND, hdr);
+         if (rc == 0 && AttachSep && (fpout = fopen (tfile,"a")) != NULL)
+         {
+           fprintf(fpout, "%s", AttachSep);
+           fclose (fpout);
+         }
+       }
+      }
+      else
+       mutt_query_save_attachment (fp, top, hdr);
+    }
     else if (top->parts)
-      mutt_save_attachment_list (fp, 1, top->parts);
+      mutt_save_attachment_list (fp, 1, top->parts, hdr);
     if (!tag)
       return;
   }
+
+  if (!option (OPTATTACHSPLIT) && (rc == 0))
+    mutt_message ("Attachment saved");
 }
 
 static void
@@ -234,13 +403,44 @@ mutt_query_pipe_attachment (char *command, FILE *fp, BODY *body, int filter)
   }
 }
 
+static STATE state;
+static void pipe_attachment (FILE *fp, BODY *b)
+{
+  FILE *ifp;
+
+  if (fp)
+  {
+    state.fpin = fp;
+    mutt_decode_attachment (b, &state);
+    if (AttachSep)
+      state_puts (AttachSep, &state);
+  }
+  else
+  {
+    if ((ifp = fopen (b->filename, "r")) == NULL)
+    {
+      mutt_perror ("fopen");
+      return;
+    }
+    mutt_copy_stream (ifp, state.fpout);
+    fclose (ifp);
+    if (AttachSep)
+      state_puts (AttachSep, &state);
+  }
+}
+
 static void
 pipe_attachment_list (char *command, FILE *fp, int tag, BODY *top, int filter)
 {
   for (; top; top = top->next)
   {
     if (!tag || top->tagged)
-      mutt_query_pipe_attachment (command, fp, top, filter);
+    {
+      if (!filter && !option (OPTATTACHSPLIT))
+       pipe_attachment (fp, top);
+      else
+       mutt_query_pipe_attachment (command, fp, top, filter);
+    }
     else if (top->parts)
       pipe_attachment_list (command, fp, tag, top->parts, filter);
     if (!tag)
@@ -251,26 +451,104 @@ pipe_attachment_list (char *command, FILE *fp, int tag, BODY *top, int filter)
 void mutt_pipe_attachment_list (FILE *fp, int tag, BODY *top, int filter)
 {
   char buf[SHORT_STRING];
+  pid_t thepid;
 
   if (fp)
     filter = 0; /* sanity check: we can't filter in the recv case yet */
 
   buf[0] = 0;
+  memset (&state, 0, sizeof (STATE));
+
   if (mutt_get_field ((filter ? "Filter through: " : "Pipe to: "),
                                  buf, sizeof (buf), 0) != 0 || !buf[0])
     return;
+
   mutt_expand_path (buf, sizeof (buf));
-  pipe_attachment_list (buf, fp, tag, top, filter);
+
+  if (!filter && !option (OPTATTACHSPLIT))
+  {
+    endwin ();
+    thepid = mutt_create_filter (buf, &state.fpout, NULL, NULL);
+    pipe_attachment_list (buf, fp, tag, top, filter);
+    fclose (state.fpout);
+    if (mutt_wait_filter (thepid) != 0 || option (OPTWAITKEY))
+      mutt_any_key_to_continue (NULL);
+  }
+  else
+    pipe_attachment_list (buf, fp, tag, top, filter);
+}
+
+static int can_print (BODY *top, int tag)
+{
+  char type [STRING];
+
+  for (; top; top = top->next)
+  {
+    snprintf (type, sizeof (type), "%s/%s", TYPE (top), top->subtype);
+    if (!tag || top->tagged)
+    {
+      if (!rfc1524_mailcap_lookup (top, type, NULL, M_PRINT))
+      {
+       if (strcasecmp ("text/plain", top->subtype) &&
+           strcasecmp ("application/postscript", top->subtype))
+       {
+         if (!mutt_can_decode (top))
+         {
+           mutt_error ("I dont know how to print %s attachments!", type);
+           return (0);
+         }
+       }
+      }
+    }
+    else if (top->parts)
+      return (can_print (top->parts, tag));
+    if (!tag)
+      break;
+  }
+  return (1);
 }
 
 static void print_attachment_list (FILE *fp, int tag, BODY *top)
 {
+  char type [STRING];
+
+
   for (; top; top = top->next)
   {
     if (!tag || top->tagged)
-      mutt_print_attachment (fp, top);
+    {
+      snprintf (type, sizeof (type), "%s/%s", TYPE (top), top->subtype);
+      if (!option (OPTATTACHSPLIT) && !rfc1524_mailcap_lookup (top, type, NULL, M_PRINT))
+      {
+       if (!strcasecmp ("text/plain", top->subtype) ||
+           !strcasecmp ("application/postscript", top->subtype))
+         pipe_attachment (fp, top);
+       else if (mutt_can_decode (top))
+       {
+         /* decode and print */
+
+         char newfile[_POSIX_PATH_MAX] = "";
+         FILE *ifp;
+
+         mutt_mktemp (newfile);
+         if (mutt_decode_save_attachment (fp, top, newfile, 0, 0) == 0)
+         {
+           if ((ifp = fopen (newfile, "r")) != NULL)
+           {
+             mutt_copy_stream (ifp, state.fpout);
+             fclose (ifp);
+             if (AttachSep)
+               state_puts (AttachSep, &state);
+           }
+         }
+         mutt_unlink (newfile);
+       }
+      }
+      else
+       mutt_print_attachment (fp, top);
+    }
     else if (top->parts)
-      mutt_print_attachment_list (fp, tag, top->parts);
+      print_attachment_list (fp, tag, top->parts);
     if (!tag)
       return;
   }
@@ -278,18 +556,24 @@ static void print_attachment_list (FILE *fp, int tag, BODY *top)
 
 void mutt_print_attachment_list (FILE *fp, int tag, BODY *top)
 {
+  pid_t thepid;
   if (query_quadoption (OPT_PRINT, tag ? "Print tagged attachment(s)?" : "Print attachment?") != M_YES)
     return;
-  print_attachment_list (fp, tag, top);
-}
 
-int mutt_is_message_type (int type, char *subtype)
-{
-  if (type != TYPEMESSAGE)
-    return 0;
-  if (strcasecmp (subtype, "rfc822") == 0 || strcasecmp (subtype, "news") == 0)
-    return 1;
-  return 0;
+  if (!option (OPTATTACHSPLIT))
+  {
+    if (!can_print (top, tag))
+      return;
+    endwin ();
+    memset (&state, 0, sizeof (STATE));
+    thepid = mutt_create_filter (NONULL (PrintCmd), &state.fpout, NULL, NULL);
+    print_attachment_list (fp, tag, top);
+    fclose (state.fpout);
+    if (mutt_wait_filter (thepid) != 0 || option (OPTWAITKEY))
+      mutt_any_key_to_continue (NULL);
+  }
+  else
+    print_attachment_list (fp, tag, top);
 }
 
 static void
@@ -404,9 +688,10 @@ create_tagged_message (const char *tempfile,
 }
 
 /* op          flag to ci_send_message()
-   tag         operate on tagged attachments?
-   hdr         current message
-   body                current attachment */
+ * tag         operate on tagged attachments?
+ * hdr         current message
+ * body                current attachment 
+ */
 static void reply_attachment_list (int op, int tag, HEADER *hdr, BODY *body)
 {
   HEADER *hn;
@@ -617,14 +902,11 @@ void mutt_view_attachments (HEADER *hdr)
        break;
 
       case OP_SAVE:
-       mutt_save_attachment_list (fp, menu->tagprefix, menu->tagprefix ? cur : idx[menu->current]->content);
+       mutt_save_attachment_list (fp, menu->tagprefix, menu->tagprefix ?  cur : idx[menu->current]->content, hdr);
        if (option (OPTRESOLVE) && menu->current < menu->max - 1)
-       {
          menu->current++;
-         menu->redraw = REDRAW_MOTION_RESYNCH;
-       }
-       else
-         menu->redraw = REDRAW_CURRENT;
+      
+        menu->redraw = REDRAW_MOTION_RESYNCH | REDRAW_FULL;
        break;
 
       case OP_DELETE:
index 7cece8527692fed087f3a2ccef28944f6f2239bc..7381eb7d0453f70928a20e5c2e87e1d79aac7e92 100644 (file)
--- a/reldate.h
+++ b/reldate.h
@@ -1 +1 @@
-const char *ReleaseDate = "1998-06-16";
+const char *ReleaseDate = "1998-08-24";
index ac16ae8bfa0fff3ddea3b108e7ec38a031e6cffb..d35a0ad1093709d034b0ac03595c8e005b75975e 100644 (file)
--- a/rfc1524.c
+++ b/rfc1524.c
@@ -55,14 +55,17 @@ int rfc1524_expand_command (BODY *a, char *filename, char *type,
   int needspipe = TRUE;
   char buf[LONG_STRING];
 
-  while (command[x] && x<clen && y<sizeof(buf)) {
+  while (command[x] && x<clen && y<sizeof(buf)) 
+  {
     if (command[x] == '\\') {
       x++;
       buf[y++] = command[x++];
     }
-    else if (command[x] == '%') {
+    else if (command[x] == '%') 
+    {
       x++;
-      if (command[x] == '{') {
+      if (command[x] == '{') 
+      {
        char param[STRING];
        int z = 0;
        char *ret = NULL;
@@ -138,7 +141,8 @@ static int get_field_text (char *field, char **entry,
   {
     if (entry)
     {
-      field = mutt_skip_whitespace (++field);
+      field++;
+      field = mutt_skip_whitespace (field);
       safe_free ((void **) entry);
       *entry = safe_strdup (field);
     }
@@ -289,7 +293,7 @@ static int rfc1524_mailcap_parse (BODY *a,
              /* a non-zero exit code means test failed */
              found = FALSE;
            }
-           free (test_command);
+           FREE (&test_command);
          }
        }
       } /* while (ch) */
@@ -338,14 +342,9 @@ static int rfc1524_mailcap_parse (BODY *a,
   return found;
 }
 
-rfc1524_entry *rfc1524_new_entry()
+rfc1524_entry *rfc1524_new_entry(void)
 {
-  rfc1524_entry *tmp;
-
-  tmp = (rfc1524_entry *)safe_malloc(sizeof(rfc1524_entry));
-  memset(tmp,0,sizeof(rfc1524_entry));
-
-  return tmp;
+  return (rfc1524_entry *)safe_calloc(1, sizeof(rfc1524_entry));
 }
 
 void rfc1524_free_entry(rfc1524_entry **entry)
@@ -420,156 +419,171 @@ int rfc1524_mailcap_lookup (BODY *a, char *type, rfc1524_entry *entry, int opt)
  * Renamed to mutt_adv_mktemp so I only have to change where it's
  * called, and not all possible cases.
  */
-void mutt_adv_mktemp (char *s)
+void mutt_adv_mktemp (char *s, size_t l)
 {
   char buf[_POSIX_PATH_MAX];
   char tmp[_POSIX_PATH_MAX];
   char *period;
-
+  size_t sl;
+  
   strfcpy (buf, NONULL (Tempdir), sizeof (buf));
   mutt_expand_path (buf, sizeof (buf));
   if (s[0] == '\0')
   {
-    sprintf (s, "%s/muttXXXXXX", buf);
+    snprintf (s, l, "%s/muttXXXXXX", buf);
     mktemp (s);
   }
   else
   {
     strfcpy (tmp, s, sizeof (tmp));
-    sprintf (s, "%s/%s", buf, tmp);
+    snprintf (s, l, "%s/%s", buf, tmp);
     if (access (s, F_OK) != 0)
       return;
     if ((period = strrchr (tmp, '.')) != NULL)
       *period = 0;
-    sprintf (s, "%s/%s.XXXXXX", buf, tmp);
+    snprintf (s, l, "%s/%s.XXXXXX", buf, tmp);
     mktemp (s);
     if (period != NULL)
     {
       *period = '.';
-      strcat (s, period);
+      sl = strlen(s);
+      strfcpy(s + sl, period, l - sl);
     }
   }
 }
 
-/* This routine expands the filename given to match the format of the
- * nametemplate given.  It returns various values based on what operations
- * it performs.
- *
+/* This routine will create a _temporary_ filename matching the
+ * name template given if this needs to be done.
+ * 
+ * Please note that only the last path element of the
+ * template and/or the old file name will be used for the
+ * comparison and the temporary file name.
+ * 
  * Returns 0 if oldfile is fine as is.
  * Returns 1 if newfile specified
  */
 
+static void strnfcpy(char *d, char *s, size_t siz, size_t len)
+{
+  if(len > siz)
+    len = siz - 1;
+  strfcpy(d, s, len);
+}
+
 int rfc1524_expand_filename (char *nametemplate,
                             char *oldfile, 
                             char *newfile,
                             size_t nflen)
 {
-  int z = 0;
-  int i = 0, j = 0;
-  int lmatch = TRUE;
-  int match = TRUE;
-  size_t len = 0;
+  int i, j, k, ps, r;
   char *s;
-
+  short lmatch = 0, rmatch = 0; 
+  char left[_POSIX_PATH_MAX];
+  char right[_POSIX_PATH_MAX];
+  
   newfile[0] = 0;
 
+  /* first, ignore leading path components.
+   */
+  
   if (nametemplate && (s = strrchr (nametemplate, '/')))
     nametemplate = s + 1;
 
   if (oldfile && (s = strrchr (oldfile, '/')))
-  {
-    len = s - oldfile + 1;
-    if (len > nflen)
-      len = nflen;
-    strfcpy (newfile, oldfile, len + 1);
-    oldfile += len;
-  }
-
-  /* If nametemplate is NULL, create a newfile from oldfile and return 0 */
+    oldfile = s + 1;
+    
   if (!nametemplate)
   {
     if (oldfile)
       strfcpy (newfile, oldfile, nflen);
-    mutt_adv_mktemp (newfile);
-    return 0;
   }
-
-  /* If oldfile is NULL, just return a newfile name */
-  if (!oldfile)
+  else if (!oldfile)
   {
     snprintf (newfile, nflen, nametemplate, "mutt");
-    mutt_adv_mktemp (newfile);
-    return 0;
   }
-
-  /* Next, attempt to determine if the oldfile already matches nametemplate */
-  /* Nametemplate is of the form pre%spost, only replace pre or post if
-   * they don't already match the oldfilename */
-  /* Test pre */
-
-  if ((s = strrchr (nametemplate, '%')) != NULL)
+  else /* oldfile && nametemplate */
   {
-    newfile[len] = '\0';
 
-    z = s - nametemplate;
-
-    for (i = 0; i < z && i < nflen; i++)
+    /* first, compare everything left from the "%s" 
+     * (if there is one).
+     */
+    
+    lmatch = 1; ps = 0;
+    for(i = 0; nametemplate[i]; i++)
     {
-      if (oldfile[i] != nametemplate[i])
-      {
-       lmatch=FALSE;
+      if(nametemplate[i] == '%' && nametemplate[i+1] == 's')
+      { 
+       ps = 1;
        break;
       }
-    }
 
-    if (!lmatch)
-    {
-      match = FALSE;
-      i = nflen - len;
-      if (i > z)
-       i = z;
-      strfcpy (newfile + len, nametemplate, i);
-    }
-
-    strfcpy (newfile + strlen (newfile), 
-           oldfile, nflen - strlen (newfile));
+      /* note that the following will _not_ read beyond oldfile's end. */
 
-    dprint (1, (debugfile,"template: %s, oldfile: %s, newfile: %s\n",
-             nametemplate, oldfile, newfile));
+      if(lmatch && nametemplate[i] != oldfile[i])
+       lmatch = 0;
+    }
 
-    /* test post */
-    lmatch = TRUE;
+    if(ps)
+    {
+      
+      /* If we had a "%s", check the rest. */
+      
+      /* now, for the right part: compare everything right from 
+       * the "%s" to the final part of oldfile.
+       * 
+       * The logic here is as follows:
+       * 
+       * - We start reading from the end.
+       * - There must be a match _right_ from the "%s",
+       *   thus the i + 2.  
+       * - If there was a left hand match, this stuff
+       *   must not be counted again.  That's done by the
+       *   condition (j >= (lmatch ? i : 0)).
+       */
+      
+      rmatch = 1;
 
-    for (z += 2, i = strlen (oldfile) - 1, j = strlen (nametemplate) - 1; 
-       i && j > z; i--, j--)
-      if (oldfile[i] != nametemplate[j])
+      for(r = 0, j = strlen(oldfile) - 1, k = strlen(nametemplate) - 1 ;
+         j >= (lmatch ? i : 0) && k >= i + 2;
+         j--, k--)
       {
-       lmatch = FALSE;
-       break;
+       if(nametemplate[k] != oldfile[j])
+       {
+         rmatch = 0;
+         break;
+       }
       }
-
-    if (!lmatch)
+      
+      /* Now, check if we had a full match. */
+      
+      if(k >= i + 2)
+       rmatch = 0;
+      
+      if(lmatch) *left = 0;
+      else strnfcpy(left, nametemplate, sizeof(left), i);
+      
+      if(rmatch) *right = 0;
+      else strfcpy(right, nametemplate + i + 2, sizeof(right));
+      
+      snprintf(newfile, nflen, "%s%s%s", left, oldfile, right);
+    }
+    else
     {
-      match = FALSE;
-      strfcpy (newfile + strlen (newfile),
-             nametemplate + z, nflen - strlen (newfile));
+      /* no "%s" in the name template. */
+      strfcpy(newfile, nametemplate, nflen);
     }
-
-    if (match) 
-      return 0;
-
-    return 1;
   }
-  else
-  {
-    /* no %s in nametemplate, graft unto path of oldfile */
-    strfcpy (newfile, nametemplate, nflen);
+  
+  mutt_adv_mktemp(newfile, nflen);
+
+  if(rmatch && lmatch)
+    return 0;
+  else 
     return 1;
-  }
+  
 }
 
-/* For nametemplate support, we may need to rename a file.
- * If rfc1524_expand_command() is used on a recv'd message, then
+/* If rfc1524_expand_command() is used on a recv'd message, then
  * the filename doesn't exist yet, but if its used while sending a message,
  * then we need to rename the existing file.
  *
index a34e7fee013269044753c7698aa08885edc74694..1051f111233bb31e833859d76a8e0f78f8dbdc3f 100644 (file)
--- a/rfc1524.h
+++ b/rfc1524.h
@@ -34,12 +34,12 @@ typedef struct rfc1524_mailcap_entry {
   unsigned int copiousoutput : 1;  /* needs pager, basically */
 } rfc1524_entry;
 
-rfc1524_entry *rfc1524_new_entry ();
+rfc1524_entry *rfc1524_new_entry (void);
 void rfc1524_free_entry (rfc1524_entry **);
 int rfc1524_expand_command (BODY *, char *, char *, char *, int);
 int rfc1524_expand_filename (char *, char *, char *, size_t);
 int rfc1524_mailcap_lookup (BODY *, char *, rfc1524_entry *, int);
-void mutt_adv_mktemp (char *);
+void mutt_adv_mktemp (char *, size_t);
 int mutt_rename_file (char *, char *);
 
 #endif /* _RFC1524_H */
index 733a8d25eb889d7d4ad1d9e7ce5dbf70513a7054..25ba7914548f684a05f67292c09d20a21697d7a2 100644 (file)
--- a/rfc2047.c
+++ b/rfc2047.c
@@ -35,7 +35,7 @@ static void q_encode_string (char *d, size_t dlen, const unsigned char *s)
   char *wptr = d;
 
   snprintf (charset, sizeof (charset), "=?%s?Q?",
-           strcasecmp ("us-ascii", charset) == 0 ? "unknown-8bit" : Charset);
+           strcasecmp ("us-ascii", NONULL(Charset)) == 0 ? "unknown-8bit" : NONULL(Charset));
   cslen = strlen (charset);
 
   strcpy (wptr, charset);
@@ -110,7 +110,7 @@ static void b_encode_string (char *d, size_t dlen, const unsigned char *s)
   int cslen;
   int wordlen;
 
-  snprintf (charset, sizeof (charset), "=?%s?B?", Charset);
+  snprintf (charset, sizeof (charset), "=?%s?B?", NONULL(Charset));
   cslen = strlen (charset);
   strcpy (wptr, charset);
   wptr += cslen;
@@ -176,7 +176,7 @@ void rfc2047_encode_string (char *d, size_t dlen, const unsigned char *s)
   {
     if (*p & 0x80)
       count++;
-    else if (*p == '=' && *p == '?')
+    else if (*p == '=' && *(p+1) == '?')
     {
       count += 2;
       p++;
@@ -188,8 +188,8 @@ void rfc2047_encode_string (char *d, size_t dlen, const unsigned char *s)
     return;
   }
 
-  if (strcasecmp("us-ascii", Charset) == 0 ||
-      strncasecmp("iso-8859", Charset, 8) == 0)
+  if (strcasecmp("us-ascii", NONULL(Charset)) == 0 ||
+      strncasecmp("iso-8859", NONULL(Charset), 8) == 0)
     encoder = q_encode_string;
   else
   {
@@ -251,7 +251,7 @@ static int rfc2047_decode_word (char *d, const char *s, size_t len)
     switch (count)
     {
       case 2:
-       if (strcasecmp (pp, Charset) != 0)
+       if (strcasecmp (pp, NONULL(Charset)) != 0)
          filter = 1;
        break;
       case 3:
@@ -291,14 +291,14 @@ static int rfc2047_decode_word (char *d, const char *s, size_t len)
        {
          while (*pp && len > 0)
          {
-           c1 = Index_64[(int) pp[0]];
-           c2 = Index_64[(int) pp[1]];
+           c1 = base64val(pp[0]);
+           c2 = base64val(pp[1]);
            *pd++ = (c1 << 2) | ((c2 >> 4) & 0x3);
            if (--len == 0) break;
            
            if (pp[2] == '=') break;
 
-           c3 = Index_64[(int) pp[2]];
+           c3 = base64val(pp[2]);
            *pd++ = ((c2 & 0xf) << 4) | ((c3 >> 2) & 0xf);
            if (--len == 0)
              break;
@@ -306,7 +306,7 @@ static int rfc2047_decode_word (char *d, const char *s, size_t len)
            if (pp[3] == '=')
              break;
 
-           c4 = Index_64[(int) pp[3]];   
+           c4 = base64val(pp[3]);
            *pd++ = ((c3 & 0x3) << 6) | c4;
            if (--len == 0)
              break;
@@ -325,7 +325,7 @@ static int rfc2047_decode_word (char *d, const char *s, size_t len)
     pd = d;
     while (*pd)
     {
-      if (!IsPrint ((unsigned char) *pd))
+      if (!IsPrint (*pd))
        *pd = '?';
       pd++;
     }
index 487bea10c7101ea2f7ca870dc13b944d02b41fe6..2c99048624e14abcf89b232c5cbce98bf30b189b 100644 (file)
--- a/rfc822.c
+++ b/rfc822.c
@@ -198,30 +198,28 @@ parse_mailboxdomain (const char *s, const char *nonspecial,
 
 static const char *
 parse_address (const char *s,
+               char *token, size_t *tokenlen, size_t tokenmax,
               char *comment, size_t *commentlen, size_t commentmax,
               ADDRESS *addr)
 {
-  char token[128];
-  size_t tokenlen = 0;
-
   s = parse_mailboxdomain (s, ".\"(\\",
-                          token, &tokenlen, sizeof (token) - 1,
+                          token, tokenlen, tokenmax,
                           comment, commentlen, commentmax);
   if (!s)
     return NULL;
 
   if (*s == '@')
   {
-    if (tokenlen < sizeof (token) - 1)
-      token[tokenlen++] = '@';
+    if (*tokenlen < tokenmax)
+      token[(*tokenlen)++] = '@';
     s = parse_mailboxdomain (s + 1, ".([]\\",
-                            token, &tokenlen, sizeof (token) - 1,
+                            token, tokenlen, tokenmax,
                             comment, commentlen, commentmax);
     if (!s)
       return NULL;
   }
 
-  token[tokenlen] = 0;
+  token[*tokenlen] = 0;
   addr->mailbox = safe_strdup (token);
 
   if (*commentlen && !addr->personal)
@@ -238,27 +236,34 @@ parse_route_addr (const char *s,
                  char *comment, size_t *commentlen, size_t commentmax,
                  ADDRESS *addr)
 {
+  char token[STRING];
+  size_t tokenlen = 0;
+
   SKIPWS (s);
 
   /* find the end of the route */
   if (*s == '@')
   {
-    char token[128];
-    size_t tokenlen = 0;
-
     while (s && *s == '@')
-      s = parse_mailboxdomain (s + 1, ".[](\\", token,
+    {
+      if (tokenlen < sizeof (token) - 1)
+       token[tokenlen++] = '@';
+      s = parse_mailboxdomain (s + 1, ".\\[](", token,
                               &tokenlen, sizeof (token) - 1,
                               comment, commentlen, commentmax);
+    }
     if (!s || *s != ':')
     {
       RFC822Error = ERR_BAD_ROUTE;
       return NULL; /* invalid route */
     }
+
+    if (tokenlen < sizeof (token) - 1)
+      token[tokenlen++] = ':';
     s++;
   }
 
-  if ((s = parse_address (s, comment, commentlen, commentmax, addr)) == NULL)
+  if ((s = parse_address (s, token, &tokenlen, sizeof (token) - 1, comment, commentlen, commentmax, addr)) == NULL)
     return NULL;
 
   if (*s != '>' || !addr->mailbox)
@@ -276,7 +281,10 @@ parse_addr_spec (const char *s,
                 char *comment, size_t *commentlen, size_t commentmax,
                 ADDRESS *addr)
 {
-  s = parse_address (s, comment, commentlen, commentmax, addr);
+  char token[STRING];
+  size_t tokenlen = 0;
+
+  s = parse_address (s, token, &tokenlen, sizeof (token) - 1, comment, commentlen, commentmax, addr);
   if (s && *s && *s != ',' && *s != ';')
   {
     RFC822Error = ERR_BAD_ADDR_SPEC;
@@ -304,7 +312,7 @@ add_addrspec (ADDRESS **top, ADDRESS **last, const char *phrase,
 ADDRESS *rfc822_parse_adrlist (ADDRESS *top, const char *s)
 {
   const char *begin, *ps;
-  char comment[128], phrase[128];
+  char comment[STRING], phrase[STRING];
   size_t phraselen = 0, commentlen = 0;
   ADDRESS *cur, *last = NULL;
   
@@ -413,7 +421,7 @@ ADDRESS *rfc822_parse_adrlist (ADDRESS *top, const char *s)
       if (phraselen)
       {
        if (cur->personal)
-         free (cur->personal);
+         FREE (&cur->personal);
        /* if we get something like "Michael R. Elkins" remove the quotes */
        rfc822_dequote_comment (phrase);
        cur->personal = safe_strdup (phrase);
@@ -475,10 +483,9 @@ void rfc822_qualify (ADDRESS *addr, const char *host)
   for (; addr; addr = addr->next)
     if (!addr->group && addr->mailbox && strchr (addr->mailbox, '@') == NULL)
     {
-      if (!(p = malloc (strlen (addr->mailbox) + strlen (host) + 2)))
-       return;
+      p = safe_malloc (strlen (addr->mailbox) + strlen (host) + 2);
       sprintf (p, "%s@%s", addr->mailbox, host);
-      free (addr->mailbox);
+      safe_free ((void **) &addr->mailbox);
       addr->mailbox = p;
     }
 }
@@ -492,7 +499,7 @@ rfc822_cat (char *buf, size_t buflen, const char *value, const char *specials)
     size_t tmplen = sizeof (tmp) - 3;
 
     *pc++ = '"';
-    for (; *value && tmplen; value++)
+    for (; *value && tmplen > 1; value++)
     {
       if (*value == '\\' || *value == '"')
       {
@@ -583,7 +590,10 @@ void rfc822_write_address_single (char *buf, size_t buflen, ADDRESS *addr)
       goto done;
     *pbuf++ = ' ';
     buflen--;
+  }
 
+  if (addr->personal || (addr->mailbox && *addr->mailbox == '@'))
+  {
     if (!buflen)
       goto done;
     *pbuf++ = '<';
@@ -599,7 +609,7 @@ void rfc822_write_address_single (char *buf, size_t buflen, ADDRESS *addr)
     pbuf += len;
     buflen -= len;
 
-    if (addr->personal)
+    if (addr->personal || (addr->mailbox && *addr->mailbox == '@'))
     {
       if (!buflen)
        goto done;
@@ -668,7 +678,10 @@ void rfc822_write_address (char *buf, size_t buflen, ADDRESS *addr)
     len = strlen (pbuf);
     pbuf += len;
     buflen -= len;
-    if (addr->next && !addr->group)
+
+    /* if there is another address, and its not a group mailbox name or
+       group terminator, add a comma to separate the addresses */
+    if (addr->next && addr->next->mailbox && !addr->group)
     {
       if (!buflen)
        goto done;
@@ -745,12 +758,7 @@ int main (int argc, char **argv)
 {
   ADDRESS *list;
   char buf[256];
-  char *str = "aaaaaaaaaaaaaa <bbbbbbbbbbbbbbbb>, ccccccc <dddddddddddddddd>,\n\
-          eeeeeeeeee <ffffffffffffffff>, ggggggggggg <hhhhhhhhhhhhhhhhhhh>,\n\
-                 iiiiiiiiiiiiiiii <jjjjjjjjjjjjjjjjjjjj>,\n\
-                         kkkkkkkkkkkkkk <lllllllllllllllll>,\n\
-                                 mmmmmmmmmmmmm <nnnnnnnnnnnnnnnnnn>, ooooooooooo <pppppppppppppp>,\n\
-                                         qqqqqqqqqqqqq <rrrrrrrrrrrrrrrr>\n";
+  char *str = "michael, Michael Elkins <me@cs.hmc.edu>, testing a really complex address: this example <@contains.a.source.route@with.multiple.hosts:address@example.com>;, lothar@of.the.hillpeople (lothar)";
   
   list = rfc822_parse_adrlist (NULL, str);
   buf[0] = 0;
index f0bff294355030232449850e940738670932f5c3..8bce3bbe9444f7b0ddaa71b0dee750bd8268767d 100644 (file)
@@ -288,6 +288,7 @@ mailboxes ! +mutt-dev +mutt-users +open-pgp +wmaker +hurricane +vim +ietf \
 #      hdr_order <hdr1> [ <hdr2> ... ]
 #
 
+unhdr_order *                          # forget the previous settings
 hdr_order date from subject to cc
 
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/send.c b/send.c
index 44e80eed661d65a8116c7b8e3738ef4446efdc6f..91dbf2c45fdbf248a4b018b3a15b7666143f8408 100644 (file)
--- a/send.c
+++ b/send.c
@@ -44,7 +44,7 @@ extern char RFC822Specials[];
 
 
 
-static void append_signature (ENVELOPE *env, FILE *f)
+static void append_signature (FILE *f)
 {
   FILE *tmpfp;
   pid_t thepid;
@@ -323,13 +323,10 @@ static int include_forward (CONTEXT *ctx, HEADER *cur, FILE *out)
 
 
 #ifdef _PGPPATH
-  if (cur->pgp)
+  if ((cur->pgp & PGPENCRYPT) && option (OPTFORWDECODE))
   {
-    if (cur->pgp & PGPENCRYPT)
-    {
-      /* make sure we have the user's passphrase before proceeding... */
-      pgp_valid_passphrase ();
-    }
+    /* make sure we have the user's passphrase before proceeding... */
+    pgp_valid_passphrase ();
   }
 #endif /* _PGPPATH */
 
@@ -392,38 +389,6 @@ static int include_reply (CONTEXT *ctx, HEADER *cur, FILE *out)
   return 0;
 }
 
-static BODY *make_forward (CONTEXT *ctx, HEADER *hdr)
-{
-  char buffer[LONG_STRING];
-  BODY *body;
-  FILE *fpout;
-
-  mutt_mktemp (buffer);
-  if ((fpout = safe_fopen (buffer, "w")) == NULL)
-    return NULL;
-
-  body = mutt_new_body ();
-  body->type = TYPEMESSAGE;
-  body->subtype = safe_strdup ("rfc822");
-  body->filename = safe_strdup (buffer);
-  body->unlink = 1;
-  body->use_disp = 0;
-
-  /* this MUST come after setting ->filename because we reuse buffer[] */
-  strfcpy (buffer, "Forwarded message from ", sizeof (buffer));
-  rfc822_write_address (buffer + 23, sizeof (buffer) - 23, hdr->env->from);
-  body->description = safe_strdup (buffer);
-
-  mutt_parse_mime_message (ctx, hdr);
-  mutt_copy_message (fpout, ctx, hdr,
-                    option (OPTMIMEFORWDECODE) ? M_CM_DECODE : 0,
-                    CH_XMIT | (option (OPTMIMEFORWDECODE) ? (CH_MIME | CH_TXTPLAIN ) : 0));
-  
-  fclose (fpout);
-  mutt_update_encoding (body);
-  return (body);
-}
-
 static int default_to (ADDRESS **to, ENVELOPE *env, int group)
 {
   char prompt[STRING];
@@ -482,6 +447,23 @@ static int default_to (ADDRESS **to, ENVELOPE *env, int group)
   return (0);
 }
 
+static LIST *make_references(ENVELOPE *e)
+{
+  LIST *t, *l;
+  
+  l = mutt_copy_list(e->references);
+  
+  if(e->message_id)
+  {
+    t = mutt_new_list();
+    t->data = safe_strdup(e->message_id);
+    t->next = l;
+    l = t;
+  }
+  
+  return l;
+}
+
 static int fetch_recips (ENVELOPE *out, ENVELOPE *in, int flags)
 {
   ADDRESS *tmp;
@@ -598,22 +580,30 @@ envelope_defaults (ENVELOPE *env, CONTEXT *ctx, HEADER *cur, int flags)
       tmp->data = safe_strdup (buffer);
     }
 
-    env->references = mutt_copy_list (curenv->references);
-
-    if (curenv->message_id)
+    if(tag)
     {
-      LIST *t;
+      HEADER *h;
+      LIST **p;
 
-      t = mutt_new_list ();
-      t->data = safe_strdup (curenv->message_id);
-      t->next = env->references;
-      env->references = t;
+      env->references = NULL;
+      p = &env->references;
+      
+      for(i = 0; i < ctx->vcount; i++)
+      {
+       while(*p) p = &(*p)->next;
+       h = ctx->hdrs[ctx->v2r[i]];
+       if(h->tagged)
+         *p = make_references(h->env);
+      }
     }
+    else
+      env->references = make_references(curenv);
+
   }
   else if (flags & SENDFORWARD)
   {
     /* set the default subject for the message. */
-    mutt_make_string (buffer, sizeof (buffer), ForwFmt, ctx, cur);
+    mutt_make_string (buffer, sizeof (buffer), NONULL(ForwFmt), ctx, cur);
     env->subject = safe_strdup (buffer);
   }
 
@@ -669,7 +659,7 @@ generate_body (FILE *tempfp,        /* stream for outgoing message */
 
       if (cur)
       {
-       tmp = make_forward (ctx, cur);
+       tmp = mutt_make_message_attach (ctx, cur, 0);
        if (last)
          last->next = tmp;
        else
@@ -681,7 +671,7 @@ generate_body (FILE *tempfp,        /* stream for outgoing message */
        {
          if (ctx->hdrs[ctx->v2r[i]]->tagged)
          {
-           tmp = make_forward (ctx, ctx->hdrs[ctx->v2r[i]]);
+           tmp = mutt_make_message_attach (ctx, ctx->hdrs[ctx->v2r[i]], 0);
            if (last)
            {
              last->next = tmp;
@@ -794,16 +784,17 @@ static ADDRESS *set_reverse_name (ENVELOPE *env)
 static ADDRESS *mutt_default_from (void)
 {
   ADDRESS *adr = rfc822_new_address ();
-
+  const char *fqdn = mutt_fqdn(1);
+  
   /* don't set realname here, it will be set later */
 
   if (option (OPTUSEDOMAIN))
   {
-    adr->mailbox = safe_malloc (strlen (Username) + strlen (Fqdn) + 2);
-    sprintf (adr->mailbox, "%s@%s", Username, Fqdn);
+    adr->mailbox = safe_malloc (strlen (NONULL(Username)) + strlen (NONULL(fqdn)) + 2);
+    sprintf (adr->mailbox, "%s@%s", NONULL(Username), NONULL(fqdn));
   }
   else
-    adr->mailbox = safe_strdup (Username);
+    adr->mailbox = safe_strdup (NONULL(Username));
   return (adr);
 }
 
@@ -903,8 +894,8 @@ ci_send_message (int flags,         /* send mode */
 
     if (!tempfp)
     {
-      dprint(1,(debugfile, "newsend_message: can't create tempfile %s (errno=%d)\n", tempfile, errno));
-      mutt_perror (tempfile);
+      dprint(1,(debugfile, "newsend_message: can't create tempfile %s (errno=%d)\n", msg->content->filename, errno));
+      mutt_perror (msg->content->filename);
       goto cleanup;
     }
   }
@@ -992,8 +983,8 @@ ci_send_message (int flags,         /* send mode */
     if (generate_body (tempfp, msg, flags, ctx, cur) == -1)
       goto cleanup;
 
-    if (! (flags & (SENDMAILX | SENDKEY)) && strcmp (Editor, "builtin") != 0)
-      append_signature (msg->env, tempfp);
+    if (! (flags & (SENDMAILX | SENDKEY)) && Editor && strcmp (Editor, "builtin") != 0)
+      append_signature (tempfp);
   }
   /* wait until now to set the real name portion of our return address so
      that $realname can be set in a send-hook */
@@ -1043,8 +1034,8 @@ ci_send_message (int flags,               /* send mode */
     if(! (flags & SENDKEY))
     {
       if (mutt_needs_mailcap (msg->content))
-       mutt_edit_attachment (msg->content, 0);
-      else if (strcmp ("builtin", Editor) == 0)
+       mutt_edit_attachment (msg->content);
+      else if (!Editor || strcmp ("builtin", Editor) == 0)
        mutt_builtin_editor (msg->content->filename, msg, cur);
       else if (option (OPTEDITHDRS))
        mutt_edit_headers (Editor, msg->content->filename, msg, fcc, sizeof (fcc));
@@ -1105,7 +1096,7 @@ main_loop:
       /* postpone the message until later. */
       if (msg->content->next)
        msg->content = mutt_make_multipart (msg->content);
-      if (mutt_write_fcc (NONULL (Postponed), msg, (cur && (flags & SENDREPLY)) ? cur->env->message_id : NULL, 1) < 0)
+      if (!Postponed || mutt_write_fcc (Postponed, msg, (cur && (flags & SENDREPLY)) ? cur->env->message_id : NULL, 1) < 0)
       {
        msg->content = remove_multipart (msg->content);
        goto main_loop;
@@ -1175,7 +1166,7 @@ main_loop:
      * it by using an empty To: field.
      */
     msg->env->to = rfc822_new_address ();
-    msg->env->to->mailbox = safe_strdup (EmptyTo);
+    msg->env->to->mailbox = safe_strdup ("undisclosed-recipients:;");
     msg->env->to->group = 1;
     msg->env->to->next = rfc822_new_address ();
  
index b6eaac648462df51d1367afa1d7b706e22b139cb..52ec8fb2191b6bfc7ca94bec4764fedd15e6d2f5 100644 (file)
--- a/sendlib.c
+++ b/sendlib.c
 #include <signal.h>
 #include <sys/wait.h>
 #include <fcntl.h>
-#include <sysexits.h>
-
 
+#ifdef HAVE_SYSEXITS_H
+#include <sysexits.h>
+#endif
 
+static struct sysexits
+{
+  int v;
+  const char *str;
+} 
+sysexits_h[] = 
+{
+#ifdef EX_USAGE
+  { EX_USAGE, "The command was used incorrectly." },
+#endif
+#ifdef EX_DATAERR
+  { EX_DATAERR, "The input data was incorrect." },
+#endif
+#ifdef EX_NOINPUT
+  { EX_NOINPUT, "No input." },
+#endif
+#ifdef EX_NOUSER
+  { EX_NOUSER, "No such user." },
+#endif
+#ifdef EX_NOHOST
+  { EX_NOHOST, "Host not found." },
+#endif
+#ifdef EX_UNAVAILABLE
+  { EX_UNAVAILABLE, "Service unavailable." },
+#endif
+#ifdef EX_SOFTWARE
+  { EX_SOFTWARE, "Software error." },
+#endif
+#ifdef EX_OSERR
+  { EX_OSERR, "Operating system error." },
+#endif
+#ifdef EX_OSFILE
+  { EX_OSFILE, "System file is missing." },
+#endif
+#ifdef EX_CANTCREAT
+  { EX_CANTCREAT, "Can't create output." },
+#endif
+#ifdef EX_IOERR
+  { EX_IOERR, "I/O error." },
+#endif
+#ifdef EX_TEMPFAIL
+  { EX_TEMPFAIL, "Temporary failure." },
+#endif
+#ifdef EX_PROTOCOL
+  { EX_PROTOCOL, "Protocol error." },
+#endif
+#ifdef EX_NOPERM
+  { EX_NOPERM, "Permission denied." },
+#endif
+  { -1, NULL}
+};
+      
+    
 #ifdef _PGPPATH
 #include "pgp.h"
 #endif /* _PGPPATH */
@@ -111,11 +165,11 @@ static void encode_quoted (FILE * fin, FILE *fout, int istext)
     if (c == '\n' && istext)
     {
       /* Check to make sure there is no trailing space on this line. */
-      if (line[linelen-1] == ' ' || line[linelen-1] == '\t')
+      if (linelen > 0 && (line[linelen-1] == ' ' || line[linelen-1] == '\t'))
       {
         if (linelen < 74)
        {
-          sprintf (line+linelen-1, "=%2.2X", line[linelen-1]);
+          sprintf (line+linelen-1, "=%2.2X", (unsigned char) line[linelen-1]);
           fputs (line, fout);
         }
         else
@@ -125,7 +179,7 @@ static void encode_quoted (FILE * fin, FILE *fout, int istext)
           line[linelen-1] = '=';
           line[linelen] = 0;
           fputs (line, fout);
-          fprintf (fout, "\n=%2.2X", savechar);
+          fprintf (fout, "\n=%2.2X", (unsigned char) savechar);
         }
       }
       else
@@ -149,7 +203,7 @@ static void encode_quoted (FILE * fin, FILE *fout, int istext)
         fputc ('\n', fout);
         linelen = 0;
       }
-      sprintf (line+linelen,"=%2.2X", c);
+      sprintf (line+linelen,"=%2.2X", (unsigned char) c);
       linelen += 3;
     }
     else
@@ -168,7 +222,7 @@ static void encode_quoted (FILE * fin, FILE *fout, int istext)
     {
       /* take care of trailing whitespace */
       if (linelen < 74)
-        sprintf (line+linelen-1, "=%2.2X", line[linelen-1]);
+        sprintf (line+linelen-1, "=%2.2X", (unsigned char) line[linelen-1]);
       else
       {
         savechar = line[linelen-1];
@@ -176,7 +230,7 @@ static void encode_quoted (FILE * fin, FILE *fout, int istext)
         line[linelen] = 0;
         fputs (line, fout);
         fputc ('\n', fout);
-        sprintf (line, "=%2.2X", savechar);
+        sprintf (line, "=%2.2X", (unsigned char) savechar);
       }
     }
     else
@@ -311,7 +365,7 @@ int mutt_write_mime_header (BODY *a, FILE *f)
   int len;
   int tmplen;
   
-  fprintf (f, "Content-Type: %s/%s", TYPE (a->type), a->subtype);
+  fprintf (f, "Content-Type: %s/%s", TYPE (a), a->subtype);
 
   if (a->parameter)
   {
@@ -391,6 +445,7 @@ int mutt_write_mime_body (BODY *a, FILE *f)
     if (!(p = mutt_get_parameter ("boundary", a->parameter)))
     {
       dprint (1, (debugfile, "mutt_write_mime_body(): no boundary parameter found!\n"));
+      mutt_error ("No boundary parameter found! [report this error]");
       return (-1);
     }
     strfcpy (boundary, p, sizeof (boundary));
@@ -424,6 +479,7 @@ int mutt_write_mime_body (BODY *a, FILE *f)
   if ((fpin = fopen (a->filename, "r")) == NULL)
   {
     dprint(1,(debugfile, "write_mime_body: %s no longer exists!\n",a->filename));
+    mutt_error ("%s no longer exists!", a->filename);
     return -1;
   }
 
@@ -573,7 +629,7 @@ static int lookup_mime_type (char *d, const char *s)
     switch (count)
     {
       case 0:
-       snprintf (buf, sizeof (buf), "%s/.mime.types", Homedir);
+       snprintf (buf, sizeof (buf), "%s/.mime.types", NONULL(Homedir));
        break;
       case 1:
        strfcpy (buf, SHAREDIR"/mime.types", sizeof (buf));
@@ -653,7 +709,6 @@ static char *set_text_charset (CONTENT *info)
 void mutt_message_to_7bit (BODY *a, FILE *fp)
 {
   char temp[_POSIX_PATH_MAX];
-  size_t linelen = 0;
   char *line = NULL;
   FILE *fpin = NULL;
   FILE *fpout = NULL;
@@ -699,7 +754,6 @@ void mutt_message_to_7bit (BODY *a, FILE *fp)
   
  cleanup:
   safe_free ((void **) &line);
-  linelen = 0;
 
   if (fpin && !fp)
     fclose (fpin);
@@ -809,6 +863,11 @@ static void mutt_set_encoding (BODY *b, CONTENT *info)
     b->encoding = ENC7BIT;
 }
 
+void mutt_stamp_attachment(BODY *a)
+{
+  a->stamp = time(NULL);
+}
+
 /* Assumes called from send mode where BODY->filename points to actual file */
 void mutt_update_encoding (BODY *a)
 {
@@ -818,7 +877,8 @@ void mutt_update_encoding (BODY *a)
     return;
 
   mutt_set_encoding (a, info);
-
+  mutt_stamp_attachment(a);
+  
   if (a->type == TYPETEXT)
   {
     /* make sure the charset is valid */
@@ -849,7 +909,55 @@ void mutt_update_encoding (BODY *a)
   safe_free ((void **) &info);
 }
 
-BODY *mutt_make_attach (const char *path)
+BODY *mutt_make_message_attach (CONTEXT *ctx, HEADER *hdr, int attach_msg)
+{
+  char buffer[LONG_STRING];
+  BODY *body;
+  FILE *fp;
+
+  mutt_mktemp (buffer);
+  if ((fp = safe_fopen (buffer, "w+")) == NULL)
+    return NULL;
+
+  body = mutt_new_body ();
+  body->type = TYPEMESSAGE;
+  body->subtype = safe_strdup ("rfc822");
+  body->filename = safe_strdup (buffer);
+  body->unlink = 1;
+  body->use_disp = 0;
+
+#if 0
+  /* this MUST come after setting ->filename because we reuse buffer[] */
+  strfcpy (buffer, "Forwarded message from ", sizeof (buffer));
+  rfc822_write_address (buffer + 23, sizeof (buffer) - 23, hdr->env->from);
+  body->description = safe_strdup (buffer);
+#endif
+
+  mutt_parse_mime_message (ctx, hdr);
+
+  /* If we are attaching a message, ignore OPTMIMEFORWDECODE */
+  mutt_copy_message (fp, ctx, hdr, 
+                    (!attach_msg && option (OPTMIMEFORWDECODE)) ? M_CM_DECODE : 0, 
+                    CH_XMIT | ((!attach_msg && option (OPTMIMEFORWDECODE)) ? (CH_MIME | CH_TXTPLAIN ) : 0));
+  
+  fflush(fp);
+  rewind(fp);
+
+  body->hdr = mutt_new_header();
+  body->hdr->offset = 0;
+  body->hdr->env = mutt_read_rfc822_header(fp, body->hdr);
+#ifdef _PGPPATH
+  body->hdr->pgp = hdr->pgp;
+#endif
+  mutt_update_encoding (body);
+  body->parts = body->hdr->content;
+
+  fclose(fp);
+  
+  return (body);
+}
+
+BODY *mutt_make_file_attach (const char *path)
 {
   BODY *att;
   CONTENT *info;
@@ -893,8 +1001,7 @@ BODY *mutt_make_attach (const char *path)
   } 
 
   mutt_set_encoding (att, info);
-
-
+  mutt_stamp_attachment(att);
 
 #ifdef _PGPPATH
   /*
@@ -1055,11 +1162,7 @@ int mutt_write_rfc822_header (FILE *fp, ENVELOPE *env, BODY *attach, int mode)
   LIST *tmp = env->userhdrs;
 
   if (mode == 0)
-  {
-    if (env->message_id)
-      fprintf (fp, "Message-ID: %s\n", env->message_id);
     fputs (mutt_make_date (buffer), fp);
-  }
 
   /* OPTUSEFROM is not consulted here so that we can still write a From:
    * field if the user sets it with the `my_hdr' command
@@ -1089,8 +1192,11 @@ int mutt_write_rfc822_header (FILE *fp, ENVELOPE *env, BODY *attach, int mode)
 
   if (env->bcc)
   {
-    fputs ("Bcc: ", fp);
-    mutt_write_address_list (env->bcc, fp, 5);
+    if(mode != 0 || option(OPTWRITEBCC))
+    {
+      fputs ("Bcc: ", fp);
+      mutt_write_address_list (env->bcc, fp, 5);
+    }
   }
   else if (mode > 0)
     fputs ("Bcc: \n", fp);
@@ -1100,6 +1206,10 @@ int mutt_write_rfc822_header (FILE *fp, ENVELOPE *env, BODY *attach, int mode)
   else if (mode == 1)
     fputs ("Subject: \n", fp);
 
+  /* save message id if the user has set it */
+  if (env->message_id)
+    fprintf (fp, "Message-ID: %s\n", env->message_id);
+
   if (env->reply_to)
   {
     fputs ("Reply-To: ", fp);
@@ -1186,18 +1296,46 @@ static void encode_descriptions (BODY *b)
   }
 }
 
+const char *mutt_fqdn(short may_hide_host)
+{
+  char *p = NULL, *q;
+  
+  if(Fqdn && Fqdn[0] != '@')
+  {
+    p = Fqdn;
+    
+    if(may_hide_host && option(OPTHIDDENHOST))
+    {
+      if((p = strchr(Fqdn, '.')))
+       p++;
+
+      /* sanity check: don't hide the host if
+       * the fqdn is something like detebe.org.
+       */
+      
+      if(!p || !(q = strchr(p, '.')))
+       p = Fqdn;
+    }
+  }
+
+  return p;
+}
+
 char *mutt_gen_msgid (void)
 {
   char buf[SHORT_STRING];
   time_t now;
   struct tm *tm;
+  const char *fqdn;
 
   now = time (NULL);
   tm = localtime (&now);
+  if(!(fqdn = mutt_fqdn(0)))
+    fqdn = NONULL(Hostname);
+
   snprintf (buf, sizeof (buf), "<%d%02d%02d%02d%02d%02d.%c%d@%s>",
            tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour,
-           tm->tm_min, tm->tm_sec, MsgIdPfx, getpid (),
-           Fqdn[0] != '@' ? Fqdn : Hostname);
+           tm->tm_min, tm->tm_sec, MsgIdPfx, getpid (), fqdn);
   MsgIdPfx = (MsgIdPfx == 'Z') ? 'A' : MsgIdPfx + 1;
   return (safe_strdup (buf));
 }
@@ -1352,9 +1490,13 @@ send_msg (const char *path, char **args, const char *msg, char **tempfile)
   {
 #ifdef DEBUG
     if (WIFEXITED (st))
+    {
       dprint (1, (debugfile, "send_msg(): child exited %d\n", WEXITSTATUS (st)));
+    }
     else
+    {
       dprint (1, (debugfile, "send_msg(): child did not exit\n"));
+    }
 #endif /* DEBUG */
     st = WIFEXITED (st) ? WEXITSTATUS (st) : -1; /* return child status */
   }
@@ -1390,6 +1532,21 @@ add_option (char **args, size_t *argslen, size_t *argsmax, char *s)
   return (args);
 }
 
+static const char *
+strsysexit(int e)
+{
+  int i;
+  
+  for(i = 0; sysexits_h[i].str; i++)
+  {
+    if(e == sysexits_h[i].v)
+      break;
+  }
+  
+  return sysexits_h[i].str;
+}
+
+
 static int
 invoke_sendmail (ADDRESS *to, ADDRESS *cc, ADDRESS *bcc, /* recips */
                 const char *msg, /* file containing message */
@@ -1434,6 +1591,7 @@ invoke_sendmail (ADDRESS *to, ADDRESS *cc, ADDRESS *bcc, /* recips */
     args = add_option (args, &argslen, &argsmax, "-R");
     args = add_option (args, &argslen, &argsmax, DsnReturn);
   }
+  args = add_option (args, &argslen, &argsmax, "--");
   args = add_args (args, &argslen, &argsmax, to);
   args = add_args (args, &argslen, &argsmax, cc);
   args = add_args (args, &argslen, &argsmax, bcc);
@@ -1447,7 +1605,7 @@ invoke_sendmail (ADDRESS *to, ADDRESS *cc, ADDRESS *bcc, /* recips */
     endwin ();
   if ((i = send_msg (path, args, msg, &childout)) != (EX_OK & 0xff))
   {
-    char *e = strerror (errno);
+    const char *e = strsysexit(i);
 
     fprintf (stderr, "Error sending message, child exited %d (%s).\n", i, NONULL (e));
     if (childout)
@@ -1501,7 +1659,7 @@ char *mutt_quote_string (const char *s)
   size_t rlen;
 
   rlen = strlen (s) + 3;
-  pr = r = malloc (rlen);
+  pr = r = (char *) safe_malloc (rlen);
   *pr++ = '"';
   while (*s)
   {
@@ -1551,7 +1709,13 @@ int mutt_send_message (HEADER *msg, const char *fcc)
   mutt_write_rfc822_header (tempfp, msg->env, msg->content, 0);
   fputc ('\n', tempfp); /* tie off the header. */
 
-  mutt_write_mime_body (msg->content, tempfp);
+  if ((mutt_write_mime_body (msg->content, tempfp) == -1))
+  {
+    fclose(tempfp);
+    unlink (tempfile);
+    return (-1);
+  }
+  
   if (fclose (tempfp) != 0)
   {
     mutt_perror (tempfile);
@@ -1601,11 +1765,13 @@ void mutt_bounce_message (HEADER *h, ADDRESS *to)
     mutt_mktemp (tempfile);
     if ((f = safe_fopen (tempfile, "w")) != NULL)
     {
+      const char *fqdn;
+
       fseek (msg->fp, h->offset, 0);
       mutt_copy_header (msg->fp, h, f, CH_XMIT | CH_NONEWLINE, NULL);
-      fprintf (f, "Resent-From: %s", Username);
-      if (Fqdn[0] != '@')
-       fprintf (f, "@%s", Fqdn);
+      fprintf (f, "Resent-From: %s", NONULL(Username));
+      if((fqdn = mutt_fqdn(1)))
+       fprintf (f, "@%s", fqdn);
       fprintf (f, "\nResent-%s", mutt_make_date (date));
       fputs ("Resent-To: ", f);
       mutt_write_address_list (to, f, 11);
@@ -1688,7 +1854,7 @@ int mutt_write_fcc (const char *path, HEADER *hdr, const char *msgid, int post)
     }
   }
 
-  hdr->read = 1; /* make sure to put it in the `cur' directory (maildir) */
+  hdr->read = !post; /* make sure to put it in the `cur' directory (maildir) */
   if ((msg = mx_open_new_message (&f, hdr, M_ADD_FROM)) == NULL)
   {
     mx_close_mailbox (&f);
index c03aa878d532f1897074111364265956a472c49b..4716ee291392f30a91392400715ad07b0eaff3bd 100644 (file)
@@ -44,7 +44,8 @@
 
 #if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF)
 
-#include <ctype.h>
+#include <string.h>
+# include <ctype.h>
 #include <sys/types.h>
 
 /* Define this as a fall through, HAVE_STDARG_H is probably already set */
@@ -178,7 +179,7 @@ static void dopr (char *buffer, size_t maxlen, const char *format, va_list args)
       }
       break;
     case DP_S_MIN:
-      if (isdigit(ch)) 
+      if (isdigit((unsigned char)ch)) 
       {
        min = 10*min + char_to_int (ch);
        ch = *format++;
@@ -202,7 +203,7 @@ static void dopr (char *buffer, size_t maxlen, const char *format, va_list args)
        state = DP_S_MOD;
       break;
     case DP_S_MAX:
-      if (isdigit(ch)) 
+      if (isdigit((unsigned char)ch)) 
       {
        if (max < 0)
          max = 0;
diff --git a/socket.c b/socket.c
new file mode 100644 (file)
index 0000000..63a4f46
--- /dev/null
+++ b/socket.c
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 1998 Michael R. Elkins <me@cs.hmc.edu>
+ * 
+ *     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.
+ */ 
+
+#include "mutt.h"
+#include "globals.h"
+#include "mutt_socket.h"
+
+#include <unistd.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+/* support for multiple socket connections */
+
+static CONNECTION *Connections = NULL;
+static int NumConnections = 0;
+
+/* simple read buffering to speed things up. */
+int mutt_socket_readchar (CONNECTION *conn, char *c)
+{
+  if (conn->bufpos >= conn->available)
+  {
+    conn->available = read (conn->fd, conn->inbuf, LONG_STRING);
+    dprint (1, (debugfile, "mutt_socket_readchar(): buffered %d chars\n", conn->available));
+    conn->bufpos = 0;
+    if (conn->available <= 0)
+      return conn->available; /* returns 0 for EOF or -1 for other error */
+  }
+  *c = conn->inbuf[conn->bufpos];
+  conn->bufpos++;
+  return 1;
+}
+
+int mutt_socket_read_line (char *buf, size_t buflen, CONNECTION *conn)
+{
+  char ch;
+  int i;
+
+  for (i = 0; i < buflen; i++)
+  {
+    if (mutt_socket_readchar (conn, &ch) != 1)
+      return (-1);
+    if (ch == '\n')
+      break;
+    buf[i] = ch;
+  }
+  buf[i-1] = 0;
+  return (i + 1);
+}
+
+int mutt_socket_read_line_d (char *buf, size_t buflen, CONNECTION *conn)
+{
+  int r = mutt_socket_read_line (buf, buflen, conn);
+  dprint (1,(debugfile,"mutt_socket_read_line_d():%s\n", buf));
+  return r;
+}
+
+int mutt_socket_write (CONNECTION *conn, const char *buf)
+{
+  dprint (1,(debugfile,"mutt_socket_write():%s", buf));
+  return (write (conn->fd, buf, strlen (buf)));
+}
+
+CONNECTION *mutt_socket_select_connection (char *host, int port, int flags)
+{
+  int x;
+
+  if (flags != M_NEW_SOCKET)
+  {
+    for (x = 0; x < NumConnections; x++)
+    {
+      if (!strcmp (host, Connections[x].server) && 
+         (port == Connections[x].port))
+       return &Connections[x];
+    }
+  }
+  if (NumConnections == 0)
+  {
+    NumConnections = 1;
+    Connections = (CONNECTION *) safe_malloc (sizeof (CONNECTION));
+  }
+  else
+  {
+    NumConnections++;
+    safe_realloc ((void *)&Connections, sizeof (CONNECTION) * NumConnections);
+  }
+  Connections[NumConnections - 1].bufpos = 0;
+  Connections[NumConnections - 1].available = 0;
+  Connections[NumConnections - 1].uses = 0;
+  Connections[NumConnections - 1].server = safe_strdup (host);
+  Connections[NumConnections - 1].port = port;
+
+  return &Connections[NumConnections - 1];
+}
+
diff --git a/sort.h b/sort.h
index 755002497682ab8dc0fd47e205f7e313316110cc..7e7c41e24479a94724aabc7e728009ae4071af55 100644 (file)
--- a/sort.h
+++ b/sort.h
@@ -16,8 +16,6 @@
  *     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */ 
 
-#include "mapping.h"
-
 #define SORT_DATE      1   /* the date the mail was sent. */
 #define SORT_SIZE      2
 #define SORT_SUBJECT   3
index dd61d757ef35f0426857b10bb82cd89b1a27e274..7cf8680747eb81b0d85cb07bf8e16bd12fc02822 100644 (file)
--- a/status.c
+++ b/status.c
@@ -20,6 +20,7 @@
 #include "mutt_menu.h"
 #include "mutt_curses.h"
 #include "sort.h"
+#include "mapping.h"
 
 #include <string.h>
 #include <ctype.h>
@@ -86,7 +87,7 @@ status_format_str (char *buf, size_t buflen, char op, const char *src,
 
     case 'h':
       snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
-      snprintf (buf, buflen, fmt, Hostname);
+      snprintf (buf, buflen, fmt, NONULL(Hostname));
       break;
 
     case 'f':
index 2c2570a12c1e54087358833c7a8b2f53c47daf6e..8336e91d8f672b5c04b33d21f1bf1aa18205c965 100644 (file)
--- a/thread.c
+++ b/thread.c
@@ -585,8 +585,44 @@ void mutt_sort_threads (CONTEXT *ctx, int init)
   mutt_linearize_tree (ctx, 1);
 }
 
+static HEADER *find_virtual (HEADER *cur)
+{
+  HEADER *top;
+
+  if (cur->virtual >= 0)
+      return (cur);
+
+  top = cur;
+  if ((cur = cur->child) == NULL)
+    return (NULL);
+
+  FOREVER
+  {
+    if (cur->virtual >= 0)
+      return (cur);
+
+    if (cur->child)
+      cur = cur->child;
+    else if (cur->next)
+      cur = cur->next;
+    else
+    {
+      while (!cur->next)
+      {
+       cur = cur->parent;
+       if (cur == top)
+         return (NULL);
+      }
+      cur = cur->next;
+    }
+    /* not reached */
+  }
+}
+
 int _mutt_aside_thread (HEADER *hdr, short dir, short subthreads)
 {
+  HEADER *tmp;
+
   if ((Sort & SORT_MASK) != SORT_THREADS)
   {
     mutt_error ("Threading is not enabled.");
@@ -600,7 +636,7 @@ int _mutt_aside_thread (HEADER *hdr, short dir, short subthreads)
   }
   else
   {
-    if (dir)
+    if ((dir != 0) ^ ((Sort & SORT_REVERSE) != 0))
     {
       while (!hdr->next && hdr->parent)
        hdr = hdr->parent;
@@ -611,15 +647,27 @@ int _mutt_aside_thread (HEADER *hdr, short dir, short subthreads)
        hdr = hdr->parent;
     }
   }
-  
-  hdr = (dir != 0) ^ ((Sort & SORT_REVERSE) != 0) ? hdr->next : hdr->prev;
-  if (hdr)
+
+  if ((dir != 0) ^ ((Sort & SORT_REVERSE) != 0))
   {
-    if (Sort & SORT_REVERSE)
-      return (hdr->next ? hdr->next->virtual + 1 : 0);
-    else
-      return (hdr->virtual);
+    do
+    { 
+       hdr = hdr->next;
+       if (!hdr)
+         return (-1);
+       tmp = find_virtual (hdr);
+    } while (!tmp);
   }
   else
-    return (-1);
+  {
+    do
+    { 
+       hdr = hdr->prev;
+       if (!hdr)
+         return (-1);
+       tmp = find_virtual (hdr);
+    } while (!tmp);
+  }
+
+  return (tmp->virtual);
 }