;;; mm-uu.el --- Return uu stuff as mm handles
;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-;; 2005 Free Software Foundation, Inc.
+;; 2005, 2006, 2007 Free Software Foundation, Inc.
;; Author: Shenghuo Zhu <zsh@cs.rochester.edu>
;; Keywords: postscript uudecode binhex shar forward gnatsweb pgp
;; 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)
+;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.
;;
;; GNU Emacs is distributed in the hope that it will be useful,
(defvar mm-uu-yenc-decode-function 'yenc-decode-region)
-(defvar mm-uu-pgp-beginning-signature
- "^-----BEGIN PGP SIGNATURE-----")
-
(defvar mm-uu-beginning-regexp nil)
(defvar mm-dissect-disposition "inline"
:group 'gnus-article-mime)
(defvar mm-uu-type-alist
- `((postscript
+ '((postscript
"^%!PS-"
"^%%EOF$"
mm-uu-postscript-extract
nil
mm-uu-diff-test)
(message-marks
- ,(concat "^" (regexp-quote message-mark-insert-begin))
- ,(concat "^" (regexp-quote message-mark-insert-end))
- (lambda () (mm-uu-verbatim-marks-extract 0 -1 1 -2))
+ ;; Text enclosed with tags similar to `message-mark-insert-begin' and
+ ;; `message-mark-insert-end'. Don't use those variables to avoid
+ ;; dependency on `message.el'.
+ "^-+[8<>]*-\\{9,\\}[a-z ]+-\\{9,\\}[a-z ]+-\\{9,\\}[8<>]*-+$"
+ "^-+[8<>]*-\\{9,\\}[a-z ]+-\\{9,\\}[a-z ]+-\\{9,\\}[8<>]*-+$"
+ (lambda () (mm-uu-verbatim-marks-extract 0 -1 1 -1))
nil)
;; Omitting [a-z8<] leads to false positives (bogus signature separators
;; and mailing list banners).
;; http://www.slrn.org/manual/slrn-manual-6.html#ss6.81
"^#v\\+"
"^#v\\-$"
- (lambda () (mm-uu-verbatim-marks-extract 0 0 1 -1))
+ (lambda () (mm-uu-verbatim-marks-extract 0 0))
nil)
(LaTeX
- "^\\\\documentclass"
+ "^\\([\\\\%][^\n]+\n\\)*\\\\documentclass.*[[{%]"
"^\\\\end{document}"
mm-uu-latex-extract
nil
Each element consist of the following entries: label,
start-regexp, end-regexp, extract-function, test-function.
-After modifying this list you must run \\[mm-uu-configure].")
+After modifying this list you must run \\[mm-uu-configure].
+
+You can disable elements from this list by customizing
+`mm-uu-configure-list'.")
(defcustom mm-uu-configure-list '((shar . disabled))
"A list of mm-uu configuration.
(defun mm-uu-emacs-sources-extract ()
(mm-make-handle (mm-uu-copy-to-buffer start-point end-point)
- '("application/emacs-lisp")
+ '("application/emacs-lisp" (charset . gnus-decoded))
nil nil
(list mm-dissect-disposition
(cons 'filename file-name))))
(defun mm-uu-diff-extract ()
(mm-make-handle (mm-uu-copy-to-buffer start-point end-point)
- '("text/x-patch")))
+ '("text/x-patch" (charset . gnus-decoded))))
(defun mm-uu-diff-test ()
(and gnus-newsgroup-name
((eq mm-verify-option 'never) nil)
((eq mm-verify-option 'always) t)
((eq mm-verify-option 'known) t)
- (t (y-or-n-p "Verify pgp signed part? ")))))
+ (t (prog1
+ (y-or-n-p "Verify pgp signed part? ")
+ (message ""))))))
(eval-when-compile
(defvar gnus-newsgroup-charset))
(progn
(mml2015-clean-buffer)
(let ((coding-system-for-write (or gnus-newsgroup-charset
- 'iso-8859-1)))
+ 'iso-8859-1))
+ (coding-system-for-read (or gnus-newsgroup-charset
+ 'iso-8859-1)))
(funcall (mml2015-clear-verify-function))))
(when (and mml2015-use (null (mml2015-clear-verify-function)))
(mm-set-handle-multipart-parameter
mm-security-handle 'gnus-details
- (format "Clear verification not supported by `%s'.\n" mml2015-use))))
- (goto-char (point-min))
- (if (search-forward "\n\n" nil t)
- (delete-region (point-min) (point)))
- (if (re-search-forward mm-uu-pgp-beginning-signature nil t)
- (delete-region (match-beginning 0) (point-max)))
- (goto-char (point-min))
- (while (re-search-forward "^- " nil t)
- (replace-match "" t t)
- (forward-line 1)))
- (list (mm-make-handle buf mm-uu-text-plain-type))))
+ (format "Clear verification not supported by `%s'.\n" mml2015-use)))
+ (mml2015-extract-cleartext-signature))
+ (list (mm-make-handle buf mm-uu-text-plain-type)))))
(defun mm-uu-pgp-signed-extract ()
(let ((mm-security-handle (list (format "multipart/signed"))))
((eq mm-decrypt-option 'never) nil)
((eq mm-decrypt-option 'always) t)
((eq mm-decrypt-option 'known) t)
- (t (y-or-n-p "Decrypt pgp encrypted part? ")))))
+ (t (prog1
+ (y-or-n-p "Decrypt pgp encrypted part? ")
+ (message ""))))))
(defun mm-uu-pgp-encrypted-extract-1 (handles ctl)
- (let ((buf (mm-uu-copy-to-buffer (point-min) (point-max))))
- (if (mm-uu-pgp-encrypted-test)
- (with-current-buffer buf
- (mml2015-clean-buffer)
- (funcall (mml2015-clear-decrypt-function))))
- (list (mm-make-handle buf mm-uu-text-plain-type))))
+ (let ((buf (mm-uu-copy-to-buffer (point-min) (point-max)))
+ (first t)
+ charset)
+ ;; Make sure there's a blank line between header and body.
+ (with-current-buffer buf
+ (goto-char (point-min))
+ (while (prog2
+ (forward-line 1)
+ (if first
+ (looking-at "[^\t\n ]+:")
+ (looking-at "[^\t\n ]+:\\|[\t ]"))
+ (setq first nil)))
+ (unless (memq (char-after) '(?\n nil))
+ (insert "\n"))
+ (save-restriction
+ (narrow-to-region (point-min) (point))
+ (setq charset (mail-fetch-field "charset")))
+ (if (and (mm-uu-pgp-encrypted-test)
+ (progn
+ (mml2015-clean-buffer)
+ (funcall (mml2015-clear-decrypt-function))
+ (equal (mm-handle-multipart-ctl-parameter mm-security-handle
+ 'gnus-info)
+ "OK")))
+ (progn
+ ;; Decode charset.
+ (if (and (or charset
+ (setq charset gnus-newsgroup-charset))
+ (setq charset (mm-charset-to-coding-system charset))
+ (not (eq charset 'ascii)))
+ ;; Assume that buffer's multibyteness is turned off.
+ ;; See `mml2015-pgg-clear-decrypt'.
+ (insert (mm-decode-coding-string (prog1
+ (buffer-string)
+ (erase-buffer)
+ (mm-enable-multibyte))
+ charset))
+ (mm-enable-multibyte))
+ (list (mm-make-handle buf mm-uu-text-plain-type)))
+ (list (mm-make-handle buf '("application/pgp-encrypted")))))))
(defun mm-uu-pgp-encrypted-extract ()
(let ((mm-security-handle (list (format "multipart/encrypted"))))
(t (goto-char (point-max))))
(setq text-start (point))
(while (re-search-forward mm-uu-beginning-regexp nil t)
- (setq start-point (match-beginning 0))
+ (setq start-point (match-beginning 0)
+ entry nil)
(let ((alist mm-uu-type-alist)
(beginning-regexp (match-string 0)))
(while (not entry)
(setq result (cons "multipart/mixed" (nreverse result))))
result)))
-(defun mm-uu-dissect-text-parts (handle)
- "Dissect text parts and put uu handles into HANDLE."
- (let ((buffer (mm-handle-buffer handle))
- type children)
+;;;###autoload
+(defun mm-uu-dissect-text-parts (handle &optional decoded)
+ "Dissect text parts and put uu handles into HANDLE.
+Assume text has been decoded if DECODED is non-nil."
+ (let ((buffer (mm-handle-buffer handle)))
(cond ((stringp buffer)
- (mapc 'mm-uu-dissect-text-parts (cdr handle)))
+ (dolist (elem (cdr handle))
+ (mm-uu-dissect-text-parts elem decoded)))
((bufferp buffer)
- (when (and (setq type (mm-handle-media-type handle))
- (stringp type)
- (string-match "\\`text/" type)
- (with-current-buffer buffer
- (setq children
- (mm-uu-dissect t (mm-handle-type handle)))))
- (kill-buffer buffer)
- (setcar handle (car children))
- (setcdr handle (cdr children))))
+ (let ((type (mm-handle-media-type handle))
+ (case-fold-search t) ;; string-match
+ children charset encoding)
+ (when (and
+ (stringp type)
+ ;; Mutt still uses application/pgp even though
+ ;; it has already been withdrawn.
+ (string-match "\\`text/\\|\\`application/pgp\\'" type)
+ (setq
+ children
+ (with-current-buffer buffer
+ (cond
+ ((or decoded
+ (eq (setq charset (mail-content-type-get
+ (mm-handle-type handle)
+ 'charset))
+ 'gnus-decoded))
+ (setq decoded t)
+ (mm-uu-dissect
+ t (cons type '((charset . gnus-decoded)))))
+ (charset
+ (setq decoded t)
+ (mm-with-multibyte-buffer
+ (insert (mm-decode-string (mm-get-part handle)
+ charset))
+ (mm-uu-dissect
+ t (cons type '((charset . gnus-decoded))))))
+ ((setq encoding (mm-handle-encoding handle))
+ (setq decoded nil)
+ ;; Inherit the multibyteness of the `buffer'.
+ (with-temp-buffer
+ (insert-buffer-substring buffer)
+ (mm-decode-content-transfer-encoding
+ encoding type)
+ (mm-uu-dissect t (list type))))
+ (t
+ (setq decoded nil)
+ (mm-uu-dissect t (list type)))))))
+ ;; Ignore it if a given part is dissected into a single
+ ;; part of which the type is the same as the given one.
+ (if (and (<= (length children) 2)
+ (string-equal (mm-handle-media-type (cadr children))
+ type))
+ (kill-buffer (mm-handle-buffer (cadr children)))
+ (kill-buffer buffer)
+ (setcdr handle (cdr children))
+ (setcar handle (car children)) ;; "multipart/mixed"
+ (dolist (elem (cdr children))
+ (mm-uu-dissect-text-parts elem decoded))))))
(t
- (mapc 'mm-uu-dissect-text-parts handle)))))
+ (dolist (elem handle)
+ (mm-uu-dissect-text-parts elem decoded))))))
(provide 'mm-uu)