aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lisp/mail/sendmail.el173
1 files changed, 127 insertions, 46 deletions
diff --git a/lisp/mail/sendmail.el b/lisp/mail/sendmail.el
index 8cf30f295df..af1fca1b1da 100644
--- a/lisp/mail/sendmail.el
+++ b/lisp/mail/sendmail.el
@@ -107,7 +107,7 @@ nil means let mailer mail back a message to report errors."
107 :group 'sendmail) 107 :group 'sendmail)
108 108
109;;;###autoload 109;;;###autoload
110(defcustom mail-yank-ignored-headers "^via:\\|^mail-from:\\|^origin:\\|^status:\\|^remailed\\|^received:\\|^message-id:\\|^summary-line:\\|^to:\\|^subject:\\|^in-reply-to:\\|^return-path:" "\ 110(defcustom mail-yank-ignored-headers "^via:\\|^mail-from:\\|^origin:\\|^status:\\|^remailed\\|^received:\\|^message-id:\\|^summary-line:\\|^to:\\|^subject:\\|^in-reply-to:\\|^return-path:\\|^mail-reply-to:\\|^mail-followup-to:" "\
111*Delete these headers from old message when it's inserted in a reply." 111*Delete these headers from old message when it's inserted in a reply."
112 :type 'regexp 112 :type 'regexp
113 :group 'sendmail) 113 :group 'sendmail)
@@ -213,6 +213,7 @@ text as modified.
213This is a normal hook, misnamed for historical reasons. 213This is a normal hook, misnamed for historical reasons.
214It is semi-obsolete and mail agents should no longer use it.") 214It is semi-obsolete and mail agents should no longer use it.")
215 215
216;;;###autoload
216(defcustom mail-citation-hook nil 217(defcustom mail-citation-hook nil
217 "*Hook for modifying a citation just inserted in the mail buffer. 218 "*Hook for modifying a citation just inserted in the mail buffer.
218Each hook function can find the citation between (point) and (mark t), 219Each hook function can find the citation between (point) and (mark t),
@@ -363,7 +364,7 @@ actually occur.")
363 (cite-prefix "[:alpha:]") 364 (cite-prefix "[:alpha:]")
364 (cite-suffix (concat cite-prefix "0-9_.@-`'\""))) 365 (cite-suffix (concat cite-prefix "0-9_.@-`'\"")))
365 (list '("^\\(To\\|Newsgroups\\):" . font-lock-function-name-face) 366 (list '("^\\(To\\|Newsgroups\\):" . font-lock-function-name-face)
366 '("^\\(B?CC\\|Reply-to\\):" . font-lock-keyword-face) 367 '("^\\(B?CC\\|Reply-to\\|Mail-\\(reply\\|followup\\)-to\\):" . font-lock-keyword-face)
367 '("^\\(Subject:\\)[ \t]*\\(.+\\)?" 368 '("^\\(Subject:\\)[ \t]*\\(.+\\)?"
368 (1 font-lock-comment-face) (2 font-lock-type-face nil t)) 369 (1 font-lock-comment-face) (2 font-lock-type-face nil t))
369 ;; Use EVAL to delay in case `mail-header-separator' gets changed. 370 ;; Use EVAL to delay in case `mail-header-separator' gets changed.
@@ -492,6 +493,8 @@ Here are commands that move to a header field (and create it if there isn't):
492 \\[mail-to] move to To: \\[mail-subject] move to Subject: 493 \\[mail-to] move to To: \\[mail-subject] move to Subject:
493 \\[mail-cc] move to CC: \\[mail-bcc] move to BCC: 494 \\[mail-cc] move to CC: \\[mail-bcc] move to BCC:
494 \\[mail-fcc] move to FCC: \\[mail-reply-to] move to Reply-To: 495 \\[mail-fcc] move to FCC: \\[mail-reply-to] move to Reply-To:
496 \\[mail-mail-reply-to] move to Mail-Reply-To:
497 \\[mail-mail-followup-to] move to Mail-Followup-To:
495\\[mail-text] mail-text (move to beginning of message text). 498\\[mail-text] mail-text (move to beginning of message text).
496\\[mail-signature] mail-signature (insert `mail-signature-file' file). 499\\[mail-signature] mail-signature (insert `mail-signature-file' file).
497\\[mail-yank-original] mail-yank-original (insert current message, in Rmail). 500\\[mail-yank-original] mail-yank-original (insert current message, in Rmail).
@@ -599,6 +602,7 @@ If within the headers, this makes the new lines into continuation lines."
599 ;; make sure we can fill after each address. 602 ;; make sure we can fill after each address.
600 (if (member fieldname 603 (if (member fieldname
601 '("to" "cc" "bcc" "from" "reply-to" 604 '("to" "cc" "bcc" "from" "reply-to"
605 "mail-reply-to" "mail-followup-to"
602 "resent-to" "resent-cc" "resent-bcc" 606 "resent-to" "resent-cc" "resent-bcc"
603 "resent-from" "resent-reply-to")) 607 "resent-from" "resent-reply-to"))
604 (while (search-forward "," end t) 608 (while (search-forward "," end t)
@@ -627,6 +631,8 @@ If within the headers, this makes the new lines into continuation lines."
627 (define-key mail-mode-map "\C-c\C-f\C-c" 'mail-cc) 631 (define-key mail-mode-map "\C-c\C-f\C-c" 'mail-cc)
628 (define-key mail-mode-map "\C-c\C-f\C-s" 'mail-subject) 632 (define-key mail-mode-map "\C-c\C-f\C-s" 'mail-subject)
629 (define-key mail-mode-map "\C-c\C-f\C-r" 'mail-reply-to) 633 (define-key mail-mode-map "\C-c\C-f\C-r" 'mail-reply-to)
634 (define-key mail-mode-map "\C-c\C-f\C-a" 'mail-mail-reply-to) ; author
635 (define-key mail-mode-map "\C-c\C-f\C-l" 'mail-mail-followup-to) ; list
630 (define-key mail-mode-map "\C-c\C-t" 'mail-text) 636 (define-key mail-mode-map "\C-c\C-t" 'mail-text)
631 (define-key mail-mode-map "\C-c\C-y" 'mail-yank-original) 637 (define-key mail-mode-map "\C-c\C-y" 'mail-yank-original)
632 (define-key mail-mode-map "\C-c\C-r" 'mail-yank-region) 638 (define-key mail-mode-map "\C-c\C-r" 'mail-yank-region)
@@ -674,6 +680,12 @@ If within the headers, this makes the new lines into continuation lines."
674(define-key mail-mode-map [menu-bar headers sent-via] 680(define-key mail-mode-map [menu-bar headers sent-via]
675 '("Sent Via" . mail-sent-via)) 681 '("Sent Via" . mail-sent-via))
676 682
683(define-key mail-mode-map [menu-bar headers mail-reply-to]
684 '("Mail Reply To" . mail-mail-reply-to))
685
686(define-key mail-mode-map [menu-bar headers mail-followup-to]
687 '("Mail Followup To" . mail-mail-followup-to))
688
677(define-key mail-mode-map [menu-bar headers reply-to] 689(define-key mail-mode-map [menu-bar headers reply-to]
678 '("Reply-To" . mail-reply-to)) 690 '("Reply-To" . mail-reply-to))
679 691
@@ -745,6 +757,16 @@ Prefix arg means don't delete this window."
745 :options '(flyspell-mode-off) 757 :options '(flyspell-mode-off)
746 :group 'sendmail) 758 :group 'sendmail)
747 759
760;;;###autoload
761(defcustom mail-mailing-lists nil "\
762*List of mailing list addresses the user is subscribed to.
763
764The variable is used to trigger insertion of the \"Mail-Followup-To\"
765header when sending a message to a mailing list."
766 :type '(repeat string)
767 :group 'sendmail)
768
769
748(defun mail-send () 770(defun mail-send ()
749 "Send the message in the current buffer. 771 "Send the message in the current buffer.
750If `mail-interactive' is non-nil, wait for success indication 772If `mail-interactive' is non-nil, wait for success indication
@@ -757,7 +779,45 @@ the user from the mailer."
757 (or (buffer-modified-p) 779 (or (buffer-modified-p)
758 (y-or-n-p "Message already sent; resend? "))) 780 (y-or-n-p "Message already sent; resend? ")))
759 (let ((inhibit-read-only t) 781 (let ((inhibit-read-only t)
760 (opoint (point))) 782 (opoint (point))
783 (ml (when mail-mailing-lists
784 ;; The surrounding regexp assumes the use of
785 ;; `mail-strip-quoted-names' on addresses before matching
786 ;; Cannot deal with full RFC 822 freedom, but that is
787 ;; unlikely to be problematic.
788 (concat "\\(?:[[:space:];,]\\|\\`\\)"
789 (regexp-opt mail-mailing-lists t)
790 "\\(?:[[:space:];,]\\|\\'\\)"))))
791 ;; If there are mailing lists defined
792 (when ml
793 (save-excursion
794 (let* ((to (mail-fetch-field "to" nil t))
795 (cc (mail-fetch-field "cc" nil t))
796 (new-header-values ; To: and Cc:
797 (mail-strip-quoted-names
798 (concat to (when cc (concat ", " cc))))))
799 ;; If message goes to known mailing list ...
800 (when (string-match ml new-header-values)
801 ;; Add Mail-Followup-To if none yet
802 (unless (mail-fetch-field "mail-followup-to")
803 (goto-char (mail-header-end))
804 (insert "Mail-Followup-To: "
805 (let ((l))
806 (mapc
807 ;; remove duplicates
808 '(lambda (e)
809 (unless (member e l)
810 (push e l)))
811 (split-string new-header-values ", +" t))
812 (mapconcat 'identity l ", "))
813 "\n"))
814 ;; Add Mail-Reply-To if none yet
815 (unless (mail-fetch-field "mail-reply-to")
816 (goto-char (mail-header-end))
817 (insert "Mail-Reply-To: "
818 (or (mail-fetch-field "reply-to")
819 user-mail-address)
820 "\n"))))))
761 (unless (memq mail-send-nonascii '(t mime)) 821 (unless (memq mail-send-nonascii '(t mime))
762 (goto-char (point-min)) 822 (goto-char (point-min))
763 (skip-chars-forward "\0-\177") 823 (skip-chars-forward "\0-\177")
@@ -833,7 +893,7 @@ external program defined by `sendmail-program'."
833 (multibyte enable-multibyte-characters) 893 (multibyte enable-multibyte-characters)
834 (case-fold-search nil) 894 (case-fold-search nil)
835 (selected-coding (select-message-coding-system)) 895 (selected-coding (select-message-coding-system))
836;;; resend-to-addresses 896 resend-to-addresses
837 delimline 897 delimline
838 fcc-was-found 898 fcc-was-found
839 (mailbuf (current-buffer)) 899 (mailbuf (current-buffer))
@@ -869,39 +929,42 @@ external program defined by `sendmail-program'."
869 (< (point) delimline)) 929 (< (point) delimline))
870 (replace-match "\n")) 930 (replace-match "\n"))
871 (goto-char (point-min)) 931 (goto-char (point-min))
932 ;; Look for Resent- headers. They require sending
933 ;; the message specially.
872 (let ((case-fold-search t)) 934 (let ((case-fold-search t))
873;;; (goto-char (point-min)) 935 (goto-char (point-min))
874;;; (while (re-search-forward "^Resent-\\(to\\|cc\\|bcc\\):" delimline t) 936 (while (re-search-forward "^Resent-\\(to\\|cc\\|bcc\\):" delimline t)
875;;; (setq resend-to-addresses 937 ;; Put a list of such addresses in resend-to-addresses.
876;;; (save-restriction 938 (setq resend-to-addresses
877;;; (narrow-to-region (point) 939 (save-restriction
878;;; (save-excursion 940 (narrow-to-region (point)
879;;; (forward-line 1) 941 (save-excursion
880;;; (while (looking-at "^[ \t]") 942 (forward-line 1)
881;;; (forward-line 1)) 943 (while (looking-at "^[ \t]")
882;;; (point))) 944 (forward-line 1))
883;;; (append (mail-parse-comma-list) 945 (point)))
884;;; resend-to-addresses))) 946 (append (mail-parse-comma-list)
885;;; ;; Delete Resent-BCC ourselves 947 resend-to-addresses)))
886;;; (if (save-excursion (beginning-of-line) 948 ;; Delete Resent-BCC ourselves
887;;; (looking-at "resent-bcc")) 949 (if (save-excursion (beginning-of-line)
888;;; (delete-region (save-excursion (beginning-of-line) (point)) 950 (looking-at "resent-bcc"))
889;;; (save-excursion (end-of-line) (1+ (point)))))) 951 (delete-region (save-excursion (beginning-of-line) (point))
890;;; Apparently this causes a duplicate Sender. 952 (save-excursion (end-of-line) (1+ (point))))))
891;;; ;; If the From is different than current user, insert Sender. 953;;; Apparently this causes a duplicate Sender.
892;;; (goto-char (point-min)) 954;;; ;; If the From is different than current user, insert Sender.
893;;; (and (re-search-forward "^From:" delimline t) 955;;; (goto-char (point-min))
894;;; (progn 956;;; (and (re-search-forward "^From:" delimline t)
895;;; (require 'mail-utils) 957;;; (progn
896;;; (not (string-equal 958;;; (require 'mail-utils)
897;;; (mail-strip-quoted-names 959;;; (not (string-equal
898;;; (save-restriction 960;;; (mail-strip-quoted-names
899;;; (narrow-to-region (point-min) delimline) 961;;; (save-restriction
900;;; (mail-fetch-field "From"))) 962;;; (narrow-to-region (point-min) delimline)
901;;; (user-login-name)))) 963;;; (mail-fetch-field "From")))
902;;; (progn 964;;; (user-login-name))))
903;;; (forward-line 1) 965;;; (progn
904;;; (insert "Sender: " (user-login-name) "\n"))) 966;;; (forward-line 1)
967;;; (insert "Sender: " (user-login-name) "\n")))
905 ;; Don't send out a blank subject line 968 ;; Don't send out a blank subject line
906 (goto-char (point-min)) 969 (goto-char (point-min))
907 (if (re-search-forward "^Subject:\\([ \t]*\n\\)+\\b" delimline t) 970 (if (re-search-forward "^Subject:\\([ \t]*\n\\)+\\b" delimline t)
@@ -1000,9 +1063,9 @@ external program defined by `sendmail-program'."
1000 (erase-buffer)))) 1063 (erase-buffer))))
1001 (goto-char (point-min)) 1064 (goto-char (point-min))
1002 (if (let ((case-fold-search t)) 1065 (if (let ((case-fold-search t))
1003 (re-search-forward "^To:\\|^cc:\\|^bcc:\\|^resent-to:\ 1066 (or resend-to-addresses
1004\\|^resent-cc:\\|^resent-bcc:" 1067 (re-search-forward "^To:\\|^cc:\\|^bcc:"
1005 delimline t)) 1068 delimline t)))
1006 (let* ((default-directory "/") 1069 (let* ((default-directory "/")
1007 (coding-system-for-write selected-coding) 1070 (coding-system-for-write selected-coding)
1008 (args 1071 (args
@@ -1023,14 +1086,14 @@ external program defined by `sendmail-program'."
1023 ;; These mean "report errors by mail" 1086 ;; These mean "report errors by mail"
1024 ;; and "deliver in background". 1087 ;; and "deliver in background".
1025 '("-oem" "-odb")) 1088 '("-oem" "-odb"))
1026;;; ;; Get the addresses from the message 1089 ;; Get the addresses from the message
1027;;; ;; unless this is a resend. 1090 ;; unless this is a resend.
1028;;; ;; We must not do that for a resend 1091 ;; We must not do that for a resend
1029;;; ;; because we would find the original addresses. 1092 ;; because we would find the original addresses.
1030;;; ;; For a resend, include the specific addresses. 1093 ;; For a resend, include the specific addresses.
1031;;; (or resend-to-addresses 1094 (or resend-to-addresses
1032 '("-t") 1095 '("-t")
1033;;; ) 1096 )
1034 (if mail-use-dsn 1097 (if mail-use-dsn
1035 (list "-N" (mapconcat 'symbol-name 1098 (list "-N" (mapconcat 'symbol-name
1036 mail-use-dsn ","))) 1099 mail-use-dsn ",")))
@@ -1249,6 +1312,24 @@ external program defined by `sendmail-program'."
1249 (expand-abbrev) 1312 (expand-abbrev)
1250 (mail-position-on-field "Reply-To")) 1313 (mail-position-on-field "Reply-To"))
1251 1314
1315(defun mail-mail-reply-to ()
1316 "Move point to end of Mail-Reply-To field.
1317Create a Mail-Reply-To field if none."
1318 (interactive)
1319 (expand-abbrev)
1320 (or (mail-position-on-field "mail-reply-to" t)
1321 (progn (mail-position-on-field "to")
1322 (insert "\nMail-Reply-To: "))))
1323
1324(defun mail-mail-followup-to ()
1325 "Move point to end of Mail-Followup-To field.
1326Create a Mail-Followup-To field if none."
1327 (interactive)
1328 (expand-abbrev)
1329 (or (mail-position-on-field "mail-followup-to" t)
1330 (progn (mail-position-on-field "to")
1331 (insert "\nMail-Followup-To: "))))
1332
1252(defun mail-position-on-field (field &optional soft) 1333(defun mail-position-on-field (field &optional soft)
1253 (let (end 1334 (let (end
1254 (case-fold-search t)) 1335 (case-fold-search t))