X-Git-Url: http://git.chise.org/gitweb/?a=blobdiff_plain;f=mime-edit.el;h=4b3c7047e0ef82442daa75660a6d097ff953ec81;hb=bb5547109f0b264b10b7f99305473cff3d345ea3;hp=89b4655fcbade603b1bf5c72e26c5f40aa295c87;hpb=ea9c73dc4063684e899f109b48fe449c4e886d6e;p=elisp%2Fsemi.git diff --git a/mime-edit.el b/mime-edit.el index 89b4655..4b3c704 100644 --- a/mime-edit.el +++ b/mime-edit.el @@ -1,9 +1,11 @@ ;;; mime-edit.el --- Simple MIME Composer for GNU Emacs -;; Copyright (C) 1993,1994,1995,1996,1997,1998 Free Software Foundation, Inc. +;; Copyright (C) 1993,94,95,96,97,98,99,2000,01,02,03 +;; Free Software Foundation, Inc. ;; Author: UMEDA Masanobu -;; MORIOKA Tomohiko +;; MORIOKA Tomohiko +;; Daiki Ueno ;; Created: 1994/08/21 renamed from mime.el ;; Renamed: 1997/2/21 from tm-edit.el ;; Keywords: MIME, multimedia, multilingual, mail, news @@ -113,6 +115,21 @@ (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 @@ -120,13 +137,11 @@ (eval-and-compile (defconst mime-edit-version - (eval-when-compile - (concat - (mime-product-name mime-user-interface-product) " " - (mapconcat #'number-to-string - (mime-product-version mime-user-interface-product) ".") - " - \"" (mime-product-code-name mime-user-interface-product) "\""))) - ) + (concat + (mime-product-name mime-user-interface-product) " " + (mapconcat #'number-to-string + (mime-product-version mime-user-interface-product) ".") + " - \"" (mime-product-code-name mime-user-interface-product) "\""))) ;;; @ variables @@ -192,7 +207,7 @@ To insert a signature file automatically, call the function ("css") ; rfc2318 ("xml") ; rfc2376 ("x-latex") - ("x-rot13-47-48") + ;; ("x-rot13-47-48") ) ("message" ("external-body" @@ -221,6 +236,10 @@ To insert a signature file automatically, call the function ("application" ("octet-stream" ("type" "" "tar" "shar")) ("postscript") + ("pdf") + ("msword") + ("vnd.ms-excel") + ("vnd.ms-powerpoint") ("x-kiss" ("x-cnf"))) ("image" ("gif") @@ -301,7 +320,17 @@ 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)) + ) + ("\\.xls$" ; MS Excel + "application" "vnd.ms-excel" nil + "base64" + "attachment" (("filename" . file)) + ) + ("\\.ppt$" ; MS Power Point + "application" "vnd.ms-powerpoint" nil "base64" "attachment" (("filename" . file)) ) @@ -313,13 +342,18 @@ To insert a signature file automatically, call the function ) ("\\.ps$" "application" "postscript" nil - "quoted-printable" + "base64" + "attachment" (("filename" . file)) + ) + ("\\.pdf$" + "application" "pdf" nil + "base64" "attachment" (("filename" . file)) ) ;; Pure binary - ("\\.jpg$" + ("\\.jpg$\\|\\.jpeg$" "image" "jpeg" nil "base64" "inline" (("filename" . file)) @@ -477,7 +511,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") @@ -485,6 +522,7 @@ If encoding is nil, it is determined from its contents." (cn-big5 8 "base64") (big5 8 "base64") (shift_jis 8 "base64") + (tis-620 8 "base64") (iso-2022-jp-2 7 "base64") (iso-2022-int-1 7 "base64") )) @@ -504,7 +542,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 @@ -626,21 +663,40 @@ 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 (if (featurep 'mule) "MULE") + (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" - (if (string-match "\\s +\\\"" emacs-version) - (concat "/" - (substring emacs-version 0 - (match-beginning 0)) - (if (and (boundp 'xemacs-betaname) - ;; It does not exist in XEmacs - ;; versions prior to 20.3. - xemacs-betaname) - (concat " " xemacs-betaname) - "") - " (" xemacs-codename ") (" - system-configuration ")") + (if (string-match "^[0-9]+\\(\\.[0-9]+\\)" emacs-version) + (concat + "/" + (substring emacs-version 0 (match-end 0)) + (cond ((and (boundp 'xemacs-betaname) + xemacs-betaname) + ;; It does not exist in XEmacs + ;; versions prior to 20.3. + (concat " " xemacs-betaname)) + ((and (boundp 'emacs-patch-level) + emacs-patch-level) + ;; It does not exist in FSF Emacs or in + ;; XEmacs versions earlier than 21.1.1. + (format " (patch %d)" emacs-patch-level)) + (t "")) + " (" 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) (substring emacs-version 0 (match-beginning 0)) @@ -675,13 +731,14 @@ inserted into message header.") Tspecials means any character that matches with it in header must be quoted.") (defconst mime-edit-mime-version-value - (eval-when-compile - (concat "1.0 (generated by " mime-edit-version ")")) + (concat "1.0 (generated by " mime-edit-version ")") "MIME version number.") (defconst mime-edit-mime-version-field-for-message/partial - (eval-when-compile - (concat "MIME-Version: 1.0 (split by " mime-edit-version ")\n")) + (concat "MIME-Version:" + (mime-encode-field-body + (concat " 1.0 (split by " mime-edit-version ")\n") + "MIME-Version:")) "MIME version field for message/partial.") @@ -766,9 +823,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) ) @@ -1019,6 +1076,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.")) )) @@ -1370,7 +1428,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))) )))) @@ -1460,7 +1522,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) ))) @@ -1558,7 +1620,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) @@ -1612,13 +1674,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) @@ -1689,6 +1751,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 @@ -1722,26 +1790,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")) @@ -1782,28 +1881,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\"; @@ -1816,6 +1928,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)) ))))) @@ -1834,9 +1947,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) @@ -1865,10 +1976,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) @@ -1877,6 +1985,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) @@ -1967,8 +2147,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 @@ -2090,7 +2269,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)) @@ -2136,7 +2315,13 @@ 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")))) + ;; In a certain period, `replace-match' with "\\N" + ;; converted 8-bit characters into multibyte string, + ;; but it has been fixed at 2004-01-15. + ;;(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")) @@ -2163,8 +2348,7 @@ Content-Transfer-Encoding: 7bit (goto-char (point-min)) (while (re-search-forward regexp nil t) (delete-region (match-beginning 0) - (progn (forward-line 1) (point))) - ))) + (1+ (std11-field-end)))))) ;;; @@ -2295,13 +2479,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 @@ -2360,12 +2556,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.") )) @@ -2376,12 +2574,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.") )) @@ -2391,15 +2591,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)) + ))) ))) @@ -2428,11 +2631,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) "\""))) @@ -2493,7 +2692,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 @@ -2511,7 +2710,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)) ) ))) @@ -2544,6 +2743,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 @@ -2559,6 +2759,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) @@ -2568,18 +2769,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 ((temp mime-raw-buffer) - buf) + (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 @@ -2602,7 +2803,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) @@ -2630,13 +2836,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)) @@ -2648,7 +2877,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)) @@ -2675,13 +2905,44 @@ 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) (let ((beg (match-beginning 0)) (hbeg (match-end 0)) - (end (std11-field-end))) + (end (std11-field-end limit))) (setq encoding (downcase (eliminate-top-spaces @@ -2698,10 +2959,17 @@ 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)) - (decode-mime-charset-region (point-min)(point-max) - (or charset default-mime-charset)) - ) + (if (and (eq type 'text) + (or encoded (not not-decode-text))) + (progn + (save-excursion + (goto-char (point-min)) + (while (re-search-forward "\r\n" nil t) + (replace-match "\n") + )) + (decode-mime-charset-region (point-min)(point-max) + (or charset default-mime-charset)) + )) (let ((he (if (re-search-forward "^$" nil t) (match-end 0) (point-min) @@ -2744,19 +3012,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