;;; sendmail.el --- mail sending commands for Emacs.
-;; Copyright (C) 1985, 1986, 1992 Free Software Foundation, Inc.
+;; Copyright (C) 1985, 1986, 1992, 1993, 1994 Free Software Foundation, Inc.
;; Maintainer: FSF
;; Keywords: mail
*Name of file to write all outgoing messages in, or nil for none.
Do not use an rmail file here! Instead, use its inbox file.")
+;;;###autoload
(defvar mail-default-reply-to nil
"*Address to insert as default Reply-to field of outgoing messages.")
+;;;###autoload
(defvar mail-alias-file nil
"*If non-nil, the name of a file to use instead of `/usr/lib/aliases'.
This file defines aliases to be expanded by the mailer; this is a different
(defvar mail-indentation-spaces 3
"*Number of spaces to insert at the beginning of each cited line.
Used by `mail-yank-original' via `mail-yank-cite'.")
-(defvar mail-yank-hooks '(mail-indent-citation)
+(defvar mail-yank-hooks nil
"Obsolete hook for modifying a citation just inserted in the mail buffer.
Each hook function can find the citation between (point) and (mark t).
And each hook function should leave point and mark around the citation
It is inserted before you edit the message,
so you can edit or delete these lines.")
+;; Note: could use /usr/ucb/mail instead of sendmail;
+;; options -t, and -v if not interactive.
+(defvar mail-mailer-swallows-blank-line
+ (if (and (string-match "sparc-sun-sunos\\(\\'\\|[^5]\\)" system-configuration)
+ (file-readable-p "/etc/sendmail.cf")
+ (let ((buffer (get-buffer-create " *temp*")))
+ (unwind-protect
+ (save-excursion
+ (set-buffer buffer)
+ (insert-file-contents "/etc/sendmail.cf")
+ (goto-char (point-min))
+ (let ((case-fold-search nil))
+ (re-search-forward "^OR\\>" nil t)))
+ (kill-buffer buffer))))
+ '(looking-at "[ \t]\\|[-a-zA-Z]+:"))
+ "Set this non-nil if the system's mailer runs the header and body together.
+\(This problem exists on Sunos 4 when sendmail is run in remote mode.)
+The value should be an expression to test whether the problem will
+actually occur.")
+
(defvar mail-mode-syntax-table nil
"Syntax table used while in mail mode.")
(setq mail-mode-syntax-table (copy-syntax-table text-mode-syntax-table))
(modify-syntax-entry ?% ". " mail-mode-syntax-table)))
+(defvar mail-send-hook nil
+ "Normal hook run before sending mail, in Mail mode.")
+
(defun mail-setup (to subject in-reply-to cc replybuffer actions)
(if (eq mail-aliases t)
(progn
(if to (setq to (point)))
(cond ((eq mail-signature t)
(if (file-exists-p "~/.signature")
- (insert-file-contents "~/.signature")))
+ (progn
+ (insert "\n\n-- \n")
+ (insert-file-contents "~/.signature"))))
(mail-signature
(insert mail-signature)))
(goto-char (point-max))
C-c C-f move to a header field (and create it if there isn't):
C-c C-f C-t move to To: C-c C-f C-s move to Subj:
C-c C-f C-b move to BCC: C-c C-f C-c move to CC:
+ C-c C-f C-f move to FCC:
C-c C-t move to message text.
C-c C-y mail-yank-original (insert current message, in Rmail).
C-c C-q mail-fill-yanked-message (fill what was yanked).
(cdr (assq 'dedicated (frame-parameters)))
(not (null (delq (selected-frame) (visible-frame-list)))))
(delete-frame (selected-frame))
- (if (and (not arg)
- (not (one-window-p))
- (save-excursion
- (set-buffer (window-buffer (next-window (selected-window) 'not)))
- (eq major-mode 'rmail-mode)))
- (delete-window)
- (switch-to-buffer newbuf)))))
+ (let (rmail-flag summary-buffer)
+ (and (not arg)
+ (not (one-window-p))
+ (save-excursion
+ (set-buffer (window-buffer (next-window (selected-window) 'not)))
+ (setq rmail-flag (eq major-mode 'rmail-mode))
+ (setq summary-buffer
+ (and (boundp 'rmail-summary-buffer)
+ rmail-summary-buffer
+ (buffer-name rmail-summary-buffer)
+ (not (get-buffer-window rmail-summary-buffer))
+ rmail-summary-buffer))))
+ (if rmail-flag
+ ;; If the Rmail buffer has a summary, show that.
+ (if summary-buffer (switch-to-buffer summary-buffer)
+ (delete-window))
+ (switch-to-buffer newbuf))))))
(defun mail-send ()
"Send the message in the current buffer.
(or (buffer-modified-p)
(y-or-n-p "Message already sent; resend? ")))
(progn
- (message "Sending...")
(run-hooks 'mail-send-hook)
+ (message "Sending...")
(funcall send-mail-function)
;; Now perform actions on successful sending.
(while mail-send-actions
0))
(tembuf (generate-new-buffer " sendmail temp"))
(case-fold-search nil)
+ resend-to-addresses
delimline
(mailbuf (current-buffer)))
(unwind-protect
(replace-match "\n"))
(let ((case-fold-search t))
(goto-char (point-min))
- (if (re-search-forward "^Sender:" delimline t)
- (error "Sender may not be specified."))
;; Find and handle any FCC fields.
(goto-char (point-min))
(if (re-search-forward "^FCC:" delimline t)
(mail-do-fcc delimline))
- ;; If the From is different than current user, insert Sender.
(goto-char (point-min))
- (and (re-search-forward "^From:" delimline t)
- (progn
- (require 'mail-utils)
- (not (string-equal
- (mail-strip-quoted-names
- (save-restriction
- (narrow-to-region (point-min) delimline)
- (mail-fetch-field "From")))
- (user-login-name))))
- (progn
- (forward-line 1)
- (insert "Sender: " (user-login-name) "\n")))
+ (require 'mail-utils)
+ (while (re-search-forward "^Resent-to:" delimline t)
+ (setq resend-to-addresses
+ (save-restriction
+ (narrow-to-region (point)
+ (save-excursion
+ (end-of-line)
+ (point)))
+ (append (mail-parse-comma-list)
+ resend-to-addresses))))
+;;; Apparently this causes a duplicate Sender.
+;;; ;; If the From is different than current user, insert Sender.
+;;; (goto-char (point-min))
+;;; (and (re-search-forward "^From:" delimline t)
+;;; (progn
+;;; (require 'mail-utils)
+;;; (not (string-equal
+;;; (mail-strip-quoted-names
+;;; (save-restriction
+;;; (narrow-to-region (point-min) delimline)
+;;; (mail-fetch-field "From")))
+;;; (user-login-name))))
+;;; (progn
+;;; (forward-line 1)
+;;; (insert "Sender: " (user-login-name) "\n")))
;; "S:" is an abbreviation for "Subject:".
(goto-char (point-min))
(if (re-search-forward "^S:" delimline t)
(goto-char (point-min))
(if (re-search-forward "^Subject:[ \t]*\n" delimline t)
(replace-match ""))
+ ;; Insert an extra newline if we need it to work around
+ ;; Sun's bug that swallows newlines.
+ (goto-char (1+ delimline))
+ (if (eval mail-mailer-swallows-blank-line)
+ (newline))
(if mail-interactive
(save-excursion
(set-buffer errbuf)
(if (boundp 'sendmail-program)
sendmail-program
"/usr/lib/sendmail")
- nil errbuf nil
- "-oi" "-t")
+ nil errbuf nil "-oi")
;; Always specify who from,
;; since some systems have broken sendmails.
(list "-f" (user-login-name))
(list (concat "-oA" mail-alias-file)))
;; These mean "report errors by mail"
;; and "deliver in background".
- (if (null mail-interactive) '("-oem" "-odb"))))
+ (if (null mail-interactive) '("-oem" "-odb"))
+ ;; Get the addresses from the message
+ ;; unless this is a resend.
+ ;; We must not do that for a resend
+ ;; because we would find the original addresses.
+ ;; For a resend, include the specific addresses.
+ (or resend-to-addresses
+ '("-t"))))
(if mail-interactive
(save-excursion
(set-buffer errbuf)
(if max (narrow-to-region (point-min) max))))))
;; Else append to the file directly.
(write-region
- ;; Include a blank line before if file already exists.
-
- (if (file-exists-p (car fcc-list)) (point-min) (1+ (point-min)))
- (point-max) (car fcc-list) t)))
+ (1+ (point-min)) (point-max) (car fcc-list) t)))
(setq fcc-list (cdr fcc-list))))
(kill-buffer tembuf)))
(progn (mail-position-on-field "to")
(insert "\nBCC: "))))
-(defun mail-fcc ()
+(defun mail-fcc (folder)
"Add a new FCC field, with file name completion."
- (interactive)
+ (interactive "FFolder carbon copy: ")
(expand-abbrev)
(or (mail-position-on-field "fcc" t) ;Put new field after exiting FCC.
(mail-position-on-field "to"))
- (insert "\nFCC: " (read-file-name "Folder carbon copy: ")))
+ (insert "\nFCC: " folder))
(defun mail-position-on-field (field &optional soft)
(let (end
(search-forward (concat "\n" mail-header-separator "\n")))
\f
(defun mail-signature (atpoint)
- "Sign letter with contents of `mail-signature-file'."
+ "Sign letter with contents of the file `~/.signature'.
+Prefix arg means put contents at point."
(interactive "P")
(save-excursion
(or atpoint
(end-of-line)
(or atpoint
(delete-region (point) (point-max)))
- (insert "\n\n")
+ (insert "\n\n-- \n")
(insert-file-contents (expand-file-name "~/.signature"))))
(defun mail-fill-yanked-message (&optional justifyp)
(interactive "P")
(if mail-reply-buffer
(let ((start (point)))
- (delete-windows-on mail-reply-buffer)
+ ;; If the original message is in another window in the same frame,
+ ;; delete that window to save screen space.
+ ;; t means don't alter other frames.
+ (delete-windows-on mail-reply-buffer t)
(insert-buffer mail-reply-buffer)
(if (consp arg)
nil
mail-indentation-spaces)))
(if mail-citation-hook
(run-hooks 'mail-citation-hook)
- (run-hooks 'mail-yank-hooks))))
+ (if mail-yank-hooks
+ (run-hooks 'mail-yank-hooks)
+ (mail-indent-citation)))))
;; This is like exchange-point-and-mark, but doesn't activate the mark.
;; It is cleaner to avoid activation, even though the command
;; loop would deactivate the mark because we inserted text.
;;; (message "Auto save file for draft message exists; consider M-x mail-recover"))
;;; t))
(switch-to-buffer "*mail*")
- (setq default-directory (expand-file-name "~/"))
+ (if (file-exists-p (expand-file-name "~/"))
+ (setq default-directory (expand-file-name "~/")))
(auto-save-mode auto-save-default)
(mail-mode)
+ ;; Disconnect the buffer from its visited file
+ ;; (in case the user has actually visited a file *mail*).
+; (set-visited-file-name nil)
(let (initialized)
(and (not noerase)
(or (not (buffer-modified-p))
(let ((buffer-read-only nil))
(erase-buffer)
(insert-file-contents file-name nil)))
- (t (error "mail-recover cancelled.")))))
+ (t (error "mail-recover cancelled")))))
;;;###autoload
(defun mail-other-window (&optional noerase to subject in-reply-to cc replybuffer sendactions)
(pop-to-buffer "*mail*"))
(mail noerase to subject in-reply-to cc replybuffer sendactions))
-
-;;;###autoload
-(define-key ctl-x-map "m" 'mail)
-
-;;;###autoload
-(define-key ctl-x-4-map "m" 'mail-other-window)
-
-;;;###autoload
-(define-key ctl-x-5-map "m" 'mail-other-frame)
-
+;;; Do not execute these when sendmail.el is loaded,
+;;; only in loaddefs.el.
+;;;###autoload (define-key ctl-x-map "m" 'mail)
+;;;###autoload (define-key ctl-x-4-map "m" 'mail-other-window)
+;;;###autoload (define-key ctl-x-5-map "m" 'mail-other-frame)
;;; Do not add anything but external entries on this page.