Update copyright year to 2014
[gnus] / lisp / mm-decode.el
index 598a722..17c8fb1 100644 (file)
@@ -1,46 +1,53 @@
 ;;; mm-decode.el --- Functions for decoding MIME things
 
-;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-;;   2005, 2006, 2007 Free Software Foundation, Inc.
+;; Copyright (C) 1998-2014 Free Software Foundation, Inc.
 
 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
 ;;     MORIOKA Tomohiko <morioka@jaist.ac.jp>
 ;; This file is part of GNU Emacs.
 
-;; GNU Emacs is free software; you can redistribute it and/or modify
+;; GNU Emacs 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, or (at your option)
-;; any later version.
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
 
 ;; GNU Emacs 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
+;; 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 GNU Emacs; see the file COPYING.  If not, write to the
-;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-;; Boston, MA 02110-1301, USA.
+;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
 
 ;;; Commentary:
 
 ;;; Code:
 
+;; For Emacs <22.2 and XEmacs.
+(eval-and-compile
+  (unless (fboundp 'declare-function) (defmacro declare-function (&rest r))))
+
 (require 'mail-parse)
-(require 'mailcap)
 (require 'mm-bodies)
-(eval-when-compile (require 'cl)
-                  (require 'term))
+(eval-when-compile (require 'cl))
 
-(eval-and-compile
-  (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"))
+(autoload 'gnus-map-function "gnus-util")
+(autoload 'gnus-replace-in-string "gnus-util")
+(autoload 'gnus-read-shell-command "gnus-util")
+
+(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")
+
+(autoload 'mm-archive-decoders "mm-archive")
+(autoload 'mm-archive-dissect-and-inline "mm-archive")
+(autoload 'mm-dissect-archive "mm-archive")
 
 (defvar gnus-current-window-configuration)
 
 (add-hook 'gnus-exit-gnus-hook 'mm-destroy-postponed-undisplay-list)
+(add-hook 'gnus-exit-gnus-hook 'mm-temp-files-delete)
 
 (defgroup mime-display ()
   "Display of MIME in mail and news articles."
   :group 'news
   :group 'multimedia)
 
+(defface mm-command-output
+  '((((class color)
+      (background dark))
+     (:foreground "ForestGreen"))
+    (((class color)
+      (background light))
+     (:foreground "red3"))
+    (t
+     (:italic t)))
+  "Face used for displaying output from commands."
+  :group 'mime-display)
+
 ;;; Convenience macros.
 
 (defmacro mm-handle-buffer (handle)
         ,disposition ,description ,cache ,id))
 
 (defcustom mm-text-html-renderer
-  (cond ((locate-library "w3") 'w3)
-       ((executable-find "w3m") (if (locate-library "w3m")
-                                    'w3m
-                                  'w3m-standalone))
+  (cond ((fboundp 'libxml-parse-html-region) 'shr)
+       ((executable-find "w3m") 'gnus-w3m)
        ((executable-find "links") 'links)
        ((executable-find "lynx") 'lynx)
-       (t 'html2text))
+       ((locate-library "w3") 'w3)
+       ((locate-library "html2text") 'html2text)
+       (t nil))
   "Render of HTML contents.
 It is one of defined renderer types, or a rendering function.
 The defined renderer types are:
-`w3'   : use Emacs/W3;
-`w3m'  : use emacs-w3m;
-`w3m-standalone': use w3m;
+`shr': use the built-in Gnus HTML renderer;
+`gnus-w3m': use Gnus renderer based on w3m;
+`w3m': use emacs-w3m;
+`w3m-standalone': use plain 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)
+`lynx': use lynx;
+`w3': use Emacs/W3;
+`html2text': use html2text;
+nil    : use external viewer (default web browser)."
+  :version "24.1"
+  :type '(choice (const shr)
+                 (const gnus-w3m)
+                 (const w3)
+                 (const w3m :tag "emacs-w3m")
+                (const w3m-standalone :tag "standalone w3m" )
                 (const links)
                 (const lynx)
                 (const html2text)
-                (const nil)
+                (const nil :tag "External viewer")
                 (function))
   :group 'mime-display)
 
-(defvar mm-inline-text-html-renderer nil
-  "Function used for rendering inline HTML contents.
-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 HTML contents with
 the <img> tags.  It has no effect on Emacs/w3.  See also the
@@ -192,7 +211,7 @@ before the external MIME handler is invoked."
     ("image/tiff"
      mm-inline-image
      (lambda (handle)
-       (mm-valid-and-fit-image-p 'tiff handle)) )
+       (mm-valid-and-fit-image-p 'tiff handle)))
     ("image/xbm"
      mm-inline-image
      (lambda (handle)
@@ -220,22 +239,21 @@ before the external MIME handler is invoked."
     ("text/plain" mm-inline-text identity)
     ("text/enriched" mm-inline-text identity)
     ("text/richtext" mm-inline-text identity)
-    ("text/x-patch" mm-display-patch-inline
-     (lambda (handle)
-       ;; 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)))
+    ("text/x-patch" mm-display-patch-inline identity)
+    ;; In case mime.types uses x-diff (as does Debian's mime-support-3.40).
+    ("text/x-diff" mm-display-patch-inline identity)
     ("application/emacs-lisp" mm-display-elisp-inline identity)
     ("application/x-emacs-lisp" mm-display-elisp-inline identity)
+    ("application/x-shellscript" mm-display-shell-script-inline identity)
+    ("application/x-sh" mm-display-shell-script-inline identity)
+    ("text/x-sh" mm-display-shell-script-inline identity)
+    ("application/javascript" mm-display-javascript-inline identity)
     ("text/dns" mm-display-dns-inline identity)
+    ("text/x-org" mm-display-org-inline identity)
     ("text/html"
      mm-inline-text-html
      (lambda (handle)
-       (or mm-inline-text-html-renderer
-          mm-text-html-renderer)))
+       mm-text-html-renderer))
     ("text/x-vcard"
      mm-inline-text-vcard
      (lambda (handle)
@@ -246,6 +264,8 @@ before the external MIME handler is invoked."
     ("message/partial" mm-inline-partial identity)
     ("message/external-body" mm-inline-external-body identity)
     ("text/.*" mm-inline-text identity)
+    ("application/x-.?tar\\(-.*\\)?" mm-archive-dissect-and-inline identity)
+    ("application/zip" mm-archive-dissect-and-inline identity)
     ("audio/wav" mm-inline-audio
      (lambda (handle)
        (and (or (featurep 'nas-sound) (featurep 'native-sound))
@@ -263,6 +283,21 @@ before the external MIME handler is invoked."
     ("multipart/alternative" ignore identity)
     ("multipart/mixed" ignore identity)
     ("multipart/related" ignore identity)
+    ("image/.*"
+     mm-inline-image
+     (lambda (handle)
+       (and (mm-valid-image-format-p 'imagemagick)
+           (mm-with-unibyte-buffer
+             (mm-insert-part handle)
+             (let ((image
+                    (ignore-errors
+                      (if (fboundp 'create-image)
+                          (create-image (buffer-string) 'imagemagick 'data-p)
+                        (mm-create-image-xemacs
+                         (mm-handle-media-subtype handle))))))
+               (when image
+                 (setcar (cdr handle) (list "image/imagemagick"))
+                 (mm-image-fit-p handle)))))))
     ;; Disable audio and image
     ("audio/.*" ignore ignore)
     ("image/.*" ignore ignore)
@@ -281,6 +316,9 @@ before the external MIME handler is invoked."
     "application/pgp-signature" "application/x-pkcs7-signature"
     "application/pkcs7-signature" "application/x-pkcs7-mime"
     "application/pkcs7-mime"
+    "application/x-gtar-compressed"
+    "application/x-tar"
+    "application/zip"
     ;; Mutt still uses this even though it has already been withdrawn.
     "application/pgp")
   "List of media types that are to be displayed inline.
@@ -307,7 +345,8 @@ when selecting a different article."
     "application/pkcs7-signature" "application/x-pkcs7-mime"
     "application/pkcs7-mime"
     ;; Mutt still uses this even though it has already been withdrawn.
-    "application/pgp\\'")
+    "application/pgp\\'"
+     "text/x-org")
   "A list of MIME types to be displayed automatically."
   :type '(repeat regexp)
   :group 'mime-display)
@@ -343,7 +382,7 @@ to:
  (\"text/html\" \"text/richtext\")
 
 Adding \"image/.*\" might also be useful.  Spammers use it as the
-prefered part of multipart/alternative messages.  See also
+preferred 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'.
@@ -360,8 +399,12 @@ enables you to choose manually one of two types those mails include."
   :group 'mime-display)
 
 (defcustom mm-inline-large-images nil
-  "If non-nil, then all images fit in the buffer."
-  :type 'boolean
+  "If t, then all images fit in the buffer.
+If 'resize, try to resize the images so they fit."
+  :type '(radio
+          (const :tag "Inline large images as they are." t)
+          (const :tag "Resize large images." resize)
+          (const :tag "Do not inline large images." nil))
   :group 'mime-display)
 
 (defcustom mm-file-name-rewrite-functions
@@ -389,7 +432,7 @@ functions), `mm-file-name-delete-whitespace',
               (repeat :inline t
                       :tag "Function"
                       function)))
-  :version "23.0" ;; No Gnus
+  :version "23.1" ;; No Gnus
   :group 'mime-display)
 
 
@@ -427,6 +470,12 @@ If not set, `default-directory' will be used."
 (defvar mm-last-shell-command "")
 (defvar mm-content-id-alist nil)
 (defvar mm-postponed-undisplay-list nil)
+(defvar mm-inhibit-auto-detect-attachment nil)
+(defvar mm-temp-files-to-be-deleted nil
+  "List of temporary files scheduled to be deleted.")
+(defvar mm-temp-files-cache-file (concat ".mm-temp-files-" (user-login-name))
+  "Name of a file that caches a list of temporary files to be deleted.
+The file will be saved in the directory `mm-tmp-directory'.")
 
 ;; According to RFC2046, in particular, in a digest, the default
 ;; Content-Type value for a body part is changed from "text/plain" to
@@ -489,14 +538,6 @@ result of the verification."
     map)
   "Keymap for input viewer with completion.")
 
-(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.")
-
 ;;; The functions.
 
 (defun mm-alist-to-plist (alist)
@@ -543,8 +584,52 @@ Postpone undisplaying of viewers for types in
     (message "Destroying external MIME viewers")
     (mm-destroy-parts mm-postponed-undisplay-list)))
 
+(defun mm-temp-files-delete ()
+  "Delete temporary files and those parent directories.
+Note that the deletion may fail if a program is catching hold of a file
+under Windows or Cygwin.  In that case, it schedules the deletion of
+files left at the next time."
+  (let* ((coding-system-for-read mm-universal-coding-system)
+        (coding-system-for-write mm-universal-coding-system)
+        (cache-file (expand-file-name mm-temp-files-cache-file
+                                      mm-tmp-directory))
+        (cache (when (file-exists-p cache-file)
+                 (mm-with-multibyte-buffer
+                   (insert-file-contents cache-file)
+                   (split-string (buffer-string) "\n" t))))
+        fails)
+    (dolist (temp (append cache mm-temp-files-to-be-deleted))
+      (when (and (file-exists-p temp)
+                (if (file-directory-p temp)
+                    ;; A parent directory left at the previous time.
+                    (progn
+                      (ignore-errors (delete-directory temp))
+                      (file-exists-p temp))
+                  ;; Delete a temporary file and its parent directory.
+                  (ignore-errors (delete-file temp))
+                  (or (file-exists-p temp)
+                      (progn
+                        (setq temp (file-name-directory temp))
+                        (ignore-errors (delete-directory temp))
+                        (file-exists-p temp)))))
+       (push temp fails)))
+    (if fails
+       ;; Schedule the deletion of the files left at the next time.
+       (progn
+         (write-region (concat (mapconcat 'identity (nreverse fails) "\n")
+                               "\n")
+                       nil cache-file nil 'silent)
+         (set-file-modes cache-file #o600))
+      (when (file-exists-p cache-file)
+       (ignore-errors (delete-file cache-file))))
+    (setq mm-temp-files-to-be-deleted nil)))
+
+(autoload 'message-fetch-field "message")
+
 (defun mm-dissect-buffer (&optional no-strict-mime loose-mime from)
-  "Dissect the current buffer and return a list of MIME handles."
+  "Dissect the current buffer and return a list of MIME handles.
+If NO-STRICT-MIME, don't require the message to have a
+MIME-Version header before proceeding."
   (save-excursion
     (let (ct ctl type subtype cte cd description id result)
       (save-restriction