;;; mm-decode.el --- Functions for decoding MIME things
-;; Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+
+;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+;; 2005, 2006 Free Software Foundation, Inc.
;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
;; MORIOKA Tomohiko <morioka@jaist.ac.jp>
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING. If not, write to the
-;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
;;; Commentary:
(require 'term))
(eval-and-compile
- (autoload 'executable-find "executable")
(autoload 'mm-inline-partial "mm-partial")
(autoload 'mm-inline-external-body "mm-extern")
+ (autoload 'mm-extern-cache-contents "mm-extern")
(autoload 'mm-insert-inline "mm-view"))
+(defvar gnus-current-window-configuration)
+
(add-hook 'gnus-exit-gnus-hook 'mm-destroy-postponed-undisplay-list)
(defgroup mime-display ()
"Display of MIME in mail and news articles."
- :link '(custom-manual "(emacs-mime)Customization")
+ :link '(custom-manual "(emacs-mime)Display Customization")
:version "21.1"
:group 'mail
:group 'news
(defgroup mime-security ()
"MIME security in mail and news articles."
- :link '(custom-manual "(emacs-mime)Customization")
+ :link '(custom-manual "(emacs-mime)Display Customization")
:group 'mail
:group 'news
:group 'multimedia)
(defcustom mm-text-html-renderer
(cond ((locate-library "w3") 'w3)
- ((locate-library "w3m") 'w3m)
+ ((executable-find "w3m") (if (locate-library "w3m")
+ 'w3m
+ 'w3m-standalone))
((executable-find "links") 'links)
- ((executable-find "lynx") 'lynx))
+ ((executable-find "lynx") 'lynx)
+ (t 'html2text))
"Render of HTML contents.
It is one of defined renderer types, or a rendering function.
The defined renderer types are:
-`w3' : using Emacs/W3;
-`w3m' : using emacs-w3m;
-`links': using links;
-`lynx' : using lynx;
-`nil' : using external viewer."
- :type '(choice (symbol w3)
- (symbol w3m)
- (symbol links)
- (symbol lynx)
- (symbol nil)
+`w3' : use Emacs/W3;
+`w3m' : use emacs-w3m;
+`w3m-standalone': use w3m;
+`links': use links;
+`lynx' : use lynx;
+`html2text' : use html2text;
+nil : use external viewer."
+ :version "22.1"
+ :type '(choice (const w3)
+ (const w3m)
+ (const w3m-standalone)
+ (const links)
+ (const lynx)
+ (const html2text)
+ (const nil)
(function))
- :version "21.3"
:group 'mime-display)
(defvar mm-inline-text-html-renderer nil
It is suggested to customize `mm-text-html-renderer' instead.")
(defcustom mm-inline-text-html-with-images nil
- "If non-nil, Gnus will allow retrieving images in the HTML contents
-with <img> tags. It has no effect on Emacs/w3. For emacs-w3m, the
-value of the option `w3m-display-inline-images' will be bound with
-this value. In addition, the variable `w3m-safe-url-regexp' will be
-bound with the value nil if it is non-nil to make emacs-w3m show all
-images, however this behavior may be changed in the future."
+ "If non-nil, Gnus will allow retrieving images in HTML contents with
+the <img> tags. It has no effect on Emacs/w3. See also the
+documentation for the `mm-w3m-safe-url-regexp' variable."
+ :version "22.1"
:type 'boolean
:group 'mime-display)
+(defcustom mm-w3m-safe-url-regexp "\\`cid:"
+ "Regexp matching URLs which are considered to be safe.
+Some HTML mails might contain a nasty trick used by spammers, using
+the <img> tag which is far more evil than the [Click Here!] button.
+It is most likely intended to check whether the ominous spam mail has
+reached your eyes or not, in which case the spammer knows for sure
+that your email address is valid. It is done by embedding an
+identifier string into a URL that you might automatically retrieve
+when displaying the image. The default value is \"\\\\`cid:\" which only
+matches parts embedded to the Multipart/Related type MIME contents and
+Gnus will never connect to the spammer's site arbitrarily. You may
+set this variable to nil if you consider all urls to be safe."
+ :version "22.1"
+ :type '(choice (regexp :tag "Regexp")
+ (const :tag "All URLs are safe" nil))
+ :group 'mime-display)
+
(defcustom mm-inline-text-html-with-w3m-keymap t
"If non-nil, use emacs-w3m command keys in the article buffer."
+ :version "22.1"
:type 'boolean
:group 'mime-display)
+(defcustom mm-enable-external t
+ "Indicate whether external MIME handlers should be used.
+
+If t, all defined external MIME handlers are used. If nil, files are saved by
+`mailcap-save-binary-file'. If it is the symbol `ask', you are prompted
+before the external MIME handler is invoked."
+ :version "22.1"
+ :type '(choice (const :tag "Always" t)
+ (const :tag "Never" nil)
+ (const :tag "Ask" ask))
+ :group 'mime-display)
+
(defcustom mm-inline-media-tests
- '(("image/jpeg"
+ '(("image/p?jpeg"
mm-inline-image
(lambda (handle)
(mm-valid-and-fit-image-p 'jpeg handle)))
mm-inline-image
(lambda (handle)
(mm-valid-and-fit-image-p 'xpm handle)))
- ("image/x-pixmap"
+ ("image/x-xpixmap"
mm-inline-image
(lambda (handle)
(mm-valid-and-fit-image-p 'xpm handle)))
("text/richtext" mm-inline-text identity)
("text/x-patch" mm-display-patch-inline
(lambda (handle)
- (locate-library "diff-mode")))
+ ;; If the diff-mode.el package is installed, the function is
+ ;; autoloaded. Checking (locate-library "diff-mode") would be trying
+ ;; to cater to broken installations. OTOH checking the function
+ ;; makes it possible to install another package which provides an
+ ;; alternative implementation of diff-mode. --Stef
+ (fboundp 'diff-mode)))
("application/emacs-lisp" mm-display-elisp-inline identity)
("application/x-emacs-lisp" mm-display-elisp-inline identity)
+ ("text/dns" mm-display-dns-inline identity)
("text/html"
mm-inline-text-html
(lambda (handle)
;; Default to displaying as text
(".*" mm-inline-text mm-readable-p))
"Alist of media types/tests saying whether types can be displayed inline."
- :type '(repeat (list (string :tag "MIME type")
+ :type '(repeat (list (regexp :tag "MIME type")
(function :tag "Display function")
(function :tag "Display test")))
:group 'mime-display)
"application/x-emacs-lisp"
"application/pgp-signature" "application/x-pkcs7-signature"
"application/pkcs7-signature" "application/x-pkcs7-mime"
- "application/pkcs7-mime")
+ "application/pkcs7-mime"
+ ;; Mutt still uses this even though it has already been withdrawn.
+ "application/pgp")
"List of media types that are to be displayed inline.
See also `mm-inline-media-tests', which says how to display a media
type inline."
- :type '(repeat string)
+ :type '(repeat regexp)
:group 'mime-display)
(defcustom mm-keep-viewer-alive-types
"application/pdf" "application/x-dvi")
"List of media types for which the external viewer will not be killed
when selecting a different article."
- :type '(repeat string)
+ :version "22.1"
+ :type '(repeat regexp)
:group 'mime-display)
(defcustom mm-automatic-display
- '("text/plain" "text/enriched" "text/richtext" "text/html"
+ '("text/plain" "text/enriched" "text/richtext" "text/html" "text/x-verbatim"
"text/x-vcard" "image/.*" "message/delivery-status" "multipart/.*"
- "message/rfc822" "text/x-patch" "application/pgp-signature"
+ "message/rfc822" "text/x-patch" "text/dns" "application/pgp-signature"
"application/emacs-lisp" "application/x-emacs-lisp"
"application/x-pkcs7-signature"
"application/pkcs7-signature" "application/x-pkcs7-mime"
- "application/pkcs7-mime")
+ "application/pkcs7-mime"
+ ;; Mutt still uses this even though it has already been withdrawn.
+ "application/pgp")
"A list of MIME types to be displayed automatically."
- :type '(repeat string)
+ :type '(repeat regexp)
:group 'mime-display)
(defcustom mm-attachment-override-types '("text/x-vcard"
"application/pkcs7-signature"
"application/x-pkcs7-signature")
"Types to have \"attachment\" ignored if they can be displayed inline."
- :type '(repeat string)
+ :type '(repeat regexp)
:group 'mime-display)
(defcustom mm-inline-override-types nil
"Types to be treated as attachments even if they can be displayed inline."
- :type '(repeat string)
+ :type '(repeat regexp)
:group 'mime-display)
(defcustom mm-automatic-external-display nil
"List of MIME type regexps that will be displayed externally automatically."
- :type '(repeat string)
+ :type '(repeat regexp)
:group 'mime-display)
(defcustom mm-discouraged-alternatives nil
somewhat unwanted, then the value of this variable should be set
to:
- (\"text/html\" \"text/richtext\")"
- :type '(repeat string)
+ (\"text/html\" \"text/richtext\")
+
+Adding \"image/.*\" might also be useful. Spammers use it as the
+prefered part of multipart/alternative messages. See also
+`gnus-buttonized-mime-types', to which adding \"multipart/alternative\"
+enables you to choose manually one of two types those mails include."
+ :type '(repeat regexp) ;; See `mm-preferred-alternative-precedence'.
:group 'mime-display)
(defcustom mm-tmp-directory
- (cond ((fboundp 'temp-directory) (temp-directory))
- ((boundp 'temporary-file-directory) temporary-file-directory)
- ("/tmp/"))
+ (if (fboundp 'temp-directory)
+ (temp-directory)
+ (if (boundp 'temporary-file-directory)
+ temporary-file-directory
+ "/tmp/"))
"Where mm will store its temporary files."
:type 'directory
:group 'mime-display)
:type 'boolean
:group 'mime-display)
-(defvar mm-file-name-rewrite-functions nil
+(defvar mm-file-name-rewrite-functions
+ '(mm-file-name-delete-control mm-file-name-delete-gotchas)
"*List of functions used for rewriting file names of MIME parts.
Each function takes a file name as input and returns a file name.
Ready-made functions include
+`mm-file-name-delete-control'
+`mm-file-name-delete-gotchas'
`mm-file-name-delete-whitespace',
`mm-file-name-trim-whitespace',
`mm-file-name-collapse-whitespace',
`upcase-initials'.")
(defvar mm-path-name-rewrite-functions nil
- "*List of functions used for rewriting path names of MIME parts.
-This is used when viewing parts externally , and is meant for
-transforming the path name so that non-compliant programs can
-find the file where it's saved.
+ "*List of functions for rewriting the full file names of MIME parts.
+This is used when viewing parts externally, and is meant for
+transforming the absolute name so that non-compliant programs can find
+the file where it's saved.
Each function takes a file name as input and returns a file name.")
:type '(choice directory (const :tag "Default" nil))
:group 'mime-display)
+(defcustom mm-attachment-file-modes 384
+ "Set the mode bits of saved attachments to this integer."
+ :version "22.1"
+ :type 'integer
+ :group 'mime-display)
+
(defcustom mm-external-terminal-program "xterm"
"The program to start an external terminal."
+ :version "22.1"
:type 'string
:group 'mime-display)
;;; Internal variables.
-(defvar mm-dissection-list nil)
(defvar mm-last-shell-command "")
(defvar mm-content-id-alist nil)
(defvar mm-postponed-undisplay-list nil)
(defcustom mm-verify-option 'never
"Option of verifying signed parts.
`never', not verify; `always', always verify;
-`known', only verify known protocols. Otherwise, ask user."
+`known', only verify known protocols. Otherwise, ask user."
+ :version "22.1"
:type '(choice (item always)
(item never)
(item :tag "only known protocols" known)
(defcustom mm-decrypt-option nil
"Option of decrypting encrypted parts.
`never', not decrypt; `always', always decrypt;
-`known', only decrypt known protocols. Otherwise, ask user."
+`known', only decrypt known protocols. Otherwise, ask user."
+ :version "22.1"
:type '(choice (item always)
(item never)
(item :tag "only known protocols" known)
(defvar mm-viewer-completion-map
(let ((map (make-sparse-keymap 'mm-viewer-completion-map)))
(set-keymap-parent map minibuffer-local-completion-map)
+ ;; Should we bind other key to minibuffer-complete-word?
+ (define-key map " " 'self-insert-command)
map)
"Keymap for input viewer with completion.")
-;; Should we bind other key to minibuffer-complete-word?
-(define-key mm-viewer-completion-map " " 'self-insert-command)
-
(defvar mm-viewer-completion-map
(let ((map (make-sparse-keymap 'mm-viewer-completion-map)))
(set-keymap-parent map minibuffer-local-completion-map)
+ ;; Should we bind other key to minibuffer-complete-word?
+ (define-key map " " 'self-insert-command)
map)
"Keymap for input viewer with completion.")
-;; Should we bind other key to minibuffer-complete-word?
-(define-key mm-viewer-completion-map " " 'self-insert-command)
-
;;; The functions.
(defun mm-alist-to-plist (alist)
(throw 'found t))))))
(defun mm-handle-set-external-undisplayer (handle function)
- "Set the undisplayer for this handle; postpone undisplaying of viewers
-for types in mm-keep-viewer-alive-types."
+ "Set the undisplayer for HANDLE to FUNCTION.
+Postpone undisplaying of viewers for types in
+`mm-keep-viewer-alive-types'."
(if (mm-keep-viewer-alive-p handle)
(let ((new-handle (copy-sequence handle)))
(mm-handle-set-undisplayer new-handle function)
(message "Destroying external MIME viewers")
(mm-destroy-parts mm-postponed-undisplay-list)))
-(defun mm-dissect-buffer (&optional no-strict-mime loose-mime)
+(defun mm-dissect-buffer (&optional no-strict-mime loose-mime from)
"Dissect the current buffer and return a list of MIME handles."
(save-excursion
- (let (ct ctl type subtype cte cd description id result from)
+ (let (ct ctl type subtype cte cd description id result)
(save-restriction
(mail-narrow-to-head)
(when (or no-strict-mime
loose-mime
(mail-fetch-field "mime-version"))
(setq ct (mail-fetch-field "content-type")
- ctl (ignore-errors (mail-header-parse-content-type ct))
+ ctl (and ct (mail-header-parse-content-type ct))
cte (mail-fetch-field "content-transfer-encoding")
cd (mail-fetch-field "content-disposition")
description (mail-fetch-field "content-description")
- from (mail-fetch-field "from")
id (mail-fetch-field "content-id"))
+ (unless from
+ (setq from (mail-fetch-field "from")))
;; FIXME: In some circumstances, this code is running within
;; an unibyte macro. mail-extract-address-components
;; creates unibyte buffers. This `if', though not a perfect
;; solution, avoids most of them.
(if from
&nb