(mime-edit-normalize-body): Don't use the `(replace-match "\\1\r\n")' form
[elisp/semi.git] / mime-edit.el
index 81b7613..18263bf 100644 (file)
@@ -1,9 +1,11 @@
 ;;; mime-edit.el --- Simple MIME Composer for GNU Emacs
 
-;; Copyright (C) 1993,94,95,96,97,98,99 Free Software Foundation, Inc.
+;; Copyright (C) 1993,94,95,96,97,98,99,2000,01,02,03
+;;   Free Software Foundation, Inc.
 
 ;; Author: UMEDA Masanobu <umerin@mse.kyutech.ac.jp>
-;;         MORIOKA Tomohiko <morioka@jaist.ac.jp>
+;;     MORIOKA Tomohiko <tomo@kanji.zinbun.kyoto-u.ac.jp>
+;;     Daiki Ueno <ueno@ueda.info.waseda.ac.jp>
 ;; Created: 1994/08/21 renamed from mime.el
 ;;     Renamed: 1997/2/21 from tm-edit.el
 ;; Keywords: MIME, multimedia, multilingual, mail, news
 (require 'sendmail)
 (require 'mail-utils)
 (require 'mel)
-(require 'eword-encode) ; eword-encode-field-body
 (require 'mime-view)
 (require 'signature)
 (require 'alist)
 (require 'invisible)
+(require 'pgg-def)
+(require 'pgg-parse)
+
+(autoload 'pgg-encrypt-region "pgg"
+  "PGP encryption of current region." t)
+(autoload 'pgg-sign-region "pgg"
+  "PGP signature of current region." t)
+(autoload 'pgg-insert-key "pgg"
+  "Insert PGP public key at point." t)
+(autoload 'smime-encrypt-region "smime"
+  "S/MIME encryption of current region.")
+(autoload 'smime-sign-region "smime"
+  "S/MIME signature of current region.")
+(defvar smime-output-buffer)
+(defvar smime-errors-buffer)
 
 
 ;;; @ version
@@ -301,7 +317,7 @@ To insert a signature file automatically, call the function
     ;;  Octect binary text
 
     ("\\.doc$"                         ;MS Word
-     "application" "winword" nil
+     "application" "msword" nil
      "base64"
      "attachment" (("filename" . file))
      )
@@ -324,7 +340,7 @@ To insert a signature file automatically, call the function
 
     ;;  Pure binary
 
-    ("\\.jpg$"
+    ("\\.jpg$\\|\\.jpeg$"
      "image"   "jpeg"          nil
      "base64"
      "inline"          (("filename" . file))
@@ -482,7 +498,10 @@ If encoding is nil, it is determined from its contents."
     (iso-8859-7                8 "quoted-printable")
     (iso-8859-8                8 "quoted-printable")
     (iso-8859-9                8 "quoted-printable")
+    (iso-8859-14       8 "quoted-printable")
+    (iso-8859-15       8 "quoted-printable")
     (iso-2022-jp       7 "base64")
+    (iso-2022-jp-3     7 "base64")
     (iso-2022-kr       7 "base64")
     (euc-kr            8 "base64")
     (cn-gb             8 "base64")
@@ -510,7 +529,6 @@ If encoding is nil, it is determined from its contents."
   "A string formatted version of mime-transfer-level")
 (make-variable-buffer-local 'mime-transfer-level-string)
 
-
 ;;; @@ about content transfer encoding
 
 (defvar mime-content-transfer-encoding-priority-list
@@ -632,8 +650,13 @@ If it is not specified for a major-mode,
          " ("
          (mime-product-code-name mime-library-product)
          ") "
+         (if (fboundp 'apel-version)
+             (concat (apel-version) " "))
          (if (featurep 'xemacs)
-             (concat (cond ((featurep 'utf-2000)
+             (concat (cond ((and (featurep 'chise)
+                                 (boundp 'xemacs-chise-version))
+                            (concat "CHISE-MULE/" xemacs-chise-version))
+                           ((featurep 'utf-2000)
                             (concat "UTF-2000-MULE/" utf-2000-version))
                            ((featurep 'mule) "MULE"))
                      " XEmacs"
@@ -652,7 +675,14 @@ If it is not specified for a major-mode,
                                  ;; XEmacs versions earlier than 21.1.1.
                                  (format " (patch %d)" emacs-patch-level))
                                 (t ""))
-                          " (" xemacs-codename ") ("
+                          " (" xemacs-codename ")"
+                          ;; `xemacs-extra-name' has appeared in the
+                          ;; development version of XEmacs 21.5-b8.
+                          (if (and (boundp 'xemacs-extra-name)
+                                   (symbol-value 'xemacs-extra-name))
+                              (concat " " (symbol-value 'xemacs-extra-name))
+                            "")
+                          " ("
                           system-configuration ")")
                        " (" emacs-version ")"))
            (let ((ver (if (string-match "\\.[0-9]+$" emacs-version)
@@ -693,7 +723,7 @@ Tspecials means any character that matches with it in header must be quoted.")
 
 (defconst mime-edit-mime-version-field-for-message/partial
   (concat "MIME-Version:"
-         (eword-encode-field-body
+         (mime-encode-field-body
           (concat " 1.0 (split by " mime-edit-version ")\n")
           "MIME-Version:"))
   "MIME version field for message/partial.")
@@ -780,9 +810,9 @@ Tspecials means any character that matches with it in header must be quoted.")
     (encrypted "Enclose as encrypted"  mime-edit-enclose-pgp-encrypted-region)
     (quote     "Verbatim region"       mime-edit-enclose-quote-region)
     (key       "Insert Public Key"     mime-edit-insert-key)
-    (split     "About split"           mime-edit-set-split)
-    (sign      "About sign"            mime-edit-set-sign)
-    (encrypt   "About encryption"      mime-edit-set-encrypt)
+    (split     "Set splitting"         mime-edit-set-split)
+    (sign      "PGP sign"              mime-edit-set-sign)
+    (encrypt   "PGP encrypt"           mime-edit-set-encrypt)
     (preview   "Preview Message"       mime-edit-preview-message)
     (level     "Toggle transfer-level" mime-edit-toggle-transfer-level)
     )
@@ -1033,6 +1063,7 @@ User customizable variables (not documented all of them):
                     paragraph-separate))
     (run-hooks 'mime-edit-mode-hook)
     (message
+     "%s"
      (substitute-command-keys
       "Type \\[mime-edit-exit] to exit MIME mode, and type \\[mime-edit-help] to get help."))
     ))
@@ -1384,7 +1415,11 @@ Optional argument ENCODING specifies an encoding method such as base64."
           (mime-create-tag
            (mime-edit-set-parameter
             (mime-edit-get-contype tag)
-            "charset" (upcase (symbol-name charset)))
+            "charset"
+            (let ((comment (get charset 'mime-charset-comment)))
+              (if comment
+                  (concat (upcase (symbol-name charset)) " (" comment ")")
+                (upcase (symbol-name charset)))))
            (mime-edit-get-encoding tag)))
          ))))
 
@@ -1474,7 +1509,7 @@ Nil if no such parameter."
        ;; Change value
        (concat (substring ctype 0 (match-beginning 1))
                parameter "=" value
-               (substring contype (match-end 1))
+               (substring ctype (match-end 1))
                opt-fields)
       (concat ctype "; " parameter "=" value opt-fields)
       )))
@@ -1572,7 +1607,7 @@ Optional DELIMITER specifies parameter delimiter (';' by default)."
 
 (defun mime-prompt-for-parameter (parameter)
   "Ask for PARAMETER.
-Parameter must be '(PROMPT CHOICE1 (CHOISE2 ...))."
+Parameter must be '(PROMPT CHOICE1 (CHOICE2...))."
   (let* ((prompt (car parameter))
         (choices (mapcar (function
                           (lambda (e)
@@ -1626,13 +1661,13 @@ Parameter must be '(PROMPT CHOICE1 (CHOISE2 ...))."
 
 (defun mime-edit-translate-header ()
   "Encode the message header into network representation."
-  (eword-encode-header 'code-conversion)
-  (run-hooks 'mime-edit-translate-header-hook)
-  )
+  (mime-encode-header-in-buffer 'code-conversion)
+  (run-hooks 'mime-edit-translate-header-hook))
 
 (defun mime-edit-translate-buffer ()
   "Encode the tagged MIME message in current buffer in MIME compliant message."
   (interactive)
+  (undo-boundary)
   (if (catch 'mime-edit-error
        (save-excursion
          (run-hooks 'mime-edit-translate-buffer-hook)
@@ -1703,6 +1738,12 @@ Parameter must be '(PROMPT CHOICE1 (CHOISE2 ...))."
                ((string-equal type "kazu-encrypted")
                 (mime-edit-encrypt-pgp-kazu bb eb boundary)
                 )
+               ((string-equal type "smime-signed")
+                (mime-edit-sign-smime bb eb boundary)
+                )
+               ((string-equal type "smime-encrypted")
+                (mime-edit-encrypt-smime bb eb boundary)
+                )
                (t
                 (setq boundary
                       (nth 2 (mime-edit-translate-region bb eb
@@ -1736,26 +1777,57 @@ Parameter must be '(PROMPT CHOICE1 (CHOISE2 ...))."
          (replace-match (concat "-" (substring tag 2)))
          )))))
 
+(defvar mime-edit-pgp-user-id nil)
+
 (defun mime-edit-sign-pgp-mime (beg end boundary)
   (save-excursion
     (save-restriction
-      (narrow-to-region beg end)
-      (let* ((ret
-             (mime-edit-translate-region beg end boundary))
+      (let* ((from (std11-field-body "From" mail-header-separator))
+            (ret (progn 
+                   (narrow-to-region beg end)
+                   (mime-edit-translate-region beg end boundary)))
             (ctype    (car ret))
             (encoding (nth 1 ret))
-            (pgp-boundary (concat "pgp-sign-" boundary)))
+            (pgp-boundary (concat "pgp-sign-" boundary))
+            micalg)
        (goto-char beg)
        (insert (format "Content-Type: %s\n" ctype))
        (if encoding
            (insert (format "Content-Transfer-Encoding: %s\n" encoding))
          )
        (insert "\n")
-       (or (as-binary-process
-            (funcall (pgp-function 'mime-sign)
-                     (point-min)(point-max) nil nil pgp-boundary))
+       (or (let ((pgg-default-user-id 
+                  (or mime-edit-pgp-user-id
+                      (if from 
+                          (nth 1 (std11-extract-address-components from))
+                        pgg-default-user-id))))
+             (pgg-sign-region (point-min)(point-max)))
            (throw 'mime-edit-error 'pgp-error)
            )
+       (setq micalg
+             (cdr (assq 'hash-algorithm
+                        (cdar (with-current-buffer pgg-output-buffer
+                                (pgg-parse-armor-region 
+                                 (point-min)(point-max))))))
+             micalg 
+             (if micalg
+                 (concat "; micalg=pgp-" (downcase (symbol-name micalg)))
+               ""))
+       (goto-char beg)
+       (insert (format "--[[multipart/signed;
+ boundary=\"%s\"%s;
+ protocol=\"application/pgp-signature\"][7bit]]
+--%s
+" pgp-boundary micalg pgp-boundary))
+       (goto-char (point-max))
+       (insert (format "\n--%s
+Content-Type: application/pgp-signature
+Content-Transfer-Encoding: 7bit
+
+" pgp-boundary))
+       (insert-buffer-substring pgg-output-buffer)
+       (goto-char (point-max))
+       (insert (format "\n--%s--\n" pgp-boundary))
        ))))
 
 (defvar mime-edit-encrypt-recipient-fields-list '("To" "cc"))
@@ -1796,28 +1868,41 @@ Parameter must be '(PROMPT CHOICE1 (CHOISE2 ...))."
   (save-excursion
     (save-restriction
       (let (from recipients header)
-       (let ((ret (mime-edit-make-encrypt-recipient-header)))
-         (setq from (aref ret 0)
-               recipients (aref ret 1)
-               header (aref ret 2))
+        (let ((ret (mime-edit-make-encrypt-recipient-header)))
+          (setq from (aref ret 0)
+                recipients (aref ret 1)
+                header (aref ret 2))
          )
-       (narrow-to-region beg end)
-       (let* ((ret
-               (mime-edit-translate-region beg end boundary))
-              (ctype    (car ret))
-              (encoding (nth 1 ret))
-              (pgp-boundary (concat "pgp-" boundary)))
-         (goto-char beg)
-         (insert header)
-         (insert (format "Content-Type: %s\n" ctype))
-         (if encoding
-             (insert (format "Content-Transfer-Encoding: %s\n" encoding))
-           )
-         (insert "\n")
-         (or (funcall (pgp-function 'encrypt)
-                      recipients (point-min) (point-max) from)
+        (narrow-to-region beg end)
+        (let* ((ret
+                (mime-edit-translate-region beg end boundary))
+               (ctype    (car ret))
+               (encoding (nth 1 ret))
+               (pgp-boundary (concat "pgp-" boundary)))
+          (goto-char beg)
+          (insert header)
+          (insert (format "Content-Type: %s\n" ctype))
+          (if encoding
+              (insert (format "Content-Transfer-Encoding: %s\n" encoding))
+            )
+          (insert "\n")
+         (mime-encode-header-in-buffer)
+         (or (let ((pgg-default-user-id 
+                    (or mime-edit-pgp-user-id
+                        (if from 
+                            (nth 1 (std11-extract-address-components from))
+                          pgg-default-user-id))))                   
+               (pgg-encrypt-region 
+                (point-min) (point-max) 
+                (mapcar (lambda (recipient)
+                          (nth 1 (std11-extract-address-components
+                                  recipient)))
+                        (split-string recipients 
+                                      "\\([ \t\n]*,[ \t\n]*\\)+")))
+               )
              (throw 'mime-edit-error 'pgp-error)
              )
+         (delete-region (point-min)(point-max))
          (goto-char beg)
          (insert (format "--[[multipart/encrypted;
  boundary=\"%s\";
@@ -1830,6 +1915,7 @@ Content-Type: application/octet-stream
 Content-Transfer-Encoding: 7bit
 
 " pgp-boundary pgp-boundary pgp-boundary))
+         (insert-buffer-substring pgg-output-buffer)
          (goto-char (point-max))
          (insert (format "\n--%s--\n" pgp-boundary))
          )))))
@@ -1848,9 +1934,7 @@ Content-Transfer-Encoding: 7bit
            (insert (format "Content-Transfer-Encoding: %s\n" encoding))
          )
        (insert "\n")
-       (or (as-binary-process
-            (funcall (pgp-function 'traditional-sign)
-                     beg (point-max)))
+       (or (pgg-sign-region beg (point-max) 'clearsign)
            (throw 'mime-edit-error 'pgp-error)
            )
        (goto-char beg)
@@ -1879,10 +1963,7 @@ Content-Transfer-Encoding: 7bit
              (insert (format "Content-Transfer-Encoding: %s\n" encoding))
            )
          (insert "\n")
-         (or (as-binary-process
-              (funcall (pgp-function 'encrypt)
-                       recipients beg (point-max) nil 'maybe)
-              )
+         (or (pgg-encrypt-region beg (point-max) recipients)
              (throw 'mime-edit-error 'pgp-error)
              )
          (goto-char beg)
@@ -1891,6 +1972,78 @@ Content-Transfer-Encoding: 7bit
          ))
       )))
 
+(defun mime-edit-sign-smime (beg end boundary)
+  (save-excursion
+    (save-restriction
+      (let* ((ret (progn 
+                   (narrow-to-region beg end)
+                   (mime-edit-translate-region beg end boundary)))
+            (ctype    (car ret))
+            (encoding (nth 1 ret))
+            (smime-boundary (concat "smime-sign-" boundary)))
+       (goto-char beg)
+       (insert (format "Content-Type: %s\n" ctype))
+       (if encoding
+           (insert (format "Content-Transfer-Encoding: %s\n" encoding))
+         )
+       (insert "\n")
+       (let (buffer-undo-list)
+         (goto-char (point-min))
+         (while (progn (end-of-line) (not (eobp)))
+           (insert "\r")
+           (forward-line 1))
+         (or (prog1 (smime-sign-region (point-min)(point-max))
+               (push nil buffer-undo-list)
+               (ignore-errors (undo)))
+             (throw 'mime-edit-error 'pgp-error)
+             ))
+       (goto-char beg)
+       (insert (format "--[[multipart/signed;
+ boundary=\"%s\"; micalg=sha1;
+ protocol=\"application/pkcs7-signature\"][7bit]]
+--%s
+" smime-boundary smime-boundary))
+       (goto-char (point-max))
+       (insert (format "\n--%s
+Content-Type: application/pkcs7-signature; name=\"smime.p7s\"
+Content-Transfer-Encoding: base64
+Content-Disposition: attachment; filename=\"smime.p7s\"
+Content-Description: S/MIME Cryptographic Signature
+
+"  smime-boundary))
+       (insert-buffer-substring smime-output-buffer)
+       (goto-char (point-max))
+       (insert (format "\n--%s--\n" smime-boundary))
+       ))))
+
+(defun mime-edit-encrypt-smime (beg end boundary)
+  (save-excursion
+    (save-restriction
+      (let* ((ret (progn 
+                   (narrow-to-region beg end)
+                   (mime-edit-translate-region beg end boundary)))
+            (ctype    (car ret))
+            (encoding (nth 1 ret)))
+       (goto-char beg)
+       (insert (format "Content-Type: %s\n" ctype))
+       (if encoding
+           (insert (format "Content-Transfer-Encoding: %s\n" encoding))
+         )
+       (insert "\n")
+       (goto-char (point-min))
+       (while (progn (end-of-line) (not (eobp)))
+         (insert "\r")
+         (forward-line 1))
+       (or (smime-encrypt-region (point-min)(point-max))
+           (throw 'mime-edit-error 'pgp-error)
+           )
+       (delete-region (point-min)(point-max))
+       (insert "--[[application/pkcs7-mime; name=\"smime.p7m\"
+Content-Disposition: attachment; filename=\"smime.p7m\"
+Content-Description: S/MIME Encrypted Message][base64]]\n")
+       (insert-buffer-substring smime-output-buffer)
+       ))))
+
 (defsubst replace-space-with-underline (str)
   (mapconcat (function
              (lambda (arg)
@@ -1981,8 +2134,7 @@ Content-Transfer-Encoding: 7bit
            (insert "Content-Type: " contype "\n")
            (if encoding
                (insert "Content-Transfer-Encoding: " encoding "\n"))
-           (eword-encode-header)
-           )
+           (mime-encode-header-in-buffer))
          (cons (and contype
                     (downcase contype))
                (and encoding
@@ -2104,7 +2256,7 @@ Content-Transfer-Encoding: 7bit
                    ;;                        (point)
                    ;;                        'hard t)))
                   ;; End patch for hard newlines
-                  (enriched-encode beg end)
+                  (enriched-encode beg end nil)
                   (goto-char beg)
                   (if (search-forward "\n\n")
                       (delete-region beg (match-end 0))
@@ -2150,7 +2302,12 @@ Content-Transfer-Encoding: 7bit
                    (narrow-to-region beg (mime-edit-content-end))
                    (goto-char beg)
                    (while (re-search-forward "\\(\\=\\|[^\r]\\)\n" nil t)
-                     (replace-match "\\1\r\n"))))
+                     ;; Don't use this in the multibyte buffer since it may
+                     ;; convert the unibyte string into multibyte.
+                     ;;;;(replace-match "\\1\r\n"))))
+                     (backward-char 1)
+                     (insert "\r")
+                     (forward-char 1))))
              (goto-char beg)
              (mime-encode-region beg (mime-edit-content-end)
                                  (or encoding "7bit"))
@@ -2308,13 +2465,25 @@ and insert data encoded as ENCODING."
   (mime-edit-enclose-region-internal 'kazu-encrypted beg end)
   )
 
+(defun mime-edit-enclose-smime-signed-region (beg end)
+  (interactive "*r")
+  (mime-edit-enclose-region-internal 'smime-signed beg end)
+  )
+
+(defun mime-edit-enclose-smime-encrypted-region (beg end)
+  (interactive "*r")
+  (mime-edit-enclose-region-internal 'smime-encrypted beg end)
+  )
+
 (defun mime-edit-insert-key (&optional arg)
   "Insert a pgp public key."
   (interactive "P")
   (mime-edit-insert-tag "application" "pgp-keys")
   (mime-edit-define-encoding "7bit")
-  (funcall (pgp-function 'insert-key))
-  )
+  (pgg-insert-key)
+  (if (and (not (eobp))
+          (not (looking-at mime-edit-single-part-tag-regexp)))
+      (insert (mime-make-text-tag) "\n")))
 
 
 ;;; @ flag setting
@@ -2373,12 +2542,14 @@ Optional TRANSFER-LEVEL is a number of transfer-level, 7 or 8."
     ))
   (if arg
       (progn
-       (setq mime-edit-pgp-processing 'sign)
+       (or (memq 'sign mime-edit-pgp-processing)
+           (setq mime-edit-pgp-processing 
+                 (nconc mime-edit-pgp-processing 
+                        (copy-sequence '(sign)))))
        (message "This message will be signed.")
        )
-    (if (eq mime-edit-pgp-processing 'sign)
-       (setq mime-edit-pgp-processing nil)
-      )
+    (setq mime-edit-pgp-processing 
+         (delq 'sign mime-edit-pgp-processing))
     (message "This message will not be signed.")
     ))
 
@@ -2389,12 +2560,14 @@ Optional TRANSFER-LEVEL is a number of transfer-level, 7 or 8."
     ))
   (if arg
       (progn
-       (setq mime-edit-pgp-processing 'encrypt)
+       (or (memq 'encrypt mime-edit-pgp-processing)
+           (setq mime-edit-pgp-processing 
+                 (nconc mime-edit-pgp-processing 
+                        (copy-sequence '(encrypt)))))
        (message "This message will be encrypt.")
        )
-    (if (eq mime-edit-pgp-processing 'encrypt)
-       (setq mime-edit-pgp-processing nil)
-      )
+    (setq mime-edit-pgp-processing
+         (delq 'encrypt mime-edit-pgp-processing))
     (message "This message will not be encrypt.")
     ))
 
@@ -2404,15 +2577,18 @@ Optional TRANSFER-LEVEL is a number of transfer-level, 7 or 8."
               (if (search-forward (concat "\n" mail-header-separator "\n"))
                   (match-end 0)
                 )))
-       (end (point-max))
        )
     (if beg
-       (cond ((eq mime-edit-pgp-processing 'sign)
-              (mime-edit-enclose-pgp-signed-region beg end)
-              )
-             ((eq mime-edit-pgp-processing 'encrypt)
-              (mime-edit-enclose-pgp-encrypted-region beg end)
-              ))
+       (dolist (pgp-processing mime-edit-pgp-processing)
+         (case pgp-processing
+           (sign
+            (mime-edit-enclose-pgp-signed-region 
+             beg (point-max))
+            )
+           (encrypt
+            (mime-edit-enclose-pgp-encrypted-region 
+             beg (point-max))
+            )))
       )))
 
 
@@ -2441,11 +2617,7 @@ Content-Type: message/partial; id=%s; number=%d; total=%d\n%s\n"
            (or (cdr (assq major-mode mime-edit-message-max-lines-alist))
                mime-edit-message-default-max-lines))
       )
-  (let* ((mime-edit-draft-file-name
-         (or (buffer-file-name)
-             (make-temp-name
-              (expand-file-name "mime-draft" temporary-file-directory))))
-        (separator mail-header-separator)
+  (let* ((separator mail-header-separator)
         (id (concat "\""
                     (replace-space-with-underline (current-time-string))
                     "@" (system-name) "\"")))
@@ -2506,7 +2678,7 @@ Content-Type: message/partial; id=%s; number=%d; total=%d\n%s\n"
          (message (format "Sending %d/%d..."
                           mime-edit-partial-number total))
          (call-interactively command)
-         (message (format "Sending %d/%d... done"
+         (message (format "Sending %d/%d...done"
                           mime-edit-partial-number total))
          )
        (setq mime-edit-partial-number
@@ -2524,7 +2696,7 @@ Content-Type: message/partial; id=%s; number=%d; total=%d\n%s\n"
       (save-excursion
        (message (format "Sending %d/%d..."
                         mime-edit-partial-number total))
-       (message (format "Sending %d/%d... done"
+       (message (format "Sending %d/%d...done"
                         mime-edit-partial-number total))
        )
       )))
@@ -2557,6 +2729,7 @@ Content-Type: message/partial; id=%s; number=%d; total=%d\n%s\n"
         (buf-name (buffer-name))
         (temp-buf-name (concat "*temp-article:" buf-name "*"))
         (buf (get-buffer temp-buf-name))
+        (pgp-processing mime-edit-pgp-processing)
         )
     (if buf
        (progn
@@ -2572,6 +2745,7 @@ Content-Type: message/partial; id=%s; number=%d; total=%d\n%s\n"
     (setq mail-header-separator separator)
     (make-local-variable 'mime-edit-buffer)
     (setq mime-edit-buffer the-buf)
+    (setq mime-edit-pgp-processing pgp-processing)
 
     (run-hooks 'mime-edit-translate-hook)
     (mime-edit-translate-buffer)
@@ -2581,19 +2755,18 @@ Content-Type: message/partial; id=%s; number=%d; total=%d\n%s\n"
        (replace-match "")
       )
     (mime-view-buffer)
-    ))
+    (make-local-variable 'mime-edit-temp-message-buffer)
+    (setq mime-edit-temp-message-buffer buf)))
 
 (defun mime-edit-quitting-method ()
   "Quitting method for mime-view."
-  (let* ((entity (get-text-property (point-min) 'mime-view-entity))
-        (temp (mime-entity-buffer entity))
+  (let* ((temp mime-edit-temp-message-buffer)
         buf)
     (mime-preview-kill-buffer)
     (set-buffer temp)
     (setq buf mime-edit-buffer)
     (kill-buffer temp)
-    (switch-to-buffer buf)
-    ))
+    (switch-to-buffer buf)))
 
 (set-alist 'mime-preview-quitting-method-alist
           'mime-temp-message-mode
@@ -2616,7 +2789,12 @@ Content-Type: message/partial; id=%s; number=%d; total=%d\n%s\n"
     string))
 
 (defun mime-edit-decode-multipart-in-buffer (content-type not-decode-text)
-  (let* ((subtype (mime-content-type-subtype content-type))
+  (let* ((subtype
+         (or
+          (cdr (assoc (mime-content-type-parameter content-type "protocol")
+                      '(("application/pgp-encrypted" . pgp-encrypted)
+                        ("application/pgp-signature" . pgp-signed))))
+          (mime-content-type-subtype content-type)))
         (boundary (mime-content-type-parameter content-type "boundary"))
         (boundary-pat (concat "\n--" (regexp-quote boundary) "[ \t]*\n")))
     (re-search-forward boundary-pat nil t)
@@ -2644,13 +2822,36 @@ Content-Type: message/partial; id=%s; number=%d; total=%d\n%s\n"
                )
              (save-restriction
                (narrow-to-region beg end)
-               (mime-edit-decode-message-in-buffer
-                (if (eq subtype 'digest)
-                    (eval-when-compile
-                      (make-mime-content-type 'message 'rfc822))
-                  )
-                not-decode-text)
-               (goto-char (point-max))
+               (cond
+                ((eq subtype 'pgp-encrypted)
+                 (when (and
+                        (progn
+                          (goto-char (point-min))
+                          (re-search-forward "^-+BEGIN PGP MESSAGE-+$"
+                                             nil t))
+                        (prog1 
+                            (save-window-excursion
+                              (pgg-decrypt-region (match-beginning 0)
+                                                  (point-max)))
+                          (delete-region (point-min)(point-max))))
+                   (insert-buffer-substring pgg-output-buffer)
+                   (mime-edit-decode-message-in-buffer 
+                    nil not-decode-text)
+                   (delete-region (goto-char (point-min))
+                                  (if (search-forward "\n\n" nil t)
+                                      (match-end 0)
+                                    (point-min)))
+                   (goto-char (point-max))
+                   ))
+                (t 
+                 (mime-edit-decode-message-in-buffer
+                  (if (eq subtype 'digest)
+                      (eval-when-compile
+                        (make-mime-content-type 'message 'rfc822))
+                    )
+                  not-decode-text)
+                 (goto-char (point-max))
+                 ))
                ))))
        ))
     (goto-char (point-min))
@@ -2662,7 +2863,8 @@ Content-Type: message/partial; id=%s; number=%d; total=%d\n%s\n"
                         )))
     ))
 
-(defun mime-edit-decode-single-part-in-buffer (content-type not-decode-text)
+(defun mime-edit-decode-single-part-in-buffer
+  (content-type not-decode-text &optional content-disposition)
   (let* ((type (mime-content-type-primary-type content-type))
         (subtype (mime-content-type-subtype content-type))
         (ctype (format "%s/%s" type subtype))
@@ -2689,7 +2891,38 @@ Content-Type: message/partial; id=%s; number=%d; total=%d\n%s\n"
         encoded
         (limit (save-excursion
                  (if (search-forward "\n\n" nil t)
-                     (1- (point))))))
+                     (1- (point)))))
+        (disposition-type
+         (mime-content-disposition-type content-disposition))
+        (disposition-str
+         (if disposition-type
+             (let ((bytes (+ 21 (length (format "%s" disposition-type)))))
+               (mapconcat (function
+                           (lambda (attr)
+                             (let* ((str (concat
+                                          (car attr)
+                                          "="
+                                          (if (string-equal "filename"
+                                                            (car attr))
+                                              (std11-wrap-as-quoted-string
+                                               (cdr attr))
+                                            (cdr attr))))
+                                    (bs (length str)))
+                               (setq bytes (+ bytes bs 2))
+                               (if (< bytes 76)
+                                   (concat "; " str)
+                                 (setq bytes (+ bs 1))
+                                 (concat ";\n " str)
+                                 )
+                               )))
+                          (mime-content-disposition-parameters
+                           content-disposition)
+                          ""))))
+        )
+    (if disposition-type
+       (setq pstr (format "%s\nContent-Disposition: %s%s"
+                          pstr disposition-type disposition-str))
+      )
     (save-excursion
       (if (re-search-forward
           "^Content-Transfer-Encoding:" limit t)
@@ -2712,7 +2945,8 @@ Content-Type: message/partial; id=%s; number=%d; total=%d\n%s\n"
                        (setq encoded t
                              encoding nil)
                        )))))))
-    (if (or encoded (not not-decode-text))
+    (if (and (eq type 'text)
+            (or encoded (not not-decode-text)))
        (progn
          (save-excursion
            (goto-char (point-min))
@@ -2764,19 +2998,24 @@ Content-Type: message/partial; id=%s; number=%d; total=%d\n%s\n"
              (mime-edit-decode-multipart-in-buffer ctl not-decode-text)
              )
             (t
-             (mime-edit-decode-single-part-in-buffer ctl not-decode-text)
+             (mime-edit-decode-single-part-in-buffer
+              ctl not-decode-text (mime-read-Content-Disposition))
              )))
        (or not-decode-text
            (decode-mime-charset-region (point-min) (point-max)
                                        default-mime-charset))
        )
-      (save-restriction
-       (std11-narrow-to-header)
-       (goto-char (point-min))
-       (while (re-search-forward mime-edit-again-ignored-field-regexp nil t)
-         (delete-region (match-beginning 0) (1+ (std11-field-end)))
-         ))
-      (mime-decode-header-in-buffer (not not-decode-text))
+      (if (= (point-min) 1)
+         (progn
+           (save-restriction
+             (std11-narrow-to-header)
+             (goto-char (point-min))
+             (while (re-search-forward
+                     mime-edit-again-ignored-field-regexp nil t)
+               (delete-region (match-beginning 0) (1+ (std11-field-end)))
+               ))
+           (mime-decode-header-in-buffer (not not-decode-text))
+           ))
       )))
 
 ;;;###autoload