Mercurial > emacs
comparison lisp/mh-e/mh-mime.el @ 89966:d8411455de48
Revision: miles@gnu.org--gnu-2004/emacs--unicode--0--patch-32
Merge from emacs--cvs-trunk--0
Patches applied:
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-486
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-487
Tweak permissions
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-488
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-489
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-490
Update from CVS: man/fixit.texi (Spelling): Fix typo.
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-491
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-494
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-495
Update from CVS: Add missing lisp/mh-e files
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-496
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-499
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-500
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-513
Update from CVS
author | Miles Bader <miles@gnu.org> |
---|---|
date | Fri, 27 Aug 2004 07:00:34 +0000 |
parents | 97905c4f1a42 25da1d331c99 |
children | 4da4a09e8b1b |
comparison
equal
deleted
inserted
replaced
89965:5e9097d1ad99 | 89966:d8411455de48 |
---|---|
32 | 32 |
33 ;;; Change Log: | 33 ;;; Change Log: |
34 | 34 |
35 ;;; Code: | 35 ;;; Code: |
36 | 36 |
37 (require 'mh-utils) | 37 (eval-when-compile (require 'mh-acros)) |
38 (mh-require-cl) | 38 (mh-require-cl) |
39 (require 'mh-comp) | 39 (require 'mh-comp) |
40 (require 'gnus-util) | 40 (require 'gnus-util) |
41 (require 'mh-gnus) | 41 (require 'mh-gnus) |
42 | 42 |
44 (autoload 'article-emphasize "gnus-art") | 44 (autoload 'article-emphasize "gnus-art") |
45 (autoload 'gnus-get-buffer-create "gnus") | 45 (autoload 'gnus-get-buffer-create "gnus") |
46 (autoload 'gnus-eval-format "gnus-spec") | 46 (autoload 'gnus-eval-format "gnus-spec") |
47 (autoload 'widget-convert-button "wid-edit") | 47 (autoload 'widget-convert-button "wid-edit") |
48 (autoload 'message-options-set-recipient "message") | 48 (autoload 'message-options-set-recipient "message") |
49 (autoload 'mml-secure-message-sign-pgpmime "mml-sec") | 49 (autoload 'mml-unsecure-message "mml-sec") |
50 (autoload 'mml-secure-message-encrypt-pgpmime "mml-sec") | |
51 (autoload 'mml-minibuffer-read-file "mml") | 50 (autoload 'mml-minibuffer-read-file "mml") |
52 (autoload 'mml-minibuffer-read-description "mml") | 51 (autoload 'mml-minibuffer-read-description "mml") |
53 (autoload 'mml-insert-empty-tag "mml") | 52 (autoload 'mml-insert-empty-tag "mml") |
54 (autoload 'mml-to-mime "mml") | 53 (autoload 'mml-to-mime "mml") |
55 (autoload 'mml-attach-file "mml") | 54 (autoload 'mml-attach-file "mml") |
80 If any of the optional arguments are absent, they are prompted for." | 79 If any of the optional arguments are absent, they are prompted for." |
81 (interactive (list | 80 (interactive (list |
82 (read-string "Forw Content-description: ") | 81 (read-string "Forw Content-description: ") |
83 (mh-prompt-for-folder "Message from" mh-sent-from-folder nil) | 82 (mh-prompt-for-folder "Message from" mh-sent-from-folder nil) |
84 (read-string (format "Messages%s: " | 83 (read-string (format "Messages%s: " |
85 (if mh-sent-from-msg | 84 (if (numberp mh-sent-from-msg) |
86 (format " [%d]" mh-sent-from-msg) | 85 (format " [%d]" mh-sent-from-msg) |
87 ""))))) | 86 ""))))) |
88 (if (equal mh-compose-insertion 'gnus) | 87 (if (equal mh-compose-insertion 'gnus) |
89 (mh-mml-forward-message description folder message) | 88 (mh-mml-forward-message description folder message) |
90 (mh-mhn-compose-forw description folder message))) | 89 (mh-mhn-compose-forw description folder message))) |
112 | 111 |
113 ;; Just defvar the variable to avoid compiler warning... This doesn't bind | 112 ;; Just defvar the variable to avoid compiler warning... This doesn't bind |
114 ;; the variable, so things should work exactly as before. | 113 ;; the variable, so things should work exactly as before. |
115 (defvar mh-have-file-command) | 114 (defvar mh-have-file-command) |
116 | 115 |
116 ;;;###mh-autoload | |
117 (defun mh-have-file-command () | 117 (defun mh-have-file-command () |
118 "Return t if 'file' command is on the system. | 118 "Return t if 'file' command is on the system. |
119 'file -i' is used to get MIME type of composition insertion." | 119 'file -i' is used to get MIME type of composition insertion." |
120 (when (not (boundp 'mh-have-file-command)) | 120 (when (not (boundp 'mh-have-file-command)) |
121 (load "executable" t t) ; executable-find not autoloaded in emacs20 | 121 (load "executable" t t) ; executable-find not autoloaded in emacs20 |
127 (expand-file-name "inc" mh-progs)))))) | 127 (expand-file-name "inc" mh-progs)))))) |
128 mh-have-file-command) | 128 mh-have-file-command) |
129 | 129 |
130 (defvar mh-file-mime-type-substitutions | 130 (defvar mh-file-mime-type-substitutions |
131 '(("application/msword" "\.xls" "application/ms-excel") | 131 '(("application/msword" "\.xls" "application/ms-excel") |
132 ("application/msword" "\.ppt" "application/ms-powerpoint")) | 132 ("application/msword" "\.ppt" "application/ms-powerpoint") |
133 ("text/plain" "\.vcf" "text/x-vcard")) | |
133 "Substitutions to make for Content-Type returned from file command. | 134 "Substitutions to make for Content-Type returned from file command. |
134 The first element is the Content-Type returned by the file command. | 135 The first element is the Content-Type returned by the file command. |
135 The second element is a regexp matching the file name, usually the extension. | 136 The second element is a regexp matching the file name, usually the extension. |
136 The third element is the Content-Type to replace with.") | 137 The third element is the Content-Type to replace with.") |
137 | 138 |
149 (setq answer (elt (car subst) 2) | 150 (setq answer (elt (car subst) 2) |
150 subst nil) | 151 subst nil) |
151 (setq subst (cdr subst)))) | 152 (setq subst (cdr subst)))) |
152 answer)) | 153 answer)) |
153 | 154 |
155 ;;;###mh-autoload | |
154 (defun mh-file-mime-type (filename) | 156 (defun mh-file-mime-type (filename) |
155 "Return MIME type of FILENAME from file command. | 157 "Return MIME type of FILENAME from file command. |
156 Returns nil if file command not on system." | 158 Returns nil if file command not on system." |
157 (cond | 159 (cond |
158 ((not (mh-have-file-command)) | 160 ((not (mh-have-file-command)) |
190 | 192 |
191 ("message/delivery-status") | 193 ("message/delivery-status") |
192 ("message/external-body") ("message/partial") ("message/rfc822") | 194 ("message/external-body") ("message/partial") ("message/rfc822") |
193 | 195 |
194 ("text/enriched") ("text/html") ("text/plain") ("text/rfc822-headers") | 196 ("text/enriched") ("text/html") ("text/plain") ("text/rfc822-headers") |
195 ("text/richtext") ("text/xml") | 197 ("text/richtext") ("text/x-vcard") ("text/xml") |
196 | 198 |
197 ("video/mpeg") ("video/quicktime")) | 199 ("video/mpeg") ("video/quicktime")) |
198 "Legal MIME content types. | 200 "Legal MIME content types. |
199 See documentation for \\[mh-edit-mhn].") | 201 See documentation for \\[mh-edit-mhn].") |
202 | |
203 ;; RFC 2045 - Multipurpose Internet Mail Extensions (MIME) Part One: | |
204 ;; Format of Internet Message Bodies. | |
205 ;; RFC 2046 - Multipurpose Internet Mail Extensions (MIME) Part Two: | |
206 ;; Media Types. | |
207 ;; RFC 2049 - Multipurpose Internet Mail Extensions (MIME) Part Five: | |
208 ;; Conformance Criteria and Examples. | |
209 ;; RFC 2017 - Definition of the URL MIME External-Body Access-Type | |
210 ;; RFC 1738 - Uniform Resource Locators (URL) | |
211 (defvar mh-access-types | |
212 '(("anon-ftp") ; RFC2046 Anonymous File Transfer Protocol | |
213 ("file") ; RFC1738 Host-specific file names | |
214 ("ftp") ; RFC2046 File Transfer Protocol | |
215 ("gopher") ; RFC1738 The Gopher Protocol | |
216 ("http") ; RFC1738 Hypertext Transfer Protocol | |
217 ("local-file") ; RFC2046 Local file access | |
218 ("mail-server") ; RFC2046 mail-server Electronic mail address | |
219 ("mailto") ; RFC1738 Electronic mail address | |
220 ("news") ; RFC1738 Usenet news | |
221 ("nntp") ; RFC1738 Usenet news using NNTP access | |
222 ("propspero") ; RFC1738 Prospero Directory Service | |
223 ("telnet") ; RFC1738 Telnet | |
224 ("tftp") ; RFC2046 Trivial File Transfer Protocol | |
225 ("url") ; RFC2017 URL scheme MIME access-type Protocol | |
226 ("wais")) ; RFC1738 Wide Area Information Servers | |
227 "Legal MIME access-type values.") | |
200 | 228 |
201 ;;;###mh-autoload | 229 ;;;###mh-autoload |
202 (defun mh-mhn-compose-insertion (filename type description attributes) | 230 (defun mh-mhn-compose-insertion (filename type description attributes) |
203 "Add a directive to insert a MIME message part from a file. | 231 "Add a directive to insert a MIME message part from a file. |
204 This is the typical way to insert non-text parts in a message. | 232 This is the typical way to insert non-text parts in a message. |
284 "application/octet-stream" | 312 "application/octet-stream" |
285 description | 313 description |
286 "type=tar; conversions=x-compress" | 314 "type=tar; conversions=x-compress" |
287 "mode=image")) | 315 "mode=image")) |
288 | 316 |
289 | 317 ;;;###mh-autoload |
290 (defun mh-mhn-compose-external-type (access-type host filename type | 318 (defun mh-mhn-compose-external-type (access-type host filename type |
291 &optional description | 319 &optional description |
292 attributes extra-params | 320 attributes extra-params |
293 comment) | 321 comment) |
294 "Add a directive to include a MIME reference to a remote file. | 322 "Add a directive to include a MIME reference to a remote file. |
299 file and TYPE which is the MIME Content-Type. Optional arguments include | 327 file and TYPE which is the MIME Content-Type. Optional arguments include |
300 DESCRIPTION, a line of text for the Content-description header, ATTRIBUTES, | 328 DESCRIPTION, a line of text for the Content-description header, ATTRIBUTES, |
301 EXTRA-PARAMS, and COMMENT. | 329 EXTRA-PARAMS, and COMMENT. |
302 | 330 |
303 See also \\[mh-edit-mhn]." | 331 See also \\[mh-edit-mhn]." |
332 (interactive (list | |
333 (completing-read "Access Type: " mh-access-types) | |
334 (read-string "Remote host: ") | |
335 (read-string "Remote url-path: ") | |
336 (completing-read "Content-Type: " | |
337 (if (fboundp 'mailcap-mime-types) | |
338 (mapcar 'list (mailcap-mime-types)) | |
339 mh-mime-content-types)) | |
340 (if current-prefix-arg (read-string "Content-description: ")) | |
341 (if current-prefix-arg (read-string "Attributes: ")) | |
342 (if current-prefix-arg (read-string "Extra Parameters: ")) | |
343 (if current-prefix-arg (read-string "Comment: ")))) | |
304 (beginning-of-line) | 344 (beginning-of-line) |
305 (insert "#@" type) | 345 (insert "#@" type) |
306 (and attributes | 346 (and attributes |
307 (insert "; " attributes)) | 347 (insert "; " attributes)) |
308 (and comment | 348 (and comment |
312 (insert description)) | 352 (insert description)) |
313 (insert "] ") | 353 (insert "] ") |
314 (insert "access-type=" access-type "; ") | 354 (insert "access-type=" access-type "; ") |
315 (insert "site=" host) | 355 (insert "site=" host) |
316 (insert "; name=" (file-name-nondirectory filename)) | 356 (insert "; name=" (file-name-nondirectory filename)) |
317 (insert "; directory=\"" (file-name-directory filename) "\"") | 357 (let ((directory (file-name-directory filename))) |
358 (and directory | |
359 (insert "; directory=\"" directory "\""))) | |
318 (and extra-params | 360 (and extra-params |
319 (insert "; " extra-params)) | 361 (insert "; " extra-params)) |
320 (insert "\n")) | 362 (insert "\n")) |
321 | 363 |
322 ;;;###mh-autoload | 364 ;;;###mh-autoload |
330 See also \\[mh-edit-mhn]." | 372 See also \\[mh-edit-mhn]." |
331 (interactive (list | 373 (interactive (list |
332 (read-string "Forw Content-description: ") | 374 (read-string "Forw Content-description: ") |
333 (mh-prompt-for-folder "Message from" mh-sent-from-folder nil) | 375 (mh-prompt-for-folder "Message from" mh-sent-from-folder nil) |
334 (read-string (format "Messages%s: " | 376 (read-string (format "Messages%s: " |
335 (if mh-sent-from-msg | 377 (if (numberp mh-sent-from-msg) |
336 (format " [%d]" mh-sent-from-msg) | 378 (format " [%d]" mh-sent-from-msg) |
337 ""))))) | 379 ""))))) |
338 (beginning-of-line) | 380 (beginning-of-line) |
339 (insert "#forw [") | 381 (insert "#forw [") |
340 (and description | 382 (and description |
347 (if (and messages | 389 (if (and messages |
348 (not (string= messages ""))) | 390 (not (string= messages ""))) |
349 (let ((start (point))) | 391 (let ((start (point))) |
350 (insert " " messages) | 392 (insert " " messages) |
351 (subst-char-in-region start (point) ?, ? )) | 393 (subst-char-in-region start (point) ?, ? )) |
352 (if mh-sent-from-msg | 394 (if (numberp mh-sent-from-msg) |
353 (insert " " (int-to-string mh-sent-from-msg)))) | 395 (insert " " (int-to-string mh-sent-from-msg)))) |
354 (insert "\n")) | 396 (insert "\n")) |
355 | 397 |
356 ;;;###mh-autoload | 398 ;;;###mh-autoload |
357 (defun mh-edit-mhn (&optional extra-args) | 399 (defun mh-edit-mhn (&optional extra-args) |
378 The value of `mh-edit-mhn-hook' is a list of functions to be called, with no | 420 The value of `mh-edit-mhn-hook' is a list of functions to be called, with no |
379 arguments, after performing the conversion. | 421 arguments, after performing the conversion. |
380 | 422 |
381 The mhn program is part of MH version 6.8 or later." | 423 The mhn program is part of MH version 6.8 or later." |
382 (interactive "*P") | 424 (interactive "*P") |
425 (mh-mhn-quote-unescaped-sharp) | |
383 (save-buffer) | 426 (save-buffer) |
384 (message "mhn editing...") | 427 (message "mhn editing...") |
385 (cond | 428 (cond |
386 (mh-nmh-flag | 429 ((mh-variant-p 'nmh) |
387 (mh-exec-cmd-error nil | 430 (mh-exec-cmd-error nil |
388 "mhbuild" (if extra-args mh-mhn-args) buffer-file-name)) | 431 "mhbuild" (if extra-args mh-mhn-args) buffer-file-name)) |
389 (t | 432 (t |
390 (mh-exec-cmd-error (format "mhdraft=%s" buffer-file-name) | 433 (mh-exec-cmd-error (format "mhdraft=%s" buffer-file-name) |
391 "mhn" (if extra-args mh-mhn-args) buffer-file-name))) | 434 "mhn" (if extra-args mh-mhn-args) buffer-file-name))) |
392 (revert-buffer t t) | 435 (revert-buffer t t) |
393 (message "mhn editing...done") | 436 (message "mhn editing...done") |
394 (run-hooks 'mh-edit-mhn-hook)) | 437 (run-hooks 'mh-edit-mhn-hook)) |
438 | |
439 (defun mh-mhn-quote-unescaped-sharp () | |
440 "Quote `#' characters that haven't been quoted for `mhbuild'. | |
441 If the `#' character is present in the first column, but it isn't part of a | |
442 MHN directive then `mhbuild' gives an error. This function will quote all such | |
443 characters." | |
444 (save-excursion | |
445 (goto-char (point-min)) | |
446 (while (re-search-forward "^#" nil t) | |
447 (beginning-of-line) | |
448 (unless (mh-mhn-directive-present-p (point) (line-end-position)) | |
449 (insert "#")) | |
450 (goto-char (line-end-position))))) | |
395 | 451 |
396 ;;;###mh-autoload | 452 ;;;###mh-autoload |
397 (defun mh-revert-mhn-edit (noconfirm) | 453 (defun mh-revert-mhn-edit (noconfirm) |
398 "Undo the effect of \\[mh-edit-mhn] by reverting to the backup file. | 454 "Undo the effect of \\[mh-edit-mhn] by reverting to the backup file. |
399 Optional non-nil argument NOCONFIRM means don't ask for confirmation." | 455 Optional non-nil argument NOCONFIRM means don't ask for confirmation." |
420 (erase-buffer) | 476 (erase-buffer) |
421 (insert-file-contents backup-file)) | 477 (insert-file-contents backup-file)) |
422 (after-find-file nil))) | 478 (after-find-file nil))) |
423 | 479 |
424 ;;;###mh-autoload | 480 ;;;###mh-autoload |
425 (defun mh-mhn-directive-present-p () | 481 (defun mh-mhn-directive-present-p (&optional begin end) |
426 "Check if the current buffer has text which might be a MHN directive." | 482 "Check if the text between BEGIN and END might be a MHN directive. |
483 The optional argument BEGIN defaults to the beginning of the buffer, while END | |
484 defaults to the the end of the buffer." | |
485 (unless begin (setq begin (point-min))) | |
486 (unless end (setq end (point-max))) | |
427 (save-excursion | 487 (save-excursion |
428 (block 'search-for-mhn-directive | 488 (block 'search-for-mhn-directive |
429 (goto-char (point-min)) | 489 (goto-char begin) |
430 (while (re-search-forward "^#" nil t) | 490 (while (re-search-forward "^#" end t) |
431 (let ((s (buffer-substring-no-properties (point) (line-end-position)))) | 491 (let ((s (buffer-substring-no-properties (point) (line-end-position)))) |
432 (cond ((equal s "")) | 492 (cond ((equal s "")) |
433 ((string-match "^forw[ \t\n]+" s) | 493 ((string-match "^forw[ \t\n]+" s) |
434 (return-from 'search-for-mhn-directive t)) | 494 (return-from 'search-for-mhn-directive t)) |
435 (t (let ((first-token (car (split-string s "[ \t;@]")))) | 495 (t (let ((first-token (car (split-string s "[ \t;@]")))) |
436 (when (string-match mh-media-type-regexp first-token) | 496 (when (and first-token |
497 (string-match mh-media-type-regexp | |
498 first-token)) | |
437 (return-from 'search-for-mhn-directive t))))))) | 499 (return-from 'search-for-mhn-directive t))))))) |
438 nil))) | 500 nil))) |
439 | 501 |
440 | 502 |
441 | 503 |
448 function may be called manually before sending the draft as well." | 510 function may be called manually before sending the draft as well." |
449 (interactive) | 511 (interactive) |
450 (require 'message) | 512 (require 'message) |
451 (when mh-gnus-pgp-support-flag ;; This is only needed for PGP | 513 (when mh-gnus-pgp-support-flag ;; This is only needed for PGP |
452 (message-options-set-recipient)) | 514 (message-options-set-recipient)) |
453 (mml-to-mime)) | 515 (let ((saved-text (buffer-string)) |
516 (buffer (current-buffer)) | |
517 (modified-flag (buffer-modified-p))) | |
518 (condition-case err (mml-to-mime) | |
519 (error | |
520 (with-current-buffer buffer | |
521 (delete-region (point-min) (point-max)) | |
522 (insert saved-text) | |
523 (set-buffer-modified-p modified-flag)) | |
524 (error (error-message-string err)))))) | |
454 | 525 |
455 ;;;###mh-autoload | 526 ;;;###mh-autoload |
456 (defun mh-mml-forward-message (description folder message) | 527 (defun mh-mml-forward-message (description folder message) |
457 "Forward a message as attachment. | 528 "Forward a message as attachment. |
458 The function will prompt the user for a DESCRIPTION, a FOLDER and MESSAGE | 529 The function will prompt the user for a DESCRIPTION, a FOLDER and MESSAGE |
459 number." | 530 number." |
460 (let ((msg (if (equal message "") | 531 (let ((msg (if (and (equal message "") (numberp mh-sent-from-msg)) |
461 mh-sent-from-msg | 532 mh-sent-from-msg |
462 (car (read-from-string message))))) | 533 (car (read-from-string message))))) |
463 (cond ((integerp msg) | 534 (cond ((integerp msg) |
464 (if (string= "" description) | 535 (if (string= "" description) |
465 ;; Rationale: mml-attach-file constructs a malformed composition | 536 ;; Rationale: mml-attach-file constructs a malformed composition |
470 (mml-attach-file (format "%s%s/%d" | 541 (mml-attach-file (format "%s%s/%d" |
471 mh-user-path (substring folder 1) msg) | 542 mh-user-path (substring folder 1) msg) |
472 "message/rfc822" | 543 "message/rfc822" |
473 description))) | 544 description))) |
474 (t (error "The message number, %s is not a integer!" msg))))) | 545 (t (error "The message number, %s is not a integer!" msg))))) |
546 | |
547 (defvar mh-mml-cryptographic-method-history ()) | |
548 | |
549 ;;;###mh-autoload | |
550 (defun mh-mml-query-cryptographic-method () | |
551 "Read the cryptographic method to use." | |
552 (if current-prefix-arg | |
553 (let ((def (or (car mh-mml-cryptographic-method-history) | |
554 mh-mml-method-default))) | |
555 (completing-read (format "Method: [%s] " def) | |
556 '(("pgp") ("pgpmime") ("smime")) | |
557 nil t nil 'mh-mml-cryptographic-method-history def)) | |
558 mh-mml-method-default)) | |
475 | 559 |
476 ;;;###mh-autoload | 560 ;;;###mh-autoload |
477 (defun mh-mml-attach-file (&optional disposition) | 561 (defun mh-mml-attach-file (&optional disposition) |
478 "Attach a file to the outgoing MIME message. | 562 "Attach a file to the outgoing MIME message. |
479 The file is not inserted or encoded until you send the message with | 563 The file is not inserted or encoded until you send the message with |
497 nil t nil nil | 581 nil t nil nil |
498 "attachment")))) | 582 "attachment")))) |
499 (mml-insert-empty-tag 'part 'type type 'filename file | 583 (mml-insert-empty-tag 'part 'type type 'filename file |
500 'disposition dispos 'description description))) | 584 'disposition dispos 'description description))) |
501 | 585 |
502 ;;;###mh-autoload | 586 (defvar mh-identity-pgg-default-user-id) |
503 (defun mh-mml-secure-message-sign-pgpmime () | 587 |
504 "Add directive to encrypt/sign the entire message." | 588 (defun mh-secure-message (method mode &optional identity) |
505 (interactive) | 589 "Add directive to Encrypt/Sign an entire message. |
590 METHOD should be one of: \"pgpmime\", \"pgp\", \"smime\". | |
591 MODE should be one of: \"sign\", \"encrypt\", \"signencrypt\", \"none\". | |
592 IDENTITY is optionally the default-user-id to use." | |
506 (if (not mh-gnus-pgp-support-flag) | 593 (if (not mh-gnus-pgp-support-flag) |
507 (error "Sorry. Your version of gnus does not support PGP/GPG") | 594 (error "Sorry. Your version of gnus does not support PGP/GPG") |
508 (mml-secure-message-sign-pgpmime))) | 595 ;; Check the arguments |
509 | 596 (let ((valid-methods (list "pgpmime" "pgp" "smime")) |
510 ;;;###mh-autoload | 597 (valid-modes (list "sign" "encrypt" "signencrypt" "none"))) |
511 (defun mh-mml-secure-message-encrypt-pgpmime (&optional dontsign) | 598 (if (not (member method valid-methods)) |
512 "Add directive to encrypt and sign the entire message. | 599 (error (format "Sorry. METHOD \"%s\" is invalid." method))) |
513 If called with a prefix argument DONTSIGN, only encrypt (do NOT sign)." | 600 (if (not (member mode valid-modes)) |
601 (error (format "Sorry. MODE \"%s\" is invalid" mode))) | |
602 (mml-unsecure-message) | |
603 (if (not (string= mode "none")) | |
604 (save-excursion | |
605 (goto-char (point-min)) | |
606 (mh-goto-header-end 1) | |
607 (if mh-identity-pgg-default-user-id | |
608 (mml-insert-tag 'secure 'method method 'mode mode | |
609 'sender mh-identity-pgg-default-user-id) | |
610 (mml-insert-tag 'secure 'method method 'mode mode))))))) | |
611 | |
612 ;;;###mh-autoload | |
613 (defun mh-mml-unsecure-message (&optional ignore) | |
614 "Remove any secure message directives. | |
615 The IGNORE argument is not used." | |
514 (interactive "P") | 616 (interactive "P") |
515 (if (not mh-gnus-pgp-support-flag) | 617 (if (not mh-gnus-pgp-support-flag) |
516 (error "Sorry. Your version of gnus does not support PGP/GPG") | 618 (error "Sorry. Your version of gnus does not support PGP/GPG") |
517 (mml-secure-message-encrypt-pgpmime dontsign))) | 619 (mml-unsecure-message))) |
620 | |
621 ;;;###mh-autoload | |
622 (defun mh-mml-secure-message-sign (method) | |
623 "Add security directive to sign the entire message using METHOD." | |
624 (interactive (list (mh-mml-query-cryptographic-method))) | |
625 (mh-secure-message method "sign" mh-identity-pgg-default-user-id)) | |
626 | |
627 ;;;###mh-autoload | |
628 (defun mh-mml-secure-message-encrypt (method) | |
629 "Add security directive to encrypt the entire message using METHOD." | |
630 (interactive (list (mh-mml-query-cryptographic-method))) | |
631 (mh-secure-message method "encrypt" mh-identity-pgg-default-user-id)) | |
632 | |
633 ;;;###mh-autoload | |
634 (defun mh-mml-secure-message-signencrypt (method) | |
635 "Add security directive to encrypt and sign the entire message using METHOD." | |
636 (interactive (list (mh-mml-query-cryptographic-method))) | |
637 (mh-secure-message method "signencrypt" mh-identity-pgg-default-user-id)) | |
518 | 638 |
519 ;;;###mh-autoload | 639 ;;;###mh-autoload |
520 (defun mh-mml-directive-present-p () | 640 (defun mh-mml-directive-present-p () |
521 "Check if the current buffer has text which may be an MML directive." | 641 "Check if the current buffer has text which may be an MML directive." |
522 (save-excursion | 642 (save-excursion |
665 (mh-show-buffer-message-number) | 785 (mh-show-buffer-message-number) |
666 (mh-get-msg-num t))) | 786 (mh-get-msg-num t))) |
667 (folder (if (eq major-mode 'mh-show-mode) | 787 (folder (if (eq major-mode 'mh-show-mode) |
668 mh-show-folder-buffer | 788 mh-show-folder-buffer |
669 mh-current-folder)) | 789 mh-current-folder)) |
670 (command (if mh-nmh-flag "mhstore" "mhn")) | 790 (command (if (mh-variant-p 'nmh) "mhstore" "mhn")) |
671 (directory | 791 (directory |
672 (cond | 792 (cond |
673 ((and (or arg | 793 ((and (or arg |
674 (equal nil mh-mime-save-parts-default-directory) | 794 (equal nil mh-mime-save-parts-default-directory) |
675 (equal t mh-mime-save-parts-default-directory)) | 795 (equal t mh-mime-save-parts-default-directory)) |
676 (not mh-mime-save-parts-directory)) | 796 (not mh-mime-save-parts-directory)) |
677 (read-file-name "Store in what directory? " nil nil t nil)) | 797 (read-file-name "Store in directory: " nil nil t nil)) |
678 ((and (or arg | 798 ((and (or arg |
679 (equal t mh-mime-save-parts-default-directory)) | 799 (equal t mh-mime-save-parts-default-directory)) |
680 mh-mime-save-parts-directory) | 800 mh-mime-save-parts-directory) |
681 (read-file-name (format | 801 (read-file-name (format |
682 "Store in what directory? [%s] " | 802 "Store in directory: [%s] " |
683 mh-mime-save-parts-directory) | 803 mh-mime-save-parts-directory) |
684 "" mh-mime-save-parts-directory t "")) | 804 "" mh-mime-save-parts-directory t "")) |
685 ((stringp mh-mime-save-parts-default-directory) | 805 ((stringp mh-mime-save-parts-default-directory) |
686 mh-mime-save-parts-default-directory) | 806 mh-mime-save-parts-default-directory) |
687 (t | 807 (t |
688 mh-mime-save-parts-directory)))) | 808 mh-mime-save-parts-directory)))) |
689 (if (and (equal directory "") mh-mime-save-parts-directory) | 809 (if (and (equal directory "") mh-mime-save-parts-directory) |
690 (setq directory mh-mime-save-parts-directory)) | 810 (setq directory mh-mime-save-parts-directory)) |
691 (if (not (file-directory-p directory)) | 811 (if (not (file-directory-p directory)) |
692 (message "No directory specified.") | 812 (message "No directory specified") |
693 (if (equal nil mh-mime-save-parts-default-directory) | 813 (if (equal nil mh-mime-save-parts-default-directory) |
694 (setq mh-mime-save-parts-directory directory)) | 814 (setq mh-mime-save-parts-directory directory)) |
695 (save-excursion | 815 (save-excursion |
696 (set-buffer (get-buffer-create mh-log-buffer)) | 816 (set-buffer (get-buffer-create mh-log-buffer)) |
697 (cd directory) | 817 (cd directory) |
730 (and cte (intern (downcase | 850 (and cte (intern (downcase |
731 (gnus-strip-whitespace cte)))) | 851 (gnus-strip-whitespace cte)))) |
732 (car ct)))))) | 852 (car ct)))))) |
733 | 853 |
734 ;;;###mh-autoload | 854 ;;;###mh-autoload |
855 (defun mh-toggle-mh-decode-mime-flag () | |
856 "Toggle whether MH-E should decode MIME or not." | |
857 (interactive) | |
858 (setq mh-decode-mime-flag (not mh-decode-mime-flag)) | |
859 (mh-show nil t) | |
860 (message (format "(setq mh-decode-mime-flag %s)" mh-decode-mime-flag))) | |
861 | |
862 ;;;###mh-autoload | |
735 (defun mh-decode-message-header () | 863 (defun mh-decode-message-header () |
736 "Decode RFC2047 encoded message header fields." | 864 "Decode RFC2047 encoded message header fields." |
737 (when mh-decode-mime-flag | 865 (when mh-decode-mime-flag |
738 (let ((buffer-read-only nil)) | 866 (let ((buffer-read-only nil)) |
739 (rfc2047-decode-region (point-min) (mh-mail-header-end))))) | 867 (rfc2047-decode-region (point-min) (mh-mail-header-end))))) |
764 (setf (mh-mime-handles (mh-buffer-data)) | 892 (setf (mh-mime-handles (mh-buffer-data)) |
765 (mm-merge-handles handles | 893 (mm-merge-handles handles |
766 (mh-mime-handles (mh-buffer-data)))) | 894 (mh-mime-handles (mh-buffer-data)))) |
767 (unless handles (mh-decode-message-body))) | 895 (unless handles (mh-decode-message-body))) |
768 | 896 |
769 (when (and handles | 897 (cond ((and handles |
770 (or (not (stringp (car handles))) (cdr handles))) | 898 (or (not (stringp (car handles))) (cdr handles))) |
771 ;; Goto start of message body | 899 ;; Goto start of message body |
772 (goto-char (point-min)) | 900 (goto-char (point-min)) |
773 (or (search-forward "\n\n" nil t) (goto-char (point-max))) | 901 (or (search-forward "\n\n" nil t) (goto-char (point-max))) |
774 | 902 |
775 ;; Delete the body | 903 ;; Delete the body |
776 (delete-region (point) (point-max)) | 904 (delete-region (point) (point-max)) |
777 | 905 |
778 ;; Display the MIME handles | 906 ;; Display the MIME handles |
779 (mh-mime-display-part handles))) | 907 (mh-mime-display-part handles)) |
908 (t (mh-signature-highlight)))) | |
780 (error | 909 (error |
781 (message "Please report this error. The error message is:\n %s" | 910 (message "Please report this error. The error message is:\n %s" |
782 (error-message-string err)) | 911 (error-message-string err)) |
783 (delete-region (point-min) (point-max)) | 912 (delete-region (point-min) (point-max)) |
784 (insert raw-message-data)))))) | 913 (insert raw-message-data)))))) |
872 (equal (car type) "text/x-vcard") | 1001 (equal (car type) "text/x-vcard") |
873 (save-excursion | 1002 (save-excursion |
874 (save-restriction | 1003 (save-restriction |
875 (widen) | 1004 (widen) |
876 (goto-char (point-min)) | 1005 (goto-char (point-min)) |
877 (not (re-search-forward "^-- $" nil t))))))) | 1006 (not (mh-signature-separator-p))))))) |
878 | 1007 |
879 (defun mh-mime-display-single (handle) | 1008 (defun mh-mime-display-single (handle) |
880 "Display a leaf node, HANDLE in the MIME tree." | 1009 "Display a leaf node, HANDLE in the MIME tree." |
881 (let* ((type (mm-handle-media-type handle)) | 1010 (let* ((type (mm-handle-media-type handle)) |
882 (small-image-flag (mh-small-image-p handle)) | 1011 (small-image-flag (mh-small-image-p handle)) |
902 nil) ; skip signatures as they are already handled... | 1031 nil) ; skip signatures as they are already handled... |
903 ((not displayp) | 1032 ((not displayp) |
904 (insert "\n") | 1033 (insert "\n") |
905 (mh-insert-mime-button handle (mh-mime-part-index handle) nil)) | 1034 (mh-insert-mime-button handle (mh-mime-part-index handle) nil)) |
906 ((and displayp (not mh-display-buttons-for-inline-parts-flag)) | 1035 ((and displayp (not mh-display-buttons-for-inline-parts-flag)) |
907 (or (mm-display-part handle) (mm-display-part handle))) | 1036 (or (mm-display-part handle) (mm-display-part handle)) |
1037 (mh-signature-highlight handle)) | |
908 ((and displayp mh-display-buttons-for-inline-parts-flag) | 1038 ((and displayp mh-display-buttons-for-inline-parts-flag) |
909 (insert "\n") | 1039 (insert "\n") |
910 (mh-insert-mime-button handle (mh-mime-part-index handle) nil) | 1040 (mh-insert-mime-button handle (mh-mime-part-index handle) nil) |
911 (forward-line -1) | 1041 (forward-line -1) |
912 (mh-mm-display-part handle))) | 1042 (mh-mm-display-part handle))) |
913 (goto-char (point-max))))) | 1043 (goto-char (point-max))))) |
1044 | |
1045 (defun mh-signature-highlight (&optional handle) | |
1046 "Highlight message signature in HANDLE. | |
1047 The optional argument, HANDLE is a MIME handle if the function is being used | |
1048 to highlight the signature in a MIME part." | |
1049 (let ((regexp | |
1050 (cond ((not handle) "^-- $") | |
1051 ((not (and (equal (mm-handle-media-supertype handle) "text") | |
1052 (equal (mm-handle-media-subtype handle) "html"))) | |
1053 "^-- $") | |
1054 ((eq (mh-mm-text-html-renderer) 'lynx) "^ --$") | |
1055 (t "^--$")))) | |
1056 (save-excursion | |
1057 (goto-char (point-max)) | |
1058 (when (re-search-backward regexp nil t) | |
1059 (mh-do-in-gnu-emacs | |
1060 (let ((ov (make-overlay (point) (point-max)))) | |
1061 (overlay-put ov 'face 'mh-show-signature-face) | |
1062 (overlay-put ov 'evaporate t))) | |
1063 (mh-do-in-xemacs | |
1064 (set-extent-property (make-extent (point) (point-max)) | |
1065 'face 'mh-show-signature-face)))))) | |
914 | 1066 |
915 (mh-do-in-xemacs | 1067 (mh-do-in-xemacs |
916 (defvar dots) | 1068 (defvar dots) |
917 (defvar type)) | 1069 (defvar type)) |
918 | 1070 |
952 'link begin end | 1104 'link begin end |
953 :mime-handle handle | 1105 :mime-handle handle |
954 :action 'mh-widget-press-button | 1106 :action 'mh-widget-press-button |
955 :button-keymap mh-mime-button-map | 1107 :button-keymap mh-mime-button-map |
956 :help-echo | 1108 :help-echo |
957 "Mouse-2 click or press RET (in show buffer) to toggle display"))) | 1109 "Mouse-2 click or press RET (in show buffer) to toggle display") |
1110 (dolist (ov (mh-funcall-if-exists overlays-in begin end)) | |
1111 (mh-funcall-if-exists overlay-put ov 'evaporate t)))) | |
958 | 1112 |
959 ;; There is a bug in Gnus inline image display due to which an extra line | 1113 ;; There is a bug in Gnus inline image display due to which an extra line |
960 ;; gets inserted every time it is viewed. To work around that problem we are | 1114 ;; gets inserted every time it is viewed. To work around that problem we are |
961 ;; using an extra property 'mh-region to remember the region that is added | 1115 ;; using an extra property 'mh-region to remember the region that is added |
962 ;; when the button is clicked. The region is then deleted to make sure that | 1116 ;; when the button is clicked. The region is then deleted to make sure that |
1007 (delete-char 1)) | 1161 (delete-char 1)) |
1008 (when (equal (mm-handle-media-supertype handle) "text") | 1162 (when (equal (mm-handle-media-supertype handle) "text") |
1009 (when (eq mh-highlight-citation-p 'gnus) | 1163 (when (eq mh-highlight-citation-p 'gnus) |
1010 (mh-gnus-article-highlight-citation)) | 1164 (mh-gnus-article-highlight-citation)) |
1011 (mh-display-smileys) | 1165 (mh-display-smileys) |
1012 (mh-display-emphasis)) | 1166 (mh-display-emphasis) |
1167 (mh-signature-highlight handle)) | |
1013 (setq region (cons (progn (goto-char (point-min)) | 1168 (setq region (cons (progn (goto-char (point-min)) |
1014 (point-marker)) | 1169 (point-marker)) |
1015 (progn (goto-char (point-max)) | 1170 (progn (goto-char (point-max)) |
1016 (point-marker))))))) | 1171 (point-marker))))))) |
1017 (when (window-live-p window) | 1172 (when (window-live-p window) |
1096 (mh-press-button) | 1251 (mh-press-button) |
1097 (message "MIME part already inserted"))) | 1252 (message "MIME part already inserted"))) |
1098 (goto-char point) | 1253 (goto-char point) |
1099 (set-buffer-modified-p nil))) | 1254 (set-buffer-modified-p nil))) |
1100 | 1255 |
1256 ;;;###mh-autoload | |
1257 (defun mh-display-with-external-viewer (part-index) | |
1258 "View MIME PART-INDEX externally." | |
1259 (interactive "P") | |
1260 (when (consp part-index) (setq part-index (car part-index))) | |
1261 (mh-folder-mime-action | |
1262 part-index | |
1263 #'(lambda () | |
1264 (let* ((part (get-text-property (point) 'mh-data)) | |
1265 (type (mm-handle-media-type part)) | |
1266 (methods (mapcar (lambda (x) (list (cdr (assoc 'viewer x)))) | |
1267 (mailcap-mime-info type 'all))) | |
1268 (def (caar methods)) | |
1269 (prompt (format "Viewer: %s" (if def (format "[%s] " def) ""))) | |
1270 (method (completing-read prompt methods nil nil nil nil def)) | |
1271 (folder mh-show-folder-buffer) | |
1272 (buffer-read-only nil)) | |
1273 (when (string-match "^[^% \t]+$" method) | |
1274 (setq method (concat method " %s"))) | |
1275 (flet ((mm-handle-set-external-undisplayer (handle function) | |
1276 (mh-handle-set-external-undisplayer folder handle function))) | |
1277 (unwind-protect (mm-display-external part method) | |
1278 (set-buffer-modified-p nil))))) | |
1279 nil)) | |
1280 | |
1101 (defun mh-widget-press-button (widget el) | 1281 (defun mh-widget-press-button (widget el) |
1102 "Callback for widget, WIDGET. | 1282 "Callback for widget, WIDGET. |
1103 Parameter EL is unused." | 1283 Parameter EL is unused." |
1104 (goto-char (widget-get widget :from)) | 1284 (goto-char (widget-get widget :from)) |
1105 (mh-press-button)) | 1285 (mh-press-button)) |
1106 | 1286 |
1107 (defun mh-mime-display-security (handle) | 1287 (defun mh-mime-display-security (handle) |
1108 "Display PGP encrypted/signed message, HANDLE." | 1288 "Display PGP encrypted/signed message, HANDLE." |
1109 (insert "\n") | |
1110 (save-restriction | 1289 (save-restriction |
1111 (narrow-to-region (point) (point)) | 1290 (narrow-to-region (point) (point)) |
1291 (insert "\n") | |
1112 (mh-insert-mime-security-button handle) | 1292 (mh-insert-mime-security-button handle) |
1113 (mh-mime-display-mixed (cdr handle)) | 1293 (mh-mime-display-mixed (cdr handle)) |
1114 (insert "\n") | 1294 (insert "\n") |
1115 (let ((mh-mime-security-button-line-format | 1295 (let ((mh-mime-security-button-line-format |
1116 mh-mime-security-button-end-line-format)) | 1296 mh-mime-security-button-end-line-format)) |
1117 (mh-insert-mime-security-button handle)) | 1297 (mh-insert-mime-security-button handle)) |
1118 (mm-set-handle-multipart-parameter | 1298 (mm-set-handle-multipart-parameter |
1119 handle 'mh-region | 1299 handle 'mh-region (cons (point-min-marker) (point-max-marker))))) |
1120 (cons (set-marker (make-marker) (point-min)) | |
1121 (set-marker (make-marker) (point-max)))))) | |
1122 | 1300 |
1123 ;;; I rewrote the security part because Gnus doesn't seem to ever minimize | 1301 ;;; I rewrote the security part because Gnus doesn't seem to ever minimize |
1124 ;;; the button. That is once the mime-security button is pressed there seems | 1302 ;;; the button. That is once the mime-security button is pressed there seems |
1125 ;;; to be no way of getting rid of the inserted text. | 1303 ;;; to be no way of getting rid of the inserted text. |
1126 (defun mh-mime-security-show-details (handle) | 1304 (defun mh-mime-security-show-details (handle) |
1147 (point-max))) | 1325 (point-max))) |
1148 (forward-line -1))))) | 1326 (forward-line -1))))) |
1149 | 1327 |
1150 (defun mh-mime-security-press-button (handle) | 1328 (defun mh-mime-security-press-button (handle) |
1151 "Callback from security button for part HANDLE." | 1329 "Callback from security button for part HANDLE." |
1152 (when (mm-handle-multipart-ctl-parameter handle 'gnus-info) | 1330 (if (mm-handle-multipart-ctl-parameter handle 'gnus-info) |
1153 (mh-mime-security-show-details handle))) | 1331 (mh-mime-security-show-details handle) |
1332 (let ((region (mm-handle-multipart-ctl-parameter handle 'mh-region)) | |
1333 point) | |
1334 (setq point (point)) | |
1335 (goto-char (car region)) | |
1336 (delete-region (car region) (cdr region)) | |
1337 (with-current-buffer (mm-handle-multipart-ctl-parameter handle 'buffer) | |
1338 (let* ((mm-verify-option 'known) | |
1339 (mm-decrypt-option 'known) | |
1340 (new (mm-possibly-verify-or-decrypt (cdr handle) handle))) | |
1341 (unless (eq new (cdr handle)) | |
1342 (mm-destroy-parts (cdr handle)) | |
1343 (setcdr handle new)))) | |
1344 (mh-mime-display-security handle) | |
1345 (goto-char point)))) | |
1154 | 1346 |
1155 ;; These variables should already be initialized in mm-decode.el if we have a | 1347 ;; These variables should already be initialized in mm-decode.el if we have a |
1156 ;; recent enough Gnus. The defvars are here to avoid compiler warnings. | 1348 ;; recent enough Gnus. The defvars are here to avoid compiler warnings. |
1157 (defvar mm-verify-function-alist nil) | 1349 (defvar mm-verify-function-alist nil) |
1158 (defvar mm-decrypt-function-alist nil) | 1350 (defvar mm-decrypt-function-alist nil) |
1189 (widget-convert-button 'link begin end | 1381 (widget-convert-button 'link begin end |
1190 :mime-handle handle | 1382 :mime-handle handle |
1191 :action 'mh-widget-press-button | 1383 :action 'mh-widget-press-button |
1192 :button-keymap mh-mime-security-button-map | 1384 :button-keymap mh-mime-security-button-map |
1193 :help-echo "Mouse-2 click or press RET (in show buffer) to see security details.") | 1385 :help-echo "Mouse-2 click or press RET (in show buffer) to see security details.") |
1386 (dolist (ov (mh-funcall-if-exists overlays-in begin end)) | |
1387 (mh-funcall-if-exists overlay-put ov 'evaporate t)) | |
1194 (when (equal info "Failed") | 1388 (when (equal info "Failed") |
1195 (let* ((type (if (equal (car handle) "multipart/signed") | 1389 (let* ((type (if (equal (car handle) "multipart/signed") |
1196 "verification" "decryption")) | 1390 "verification" "decryption")) |
1197 (warning (if (equal type "decryption") | 1391 (warning (if (equal type "decryption") |
1198 "(passphrase may be incorrect)" ""))) | 1392 "(passphrase may be incorrect)" ""))) |
1202 "Display message, HANDLE. | 1396 "Display message, HANDLE. |
1203 The function decodes the message and displays it. It avoids decoding the same | 1397 The function decodes the message and displays it. It avoids decoding the same |
1204 message multiple times." | 1398 message multiple times." |
1205 (let ((b (point)) | 1399 (let ((b (point)) |
1206 (clean-message-header mh-clean-message-header-flag) | 1400 (clean-message-header mh-clean-message-header-flag) |
1207 (invisible-headers mh-invisible-headers) | 1401 (invisible-headers mh-invisible-header-fields-compiled) |
1208 (visible-headers mh-visible-headers)) | 1402 (visible-headers nil)) |
1209 (save-excursion | 1403 (save-excursion |
1210 (save-restriction | 1404 (save-restriction |
1211 (narrow-to-region b b) | 1405 (narrow-to-region b b) |
1212 (mm-insert-part handle) | 1406 (mm-insert-part handle) |
1213 (mh-mime-display | 1407 (mh-mime-display |