;;; 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
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))
+ (goto-char (point-min))
+ (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))
(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
;;; (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)