comparison lisp/modes/sendmail.el @ 0:376386a54a3c r19-14

Import from CVS: tag r19-14
author cvs
date Mon, 13 Aug 2007 08:45:50 +0200
parents
children 0293115a14e9
comparison
equal deleted inserted replaced
-1:000000000000 0:376386a54a3c
1 ;;; sendmail.el --- mail sending commands for Emacs.
2
3 ;; Copyright (C) 1985, 1986, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
4
5 ;; Maintainer: FSF
6 ;; Keywords: mail
7
8 ;; This file is part of XEmacs.
9
10 ;; XEmacs is free software; you can redistribute it and/or modify it
11 ;; under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14
15 ;; XEmacs is distributed in the hope that it will be useful, but
16 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 ;; General Public License for more details.
19
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with XEmacs; see the file COPYING. If not, write to the Free
22 ;; Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23
24 ;;; Synched up with: FSF 19.30.
25
26 ;;; Commentary:
27
28 ;; This mode provides mail-sending facilities from within Emacs. It is
29 ;; documented in the Emacs user's manual.
30
31 ;;; Code:
32
33 ;;;###autoload
34 (defvar mail-from-style 'angles "\
35 *Specifies how \"From:\" fields look.
36
37 If `nil', they contain just the return address like:
38 king@grassland.com
39 If `parens', they look like:
40 king@grassland.com (Elvis Parsley)
41 If `angles', they look like:
42 Elvis Parsley <king@grassland.com>")
43
44 ;;;###autoload
45 (defvar mail-self-blind nil "\
46 Non-nil means insert BCC to self in messages to be sent.
47 This is done when the message is initialized,
48 so you can remove or alter the BCC field to override the default.")
49
50 ;;;###autoload
51 (defvar mail-interactive nil "\
52 Non-nil means when sending a message wait for and display errors.
53 nil means let mailer mail back a message to report errors.")
54
55 ;;;###autoload
56 (defvar mail-dir nil "*Default directory for saving messages.")
57
58 ;;; XEmacs change: moved rmail-ignored-headers here from rmail.el so that
59 ;;; the value of mail-yank-ignored-headers can default from it. Both of
60 ;;; these end up in loaddefs.el, but "sendmail" comes before "rmail", so...
61 ;;;
62 ;;;###autoload
63 (defvar rmail-ignored-headers
64 (purecopy
65 (concat
66 "^\\("
67 (mapconcat
68 'identity
69 '(;; RFC822
70 "Sender:" "References:" "Return-Path:" "Received:"
71 "[^: \t\n]*Message-ID:" "Errors-To:"
72 ;; RFC977 (NNTP)
73 "Path:" "Expires:" "Xref:" "Lines:" "Approved:" "Distribution:"
74 ;; SYSV mail:
75 "Content-Length:"
76 ;; MIME:
77 "Mime-Version:" "Content-Type:" "Content-Transfer-Encoding:"
78 ;; X400
79 "X400-Received:" "X400-Originator:" "X400-Mts-Identifier:"
80 "X400-Content-Type:" "Content-Identifier:"
81 ;; RMAIL and /usr/ucb/mail:
82 "Status:" "Summary-Line:"
83 ;; Supercite:
84 "X-Attribution:"
85 ;; Other random junk occasionally seen:
86 "Via:" "Sent-Via:" "Mail-From:" "Origin:" "Comments:" "Originator:"
87 "NF-ID:" "NF-From:" "Posting-Version:" "Posted:" "Posted-Date:"
88 "Date-Received:" "Relay-Version:" "Article-I\\.D\\.:" "NNTP-Version:"
89 "NNTP-Posting-Host:" "X-Mailer:" "X-Newsreader:" "News-Software:"
90 "X-Received:" "X-References:" "X-Envelope-To:"
91 "X-VMS-" "Remailed-" "X-Plantation:" "X-Windows:" "X-Pgp-"
92 )
93 "\\|")
94 "\\)"))
95 "*Gubbish header fields one would rather not see.")
96
97
98 ;;;###autoload
99 (defvar mail-yank-ignored-headers
100 (purecopy
101 (concat rmail-ignored-headers "\\|"
102 "^\\("
103 (mapconcat 'identity
104 '(;; RFC822
105 "Resent-To:" "Resent-By:" "Resent-CC:"
106 "To:" "Subject:" "In-Reply-To:"
107 )
108 "\\|")
109 "\\)"))
110 "Delete these headers from old message when it's inserted in a reply.")
111 ;; minimalist FSF version
112 ;(defvar mail-yank-ignored-headers "^via:\\|^mail-from:\\|^origin:\\|^status:\\|^remailed\\|^received:\\|^message-id:\\|^summary-line:\\|^to:\\|^subject:\\|^in-reply-to:\\|^return-path:" "\
113 ;Delete these headers from old message when it's inserted in a reply.")
114
115 ;; Useful to set in site-init.el
116 ;;;###autoload
117 (defvar send-mail-function 'sendmail-send-it "\
118 Function to call to send the current buffer as mail.
119 The headers should be delimited by a line whose contents
120 match the variable `mail-header-separator'.")
121
122 ;;;###autoload
123 (defvar mail-header-separator (purecopy "--text follows this line--") "\
124 *Line used to separate headers from text in messages being composed.")
125
126 ;;;###autoload
127 (defvar mail-archive-file-name nil "\
128 *Name of file to write all outgoing messages in, or nil for none.
129 This can be an inbox file or an Rmail file.")
130
131 ;;;###autoload
132 (defvar mail-default-reply-to nil
133 "*Address to insert as default Reply-to field of outgoing messages.
134 If nil, it will be initialized from the REPLYTO environment variable
135 when you first send mail.")
136
137 ;;;###autoload
138 (defvar mail-alias-file nil
139 "*If non-nil, the name of a file to use instead of `/usr/lib/aliases'.
140 This file defines aliases to be expanded by the mailer; this is a different
141 feature from that of defining aliases in `.mailrc' to be expanded in Emacs.
142 This variable has no effect unless your system uses sendmail as its mailer.")
143
144 ;(defvar mail-personal-alias-file "~/.mailrc"
145 ; "*If non-nil, the name of the user's personal mail alias file.
146 ;This file typically should be in same format as the `.mailrc' file used by
147 ;the `Mail' or `mailx' program.
148 ;This file need not actually exist.")
149 (defvaralias 'mail-personal-alias-file 'mail-abbrev-mailrc-file)
150
151 (defvar mail-setup-hook nil
152 "Normal hook, run each time a new outgoing mail message is initialized.
153 The function `mail-setup' runs this hook.")
154
155 ; These are removed. See `mail-abbrevs.el'.
156
157 ;(defvar mail-aliases t
158 ; "Alist of mail address aliases,
159 ;or t meaning should be initialized from your mail aliases file.
160 ;\(The file's name is normally `~/.mailrc', but your MAILRC environment
161 ;variable can override that name.)
162 ;The alias definitions in the file have this form:
163 ; alias ALIAS MEANING")
164 ;
165 ;(defvar mail-alias-modtime nil
166 ; "The modification time of your mail alias file when it was last examined.")
167
168 ;;;###autoload
169 (defvar mail-yank-prefix "> " ; XEmacs change
170 "*Prefix insert on lines of yanked message being replied to.
171 nil means use indentation.")
172
173 (defvar mail-indentation-spaces 3
174 "*Number of spaces to insert at the beginning of each cited line.
175 Used by `mail-yank-original' via `mail-indent-citation'.")
176
177 (defvar mail-yank-hooks nil
178 "Obsolete hook for modifying a citation just inserted in the mail buffer.
179 Each hook function can find the citation between (point) and (mark t).
180 And each hook function should leave point and mark around the citation
181 text as modified.
182
183 This is a normal hook, misnamed for historical reasons.
184 It is semi-obsolete and mail agents should no longer use it.")
185
186 (defvar mail-citation-hook nil
187 "*Hook for modifying a citation just inserted in the mail buffer.
188 Each hook function can find the citation between (point) and (mark t).
189 And each hook function should leave point and mark around the citation
190 text as modified.
191
192 If this hook is entirely empty (nil), a default action is taken
193 instead of no action.")
194
195 (defvar mail-abbrevs-loaded nil)
196 (defvar mail-mode-map nil)
197
198 ; Removed autoloads of `build-mail-aliases' and `expand-mail-aliases'.
199 ; See `mail-abbrevs.el'.
200
201 (autoload 'mail-aliases-setup "mail-abbrevs")
202
203 ;;;###autoload
204 (defvar mail-signature nil
205 "*Text inserted at end of mail buffer when a message is initialized.
206 If t, it means to insert the contents of the file `mail-signature-file'.")
207
208 (defvar mail-signature-file "~/.signature"
209 "*File containing the text inserted at end of mail buffer.")
210
211 (defvar mail-reply-buffer nil)
212 (defvar mail-send-actions nil
213 "A list of actions to be performed upon successful sending of a message.")
214
215 (defvar mail-default-headers nil
216 "*A string containing header lines, to be inserted in outgoing messages.
217 It is inserted before you edit the message,
218 so you can edit or delete these lines.")
219
220 (defvar mail-bury-selects-summary t
221 "*If non-nil, try to show RMAIL summary buffer after returning from mail.
222 The functions \\[mail-send-on-exit] or \\[mail-dont-send] select
223 the RMAIL summary buffer before returning, if it exists and this variable
224 is non-nil.")
225
226 ;; Note: could use /usr/ucb/mail instead of sendmail;
227 ;; options -t, and -v if not interactive.
228 (defvar mail-mailer-swallows-blank-line
229 (if (and (string-match "sparc-sun-sunos\\(\\'\\|[^5]\\)" system-configuration)
230 (file-readable-p "/etc/sendmail.cf")
231 (let ((buffer (get-buffer-create " *temp*")))
232 (unwind-protect
233 (save-excursion
234 (set-buffer buffer)
235 (insert-file-contents "/etc/sendmail.cf")
236 (goto-char (point-min))
237 (let ((case-fold-search nil))
238 (re-search-forward "^OR\\>" nil t)))
239 (kill-buffer buffer))))
240 ;; According to RFC822, "The field-name must be composed of printable
241 ;; ASCII characters (i.e. characters that have decimal values between
242 ;; 33 and 126, except colon)", i.e. any chars except ctl chars,
243 ;; space, or colon.
244 '(looking-at "[ \t]\\|[][!\"#$%&'()*+,-./0-9;<=>?@A-Z\\\\^_`a-z{|}~]+:"))
245 "Set this non-nil if the system's mailer runs the header and body together.
246 \(This problem exists on Sunos 4 when sendmail is run in remote mode.)
247 The value should be an expression to test whether the problem will
248 actually occur.")
249
250 (defvar mail-use-multiple-buffers-p t
251 "Non-nil means `mail' will create a new buffer if one already exists.")
252
253 (defvar mail-mode-syntax-table nil
254 "Syntax table used while in mail mode.")
255
256 (if (not mail-mode-syntax-table)
257 (progn
258 (setq mail-mode-syntax-table (copy-syntax-table text-mode-syntax-table))
259 (modify-syntax-entry ?% ". " mail-mode-syntax-table)))
260
261 (defvar mail-font-lock-keywords
262 (let* ((cite-prefix "A-Za-z") (cite-suffix (concat cite-prefix "0-9_.@-")))
263 (list '("^To:" . font-lock-function-name-face)
264 '("^B?CC:\\|^Reply-To:" . font-lock-keyword-face)
265 '("^\\(Subject:\\)[ \t]*\\(.+\\)?"
266 (1 font-lock-comment-face) (2 font-lock-type-face nil t))
267 (list (concat "^\\(" (regexp-quote mail-header-separator) "\\)$")
268 1 'font-lock-comment-face)
269 (cons (concat "^[ \t]*"
270 "\\([" cite-prefix "]+[" cite-suffix "]*\\)?"
271 "[>|}].*")
272 'font-lock-reference-face)
273 '("^\\(X-[A-Za-z0-9-]+\\|In-reply-to\\):.*"
274 . font-lock-string-face)))
275 "Additional expressions to highlight in Mail mode.")
276 (put 'mail-mode 'font-lock-defaults '(mail-font-lock-keywords t))
277
278 (defvar mail-send-hook nil
279 "Normal hook run before sending mail, in Mail mode.")
280
281 ; Removed. See above and `mail-abbrevs.el'.
282 ;(defun sendmail-synch-aliases ()
283 ; (let ((modtime (nth 5 (file-attributes mail-personal-alias-file))))
284 ; (or (equal mail-alias-modtime modtime)
285 ; (setq mail-alias-modtime modtime
286 ; mail-aliases t))))
287
288 (defun mail-setup (to subject in-reply-to cc replybuffer actions)
289 (or mail-default-reply-to
290 (setq mail-default-reply-to (getenv "REPLYTO")))
291 ;Removed. See `mail-abbrevs.el'.
292 ; (sendmail-synch-aliases)
293 ; (if (eq mail-aliases t)
294 ; (progn
295 ; (setq mail-aliases nil)
296 ; (if (file-exists-p mail-personal-alias-file)
297 ; (build-mail-aliases))))
298 (setq mail-send-actions actions)
299 (mail-aliases-setup)
300 (setq mail-reply-buffer replybuffer)
301 (goto-char (point-min))
302 (insert "To: ")
303 (save-excursion
304 (if to
305 ;; Here removed code to extract names from within <...>
306 ;; on the assumption that mail-strip-quoted-names
307 ;; has been called and has done so.
308 (let ((fill-prefix "\t")
309 (address-start (point)))
310 (insert to "\n")
311 (fill-region-as-paragraph address-start (point-max)))
312 (newline))
313 (if cc
314 (let ((fill-prefix "\t")
315 (address-start (progn (insert "CC: ") (point))))
316 (insert cc "\n")
317 (fill-region-as-paragraph address-start (point-max))))
318 (if in-reply-to
319 (let ((fill-prefix "\t")
320 (fill-column 78)
321 (address-start (point)))
322 (insert "In-reply-to: " in-reply-to "\n")
323 (fill-region-as-paragraph address-start (point-max))))
324 (insert "Subject: " (or subject "") "\n")
325 (if mail-default-headers
326 (insert mail-default-headers))
327 (if mail-default-reply-to
328 (insert "Reply-to: " mail-default-reply-to "\n"))
329 (if mail-self-blind
330 (insert "BCC: " (user-login-name) "\n"))
331 (if mail-archive-file-name
332 (insert "FCC: " mail-archive-file-name "\n"))
333 (insert mail-header-separator "\n")
334
335 ;; Insert the signature. But remember the beginning of the message.
336 (if to (setq to (point)))
337 (cond ((eq mail-signature t)
338 (if (file-exists-p mail-signature-file)
339 (progn
340 (insert "\n\n-- \n")
341 (insert-file-contents mail-signature-file))))
342 (mail-signature
343 (insert mail-signature)))
344 (goto-char (point-max))
345 (or (bolp) (newline)))
346 (if to (goto-char to))
347 (or to subject in-reply-to
348 (set-buffer-modified-p nil))
349 (run-hooks 'mail-setup-hook))
350
351 ;;;###autoload
352 (defun mail-mode ()
353 "Major mode for editing mail to be sent.
354 Like Text Mode but with these additional commands:
355 C-c C-s mail-send (send the message) C-c C-c mail-send-and-exit
356 C-c C-f move to a header field (and create it if there isn't):
357 C-c C-f C-t move to To: C-c C-f C-s move to Subj:
358 C-c C-f C-b move to BCC: C-c C-f C-c move to CC:
359 C-c C-f C-f move to FCC: C-c C-f C-r move to Reply-To:
360 C-c C-t mail-text (move to beginning of message text).
361 C-c C-w mail-signature (insert `mail-signature-file' file).
362 C-c C-y mail-yank-original (insert current message, in Rmail).
363 C-c C-q mail-fill-yanked-message (fill what was yanked).
364 C-c C-v mail-sent-via (add a sent-via field for each To or CC)."
365 (interactive)
366 (kill-all-local-variables)
367 (make-local-variable 'mail-reply-buffer)
368 (setq mail-reply-buffer nil)
369 (make-local-variable 'mail-send-actions)
370 (set-syntax-table mail-mode-syntax-table)
371 (use-local-map mail-mode-map)
372 (setq local-abbrev-table text-mode-abbrev-table)
373 (setq major-mode 'mail-mode)
374 (setq mode-name "Mail")
375 (setq buffer-offer-save t)
376 (turn-on-auto-fill) ; XEmacs - maybe filladapt should be default, too.
377 (make-local-variable 'paragraph-separate)
378 (make-local-variable 'paragraph-start)
379 (setq paragraph-start (concat (regexp-quote mail-header-separator)
380 "$\\|[ \t]*[-_][-_][-_]+$\\|"
381 paragraph-start))
382 (setq paragraph-separate (concat (regexp-quote mail-header-separator)
383 "$\\|[ \t]*[-_][-_][-_]+$\\|"
384 paragraph-separate))
385 ;; Set menu
386 (setq mode-popup-menu mail-popup-menu)
387 (if (featurep 'menubar)
388 (progn
389 ;; make a local copy of the menubar, so our modes don't
390 ;; change the global menubar
391 (set-buffer-menubar current-menubar)
392 (add-submenu nil mail-menubar-menu)))
393
394 (run-hooks 'text-mode-hook 'mail-mode-hook))
395
396
397 ;;; Set up keymap.
398
399 (if mail-mode-map
400 nil
401 (setq mail-mode-map (make-sparse-keymap))
402 (set-keymap-parents mail-mode-map (list text-mode-map))
403 (set-keymap-name mail-mode-map 'mail-mode-map)
404 (define-key mail-mode-map "\C-c?" 'describe-mode)
405 (define-key mail-mode-map "\C-c\C-f\C-t" 'mail-to)
406 (define-key mail-mode-map "\C-c\C-f\C-b" 'mail-bcc)
407 (define-key mail-mode-map "\C-c\C-f\C-f" 'mail-fcc)
408 (define-key mail-mode-map "\C-c\C-f\C-c" 'mail-cc)
409 (define-key mail-mode-map "\C-c\C-f\C-s" 'mail-subject)
410 (define-key mail-mode-map "\C-c\C-f\C-r" 'mail-reply-to)
411 (define-key mail-mode-map "\C-c\C-t" 'mail-text)
412 (define-key mail-mode-map "\C-c\C-y" 'mail-yank-original)
413 (define-key mail-mode-map "\C-c\C-q" 'mail-fill-yanked-message)
414 (define-key mail-mode-map "\C-c\C-w" 'mail-signature)
415 ;;CRAP!!(define-key mail-mode-map "\C-c\C-v" 'mail-sent-via)CRAP!
416 (define-key mail-mode-map "\C-c\C-c" 'mail-send-and-exit)
417 (define-key mail-mode-map "\C-c\C-s" 'mail-send))
418
419 ;;; mail-mode popup menu
420
421 (defvar mail-menubar-menu
422 (purecopy
423 '("Mail"
424 "Sending Mail:"
425 "----"
426 ["Send and Exit" mail-send-and-exit t]
427 ["Send Mail" mail-send t]
428 "----"
429 "Go to Field:"
430 "----"
431 ["To:" mail-to t]
432 ["Subject:" mail-subject t]
433 ["CC:" mail-cc t]
434 ["BCC:" mail-bcc t]
435 ["Reply-To:" mail-reply-to t]
436 ;; ["Sent Via:" mail-sent-via t]
437 ["Text" mail-text t]
438 "----"
439 "Miscellaneous Commands:"
440 "----"
441 ["Yank Original" mail-yank-original
442 (not (null mail-reply-buffer))]
443 ["Fill Yanked Message" mail-fill-yanked-message
444 (save-excursion
445 (goto-char (point-min))
446 (and (search-forward (concat "\n" mail-header-separator
447 "\n") nil t)
448 (not (looking-at "[ \t\n]*\\'"))))]
449 ["Insert Signature" mail-signature
450 (and (stringp mail-signature-file)
451 (file-exists-p mail-signature-file))]
452 ["Insert File..." insert-file t]
453 ["Insert Buffer..." insert-buffer t]
454 "----"
455 ["Cancel" mail-dont-send t]
456 ))
457 "Menubar menu for `mail-mode'.")
458
459 (defvar mail-popup-menu
460 (purecopy
461 (cons "Sendmail Commands"
462 (cdr mail-menubar-menu)))
463 "Menubar menu for `mail-mode'.")
464
465
466 (defun mail-send-and-exit (arg)
467 "Send message like `mail-send', then, if no errors, exit from mail buffer.
468 Prefix arg means don't delete this window."
469 (interactive "P")
470 (mail-send)
471 (mail-bury arg))
472
473 (defun mail-dont-send (arg)
474 "Don't send the message you have been editing.
475 Prefix arg means don't delete this window."
476 (interactive "P")
477 (mail-bury arg))
478
479 (defun mail-bury (arg)
480 "Bury this mail buffer."
481 (let ((newbuf (other-buffer (current-buffer))))
482 (bury-buffer (current-buffer))
483 (if (and (fboundp 'frame-parameters)
484 (cdr (assq 'dedicated (frame-parameters)))
485 (not (null (delq (selected-frame) (visible-frame-list)))))
486 (delete-frame (selected-frame))
487 (let (rmail-flag summary-buffer)
488 (and (not arg)
489 (not (one-window-p))
490 (save-excursion
491 (set-buffer (window-buffer (next-window (selected-window) 'not)))
492 (setq rmail-flag (eq major-mode 'rmail-mode))
493 (setq summary-buffer
494 (and mail-bury-selects-summary
495 (boundp 'rmail-summary-buffer)
496 rmail-summary-buffer
497 (buffer-name rmail-summary-buffer)
498 (not (get-buffer-window rmail-summary-buffer))
499 rmail-summary-buffer))))
500 (if rmail-flag
501 ;; If the Rmail buffer has a summary, show that.
502 (if summary-buffer (switch-to-buffer summary-buffer)
503 (delete-window))
504 (switch-to-buffer newbuf))))))
505
506 (defun mail-send ()
507 "Send the message in the current buffer.
508 If `mail-interactive' is non-nil, wait for success indication or error
509 messages, and inform user. Otherwise any failure is reported in a message
510 back to the user from the mailer."
511 (interactive)
512 (if (if buffer-file-name
513 (y-or-n-p "Send buffer contents as mail message? ")
514 (or (buffer-modified-p)
515 (y-or-n-p "Message already sent; resend? ")))
516 (progn
517 (expand-abbrev) ; for mail-abbrevs
518 (run-hooks 'mail-send-hook)
519 (message "Sending...")
520 (funcall send-mail-function)
521 ;; Now perform actions on successful sending.
522 (while mail-send-actions
523 (condition-case nil
524 (apply (car (car mail-send-actions))
525 (cdr (car mail-send-actions)))
526 (error))
527 (setq mail-send-actions (cdr mail-send-actions)))
528 (message "Sending...done")
529
530 ;; If buffer has no file, mark it as unmodified and delete autosave.
531 (cond ((or (not buffer-file-name)
532 (not (buffer-modified-p)))
533 (set-buffer-modified-p nil)
534 (delete-auto-save-file-if-necessary t))
535 ((or noninteractive
536 (y-or-n-p (format "Save file %s? " buffer-file-name)))
537 (save-buffer))))))
538
539 (defun sendmail-send-it ()
540 (require 'mail-utils)
541 (let ((errbuf (if mail-interactive
542 (generate-new-buffer " sendmail errors")
543 0))
544 (tembuf (generate-new-buffer " sendmail temp"))
545 (case-fold-search nil)
546 resend-to-addresses
547 delimline
548 (mailbuf (current-buffer)))
549 (unwind-protect
550 (save-excursion
551 (set-buffer tembuf)
552 (erase-buffer)
553 (insert-buffer-substring mailbuf)
554 (goto-char (point-max))
555 ;; require one newline at the end.
556 (or (= (preceding-char) ?\n)
557 (insert ?\n))
558 ;; Change header-delimiter to be what sendmail expects.
559 (goto-char (point-min))
560 (re-search-forward
561 (concat "^" (regexp-quote mail-header-separator) "\n"))
562 (replace-match "\n")
563 (backward-char 1)
564 (setq delimline (point-marker))
565 ;Removed. See `mail-abbrevs.el'.
566 ; (sendmail-synch-aliases)
567 ; (if mail-aliases
568 ; (expand-mail-aliases (point-min) delimline))
569 ; (goto-char (point-min))
570 ;; ignore any blank lines in the header
571 (while (and (re-search-forward "\n\n\n*" delimline t)
572 (< (point) delimline))
573 (replace-match "\n"))
574 (let ((case-fold-search t))
575 (goto-char (point-min))
576 (while (re-search-forward "^Resent-to:" delimline t)
577 (setq resend-to-addresses
578 (save-restriction
579 (narrow-to-region (point)
580 (save-excursion
581 (end-of-line)
582 (point)))
583 (append (mail-parse-comma-list)
584 resend-to-addresses))))
585 ;;; Apparently this causes a duplicate Sender.
586 ;;; ;; If the From is different than current user, insert Sender.
587 ;;; (goto-char (point-min))
588 ;;; (and (re-search-forward "^From:" delimline t)
589 ;;; (progn
590 ;;; (require 'mail-utils)
591 ;;; (not (string-equal
592 ;;; (mail-strip-quoted-names
593 ;;; (save-restriction
594 ;;; (narrow-to-region (point-min) delimline)
595 ;;; (mail-fetch-field "From")))
596 ;;; (user-login-name))))
597 ;;; (progn
598 ;;; (forward-line 1)
599 ;;; (insert "Sender: " (user-login-name) "\n")))
600 ;; Don't send out a blank subject line
601 (goto-char (point-min))
602 (if (re-search-forward "^Subject:\\([ \t]*\n\\)+\\b" delimline t)
603 (replace-match ""))
604 ;; Put the "From:" field in unless for some odd reason
605 ;; they put one in themselves.
606 (goto-char (point-min))
607 (if (not (re-search-forward "^From:" delimline t))
608 (let* ((login user-mail-address)
609 (fullname (user-full-name)))
610 (cond ((eq mail-from-style 'angles)
611 (insert "From: " fullname)
612 (let ((fullname-start (+ (point-min) 6))
613 (fullname-end (point-marker)))
614 (goto-char fullname-start)
615 ;; Look for a character that cannot appear unquoted
616 ;; according to RFC 822.
617 (if (re-search-forward "[^- !#-'*+/-9=?A-Z^-~]"
618 fullname-end 1)
619 (progn
620 ;; Quote fullname, escaping specials.
621 (goto-char fullname-start)
622 (insert "\"")
623 (while (re-search-forward "[\"\\]"
624 fullname-end 1)
625 (replace-match "\\\\\\&" t))
626 (insert "\""))))
627 (insert " <" login ">\n"))
628 ((eq mail-from-style 'parens)
629 (insert "From: " login " (")
630 (let ((fullname-start (point)))
631 (insert fullname)
632 (let ((fullname-end (point-marker)))
633 (goto-char fullname-start)
634 ;; RFC 822 says \ and nonmatching parentheses
635 ;; must be escaped in comments.
636 ;; Escape every instance of ()\ ...
637 (while (re-search-forward "[()\\]" fullname-end 1)
638 (replace-match "\\\\\\&" t))
639 ;; ... then undo escaping of matching parentheses,
640 ;; including matching nested parentheses.
641 (goto-char fullname-start)
642 (while (re-search-forward
643 "\\(\\=\\|[^\\]\\(\\\\\\\\\\)*\\)\\\\(\\(\\([^\\]\\|\\\\\\\\\\)*\\)\\\\)"
644 fullname-end 1)
645 (replace-match "\\1(\\3)" t)
646 (goto-char fullname-start))))
647 (insert ")\n"))
648 ((null mail-from-style)
649 (insert "From: " login "\n")))))
650 ;; Insert an extra newline if we need it to work around
651 ;; Sun's bug that swallows newlines.
652 (goto-char (1+ delimline))
653 (if (eval mail-mailer-swallows-blank-line)
654 (newline))
655 ;; Find and handle any FCC fields.
656 (goto-char (point-min))
657 (if (re-search-forward "^FCC:" delimline t)
658 (mail-do-fcc delimline))
659 (if mail-interactive
660 (save-excursion
661 (set-buffer errbuf)
662 (erase-buffer))))
663 (let ((default-directory "/"))
664 (apply 'call-process-region
665 (append (list (point-min) (point-max)
666 (if (boundp 'sendmail-program)
667 sendmail-program
668 "/usr/lib/sendmail")
669 nil errbuf nil "-oi")
670 ;; Always specify who from,
671 ;; since some systems have broken sendmails.
672 (list "-f" (user-login-name))
673 ;;; ;; Don't say "from root" if running under su.
674 ;;; (and (equal (user-real-login-name) "root")
675 ;;; (list "-f" (user-login-name)))
676 (and mail-alias-file
677 (list (concat "-oA" mail-alias-file)))
678 ;; These mean "report errors by mail"
679 ;; and "deliver in background".
680 (if (null mail-interactive) '("-oem" "-odb"))
681 ;; Get the addresses from the message
682 ;; unless this is a resend.
683 ;; We must not do that for a resend
684 ;; because we would find the original addresses.
685 ;; For a resend, include the specific addresses.
686 (or resend-to-addresses
687 '("-t")))))
688 (if mail-interactive
689 (save-excursion
690 (set-buffer errbuf)
691 (goto-char (point-min))
692 (while (re-search-forward "\n\n* *" nil t)
693 (replace-match "; "))
694 (if (not (zerop (buffer-size)))
695 (error "Sending...failed to %s"
696 (buffer-substring (point-min) (point-max)))))))
697 (kill-buffer tembuf)
698 (if (bufferp errbuf)
699 (kill-buffer errbuf)))))
700
701 ;;; FCC hackery, by jwz. This version works on BABYL and VM buffers.
702 ;;; To accomplish the latter, VM is loaded when this file is compiled.
703 ;;; Don't worry, it's only loaded at compile-time.
704
705 (defun mail-do-fcc (header-end)
706 (let (fcc-list
707 (send-mail-buffer (current-buffer))
708 (tembuf (generate-new-buffer " rmail output"))
709 (case-fold-search t)
710 beg end)
711 (or (markerp header-end) (error "header-end must be a marker"))
712 (save-excursion
713 (goto-char (point-min))
714 (while (re-search-forward "^FCC:[ \t]*" header-end t)
715 (setq fcc-list (cons (buffer-substring (point)
716 (progn
717 (end-of-line)
718 (skip-chars-backward " \t")
719 (point)))
720 fcc-list))
721 (delete-region (match-beginning 0)
722 (progn (forward-line 1) (point))))
723 (set-buffer tembuf)
724 (erase-buffer)
725 ;; insert just the headers to avoid moving the gap more than
726 ;; necessary (the message body could be arbitrarily huge.)
727 (insert-buffer-substring send-mail-buffer 1 header-end)
728
729 ;; if there's no From: or Date: field, cons some.
730 (goto-char (point-min))
731 (or (re-search-forward "^From[ \t]*:" header-end t)
732 (insert "From: " (user-login-name) " (" (user-full-name) ")\n"))
733 (goto-char (point-min))
734 (or (re-search-forward "^Date[ \t]*:" header-end t)
735 (mail-do-fcc-insert-date-header))
736
737 ;; insert a magic From_ line.
738 (goto-char (point-min))
739 (insert "\nFrom " (user-login-name) " " (current-time-string) "\n")
740 (goto-char (point-max))
741 (insert-buffer-substring send-mail-buffer header-end)
742 (goto-char (point-max))
743 (insert ?\n)
744 (goto-char (1- header-end))
745
746 ;; ``Quote'' "^From " as ">From "
747 ;; (note that this isn't really quoting, as there is no requirement
748 ;; that "^[>]+From " be quoted in the same transparent way.)
749 (let ((case-fold-search nil))
750 (while (search-forward "\nFrom " nil t)
751 (forward-char -5)
752 (insert ?>)))
753
754 (setq beg (point-min)
755 end (point-max))
756 (while fcc-list
757 (let ((target-buffer (get-file-buffer (car fcc-list))))
758 (if target-buffer
759 ;; File is present in a buffer => append to that buffer.
760 (save-excursion
761 (set-buffer target-buffer)
762 (cond ((eq major-mode 'rmail-mode)
763 (mail-do-fcc-rmail-internal tembuf))
764 ((eq major-mode 'vm-mode)
765 (mail-do-fcc-vm-internal tembuf))
766 (t
767 ;; Append to an ordinary buffer as a Unix mail message.
768 (goto-char (point-max))
769 (insert-buffer-substring tembuf beg end))))
770 ;; Else append to the file directly.
771 ;; (It's OK if it is an RMAIL or VM file -- the message will be
772 ;; parsed when the file is read in.)
773 (write-region
774 (1+ (point-min)) (point-max) (car fcc-list) t)))
775 (setq fcc-list (cdr fcc-list))))
776 (kill-buffer tembuf)))
777
778 (defvar mail-do-fcc-cached-timezone nil)
779
780 (defun mail-do-fcc-insert-date-header ()
781 ;; Convert the ctime() format that `current-time-string' returns into
782 ;; an RFC-822-legal date.
783 (let ((s (current-time-string)))
784 (string-match "\\`\\([A-Z][a-z][a-z]\\) +\\([A-Z][a-z][a-z]\\) +\\([0-9][0-9]?\\) *\\([0-9][0-9]?:[0-9][0-9]:[0-9][0-9]\\) *[0-9]?[0-9]?\\([0-9][0-9]\\)"
785 s)
786 (insert "Date: "
787 (substring s (match-beginning 1) (match-end 1)) ", "
788 (substring s (match-beginning 3) (match-end 3)) " "
789 (substring s (match-beginning 2) (match-end 2)) " "
790 (substring s (match-beginning 5) (match-end 5)) " "
791 (substring s (match-beginning 4) (match-end 4)) " ")
792
793 (if mail-do-fcc-cached-timezone
794 (insert mail-do-fcc-cached-timezone "\n")
795 ;;
796 ;; First, try to use the current-time-zone function, which may not be
797 ;; defined, and even if it is defined, may error or return nil.
798 ;;
799 (or (condition-case ()
800 (let ((zoneinfo (current-time-zone)))
801 (setq mail-do-fcc-cached-timezone
802 (if (stringp (nth 1 zoneinfo))
803 (nth 1 zoneinfo)
804 (or (if (nth 1 zoneinfo) (nth 3 zoneinfo))
805 (nth 2 zoneinfo))))
806 (if mail-do-fcc-cached-timezone
807 (insert mail-do-fcc-cached-timezone "\n"))
808 mail-do-fcc-cached-timezone)
809 (error nil))
810 ;;
811 ;; Otherwise, run date(1) and parse its output. Yuck!
812 ;;
813 (save-restriction
814 (narrow-to-region (point) (point))
815 (call-process "date" nil t nil)
816 (end-of-line)
817 (insert "\n")
818 (forward-word -1) ; skip back over year
819 (delete-region (1- (point)) (1- (point-max))) ; nuke year to end
820 (forward-word -1) ; skip back over zone
821 (delete-region (point-min) (point)) ; nuke beginning to zone
822 (setq mail-do-fcc-cached-timezone
823 (buffer-substring (point-min) (1- (point-max)))))))))
824
825 (defun mail-do-fcc-rmail-internal (buffer)
826 (or (eq major-mode 'rmail-mode) (error "this only works in rmail-mode"))
827 (let ((b (point-min))
828 (e (point-max))
829 (buffer-read-only nil))
830 (unwind-protect
831 (progn
832 (widen)
833 (goto-char (point-max))
834 ;; This forces RMAIL's message counters to be recomputed when the
835 ;; next RMAIL operation is done on the buffer.
836 ;; See rmail-maybe-set-message-counters.
837 (setq rmail-total-messages nil)
838 (insert "\^L\n0, unseen,,\n*** EOOH ***")
839 (insert-buffer-substring buffer)
840 (insert "\n\C-_"))
841 (narrow-to-region b e)
842 (rmail-maybe-set-message-counters))))
843
844 ;;; Load VM into the compilation environment but not the load environment.
845 (eval-when-compile
846 (or (and (boundp 'loading-vm-kludge) loading-vm-kludge)
847 ;; nastiness to avoid circular provide/require dependency nonsense
848 (fboundp 'vm-spool-files)
849 (let ((loading-vm-kludge t))
850 (require 'vm))))
851
852 (defun mail-do-fcc-vm-internal (buffer)
853 (or (eq major-mode 'vm-mode) (error "this only works in vm-mode"))
854 (let ((buffer-read-only nil)
855 (foreign-folder-p (not (eq vm-folder-type 'From_))))
856
857 (if foreign-folder-p
858 ;; `buffer' has already been prepared with a "From " line which
859 ;; has a sensible user-id and date in it, but if we're FCCing to
860 ;; a VM folder that isn't in From_ format, we must discard that
861 ;; and let VM do whatever voodoo it needs to do. (Actually we
862 ;; could do this all the time, but then all FCCed messages would
863 ;; have "From VM ..." envelopes, which is less attractive.)
864 (save-excursion
865 (set-buffer buffer)
866 (goto-char (point-min))
867 (skip-chars-forward "\n")
868 (forward-line)
869 (delete-region (point-min) (point))))
870
871 ;; Largely copied from #'vm-save-message in vm-save.el
872 (vm-save-restriction
873 (widen)
874 (goto-char (point-max))
875 (if foreign-folder-p
876 (vm-write-string (current-buffer)
877 (vm-leading-message-separator vm-folder-type)))
878 (insert-buffer-substring buffer)
879 (if foreign-folder-p
880 (vm-write-string (current-buffer)
881 (vm-trailing-message-separator vm-folder-type)))
882
883 (vm-increment vm-messages-not-on-disk)
884 (vm-set-buffer-modified-p t)
885 (vm-clear-modification-flag-undos)
886 (vm-check-for-killed-summary)
887 (vm-assimilate-new-messages)
888 (vm-update-summary-and-mode-line))))
889
890 ;;(defun mail-sent-via ()
891 ;; "Make a Sent-via header line from each To or CC header line."
892 ;; (interactive)
893 ;; (save-excursion
894 ;; (goto-char (point-min))
895 ;; ;; find the header-separator
896 ;; (search-forward (concat "\n" mail-header-separator "\n"))
897 ;; (forward-line -1)
898 ;; ;; put a marker at the end of the header
899 ;; (let ((end (point-marker))
900 ;; (case-fold-search t)
901 ;; to-line)
902 ;; (goto-char (point-min))
903 ;; ;; search for the To: lines and make Sent-via: lines from them
904 ;; ;; search for the next To: line
905 ;; (while (re-search-forward "^\\(to\\|cc\\):" end t)
906 ;; ;; Grab this line plus all its continuations, sans the `to:'.
907 ;; (let ((to-line
908 ;; (buffer-substring (point)
909 ;; (progn
910 ;; (if (re-search-forward "^[^ \t\n]" end t)
911 ;; (backward-char 1)
912 ;; (goto-char end))
913 ;; (point)))))
914 ;; ;; Insert a copy, with altered header field name.
915 ;; (insert-before-markers "Sent-via:" to-line))))))
916
917 (defun mail-to ()
918 "Move point to end of To-field."
919 (interactive)
920 (expand-abbrev)
921 (mail-position-on-field "To"))
922
923 (defun mail-subject ()
924 "Move point to end of Subject-field."
925 (interactive)
926 (expand-abbrev)
927 (mail-position-on-field "Subject"))
928
929 (defun mail-cc ()
930 "Move point to end of CC-field. Create a CC field if none."
931 (interactive)
932 (expand-abbrev)
933 (or (mail-position-on-field "cc" t)
934 (progn (mail-position-on-field "to")
935 (insert "\nCC: "))))
936
937 (defun mail-bcc ()
938 "Move point to end of BCC-field. Create a BCC field if none."
939 (interactive)
940 (expand-abbrev)
941 (or (mail-position-on-field "bcc" t)
942 (progn (mail-position-on-field "to")
943 (insert "\nBCC: "))))
944
945 (defun mail-fcc (folder)
946 "Add a new FCC field, with file name completion."
947 (interactive "FFolder carbon copy: ")
948 (expand-abbrev)
949 (or (mail-position-on-field "fcc" t) ;Put new field after exiting FCC.
950 (mail-position-on-field "to"))
951 (insert "\nFCC: " folder))
952
953 (defun mail-reply-to ()
954 "Move point to end of Reply-To-field. Create a Reply-To field if none."
955 (interactive)
956 (expand-abbrev)
957 (or (mail-position-on-field "reply-to" t)
958 (progn (mail-position-on-field "to")
959 (insert "\nReply-To: "))))
960
961 (defun mail-position-on-field (field &optional soft)
962 (let (end
963 (case-fold-search t))
964 (goto-char (point-min))
965 (re-search-forward (concat "^" (regexp-quote mail-header-separator) "$"))
966 (setq end (match-beginning 0))
967 (goto-char (point-min))
968 (if (re-search-forward (concat "^" (regexp-quote field) ":") end t)
969 (progn
970 (re-search-forward "^[^ \t]" nil 'move)
971 (beginning-of-line)
972 (skip-chars-backward "\n")
973 t)
974 (or soft
975 (progn (goto-char end)
976 ;; #### FSF has the next two clauses reversed.
977 ;; which is correct?
978 (skip-chars-backward "\n")
979 (insert "\n" field ": ")))
980 nil)))
981
982 (defun mail-text ()
983 "Move point to beginning of message text."
984 (interactive)
985 (expand-abbrev)
986 (goto-char (point-min))
987 (search-forward (concat "\n" mail-header-separator "\n")))
988
989 (defun mail-signature (&optional atpoint)
990 "Sign letter with contents of the file `mail-signature-file'.
991 Prefix arg means put contents at point."
992 (interactive "P")
993 (save-excursion
994 (or atpoint
995 (goto-char (point-max)))
996 (skip-chars-backward " \t\n")
997 (end-of-line)
998 (or atpoint
999 (delete-region (point) (point-max)))
1000 (insert "\n\n-- \n")
1001 (insert-file-contents (expand-file-name mail-signature-file))))
1002
1003 (defun mail-fill-yanked-message (&optional justifyp)
1004 "Fill the paragraphs of a message yanked into this one.
1005 Numeric argument means justify as well."
1006 (interactive "P")
1007 (save-excursion
1008 (goto-char (point-min))
1009 (search-forward (concat "\n" mail-header-separator "\n") nil t)
1010 (fill-individual-paragraphs (point)
1011 (point-max)
1012 justifyp
1013 t)))
1014
1015 (defun mail-indent-citation ()
1016 "Modify text just inserted from a message to be cited.
1017 The inserted text should be the region.
1018 When this function returns, the region is again around the modified text.
1019
1020 Normally, indent each nonblank line `mail-indentation-spaces' spaces.
1021 However, if `mail-yank-prefix' is non-nil, insert that prefix on each line."
1022 (let ((start (point)))
1023 (mail-yank-clear-headers start (mark t))
1024 (if (null mail-yank-prefix)
1025 (indent-rigidly start (mark t) mail-indentation-spaces)
1026 (save-excursion
1027 (goto-char start)
1028 (while (< (point) (mark t))
1029 (insert mail-yank-prefix)
1030 (forward-line 1))))))
1031
1032 (defun mail-yank-original (arg)
1033 "Insert the message being replied to, if any (in rmail).
1034 Puts point before the text and mark after.
1035 Normally, indents each nonblank line ARG spaces (default 3).
1036 However, if `mail-yank-prefix' is non-nil, insert that prefix on each line.
1037
1038 Just \\[universal-argument] as argument means don't indent, insert no prefix,
1039 and don't delete any header fields."
1040 (interactive "P")
1041 (if mail-reply-buffer
1042 (let ((start (point))
1043 (reader-buf mail-reply-buffer)
1044 (reader-window (get-buffer-window mail-reply-buffer
1045 (selected-frame))))
1046 ;; If the original message is in another window in the same frame,
1047 ;; delete that window to save screen space.
1048 ;; t means don't alter other frames.
1049 (if reader-window
1050 (delete-windows-on reader-buf t))
1051 (insert-buffer reader-buf)
1052 (if (consp arg)
1053 nil
1054 (goto-char start)
1055 (let ((mail-indentation-spaces (if arg (prefix-numeric-value arg)
1056 mail-indentation-spaces)))
1057 (cond (mail-citation-hook
1058 (run-hooks 'mail-citation-hook))
1059 (mail-yank-hooks
1060 (run-hooks 'mail-yank-hooks))
1061 (t
1062 (mail-indent-citation)))))
1063 (exchange-point-and-mark t)
1064 (if (not (eolp)) (insert ?\n)))))
1065
1066 (defun mail-yank-clear-headers (start end)
1067 (if mail-yank-ignored-headers
1068 (save-excursion
1069 (goto-char start)
1070 (if (search-forward "\n\n" end t)
1071 (save-restriction
1072 (narrow-to-region start (point))
1073 (goto-char start)
1074 (while (let ((case-fold-search t))
1075 (re-search-forward mail-yank-ignored-headers nil t))
1076 (beginning-of-line)
1077 (delete-region (point)
1078 (progn (re-search-forward "\n[^ \t]")
1079 (forward-char -1)
1080 (point)))))))))
1081
1082 ;; Put these last, to reduce chance of lossage from quitting in middle of loading the file.
1083
1084 ;;;###autoload
1085 (defun mail (&optional noerase to subject in-reply-to cc replybuffer actions)
1086 "Edit a message to be sent. Prefix arg means resume editing (don't erase).
1087 When this function returns, the buffer `*mail*' is selected.
1088 The value is t if the message was newly initialized; otherwise, nil.
1089
1090 Optionally, the signature file `mail-signature-file' can be inserted at the
1091 end; see the variable `mail-signature'.
1092
1093 \\<mail-mode-map>
1094 While editing message, type \\[mail-send-and-exit] to send the message and exit.
1095
1096 Various special commands starting with C-c are available in sendmail mode
1097 to move to message header fields:
1098 \\{mail-mode-map}
1099
1100 The variable `mail-signature' controls whether the signature file
1101 `mail-signature-file' is inserted immediately.
1102
1103 If `mail-signature' is nil, use \\[mail-signature] to insert the
1104 signature in `mail-signature-file'.
1105
1106 If `mail-self-blind' is non-nil, a BCC to yourself is inserted
1107 when the message is initialized.
1108
1109 If `mail-default-reply-to' is non-nil, it should be an address (a string);
1110 a Reply-to: field with that address is inserted.
1111
1112 If `mail-archive-file-name' is non-nil, an FCC field with that file name
1113 is inserted.
1114
1115 The normal hook `mail-setup-hook' is run after the message is
1116 initialized. It can add more default fields to the message.
1117
1118 When calling from a program, the first argument if non-nil says
1119 not to erase the existing contents of the `*mail*' buffer.
1120
1121 The second through fifth arguments,
1122 TO, SUBJECT, IN-REPLY-TO and CC, specify if non-nil
1123 the initial contents of those header fields.
1124 These arguments should not have final newlines.
1125 The sixth argument REPLYBUFFER is a buffer whose contents
1126 should be yanked if the user types C-c C-y.
1127 The seventh argument ACTIONS is a list of actions to take
1128 if/when the message is sent. Each action looks like (FUNCTION . ARGS);
1129 when the message is sent, we apply FUNCTION to ARGS.
1130 This is how Rmail arranges to mark messages `answered'."
1131 (interactive "P")
1132 (if mail-use-multiple-buffers-p
1133
1134 ;; RMS doesn't like this behavior but it seems more logical to me. --ben
1135 (let ((index 1)
1136 buffer)
1137 ;; If requested, look for a mail buffer that is modified and go to it.
1138 (if noerase
1139 (progn
1140 (while (and (setq buffer
1141 (get-buffer (if (= 1 index) "*mail*"
1142 (format "*mail*<%d>" index))))
1143 (not (buffer-modified-p buffer)))
1144 (setq index (1+ index)))
1145 (if buffer (switch-to-buffer buffer)
1146 ;; If none exists, start a new message.
1147 ;; This will never re-use an existing unmodified mail buffer
1148 ;; (since index is not 1 anymore). Perhaps it should.
1149 (setq noerase nil))))
1150 ;; Unless we found a modified message and are happy, start a
1151 ;; new message.
1152 (if (not noerase)
1153 (progn
1154 ;; Look for existing unmodified mail buffer.
1155 (while (and (setq buffer
1156 (get-buffer (if (= 1 index) "*mail*"
1157 (format "*mail*<%d>" index))))
1158 (buffer-modified-p buffer))
1159 (setq index (1+ index)))
1160 ;; If none, make a new one.
1161 (or buffer
1162 (setq buffer (generate-new-buffer "*mail*")))
1163 ;; Go there and initialize it.
1164 (switch-to-buffer buffer)
1165 (erase-buffer)
1166 ;; put mail auto-save files in home dir instead of
1167 ;; scattering them around the file system.
1168 (setq default-directory (or mail-dir (expand-file-name "~/")))
1169 (auto-save-mode auto-save-default)
1170 (mail-mode)
1171 (mail-setup to subject in-reply-to cc replybuffer actions)
1172 (if (and buffer-auto-save-file-name
1173 (file-exists-p buffer-auto-save-file-name))
1174 (message "Auto save file for draft message exists; consider M-x mail-recover"))
1175 t)))
1176
1177 ;; Alternate behavior that RMS likes.
1178 (pop-to-buffer "*mail*")
1179 (auto-save-mode auto-save-default)
1180 (mail-mode)
1181 ;; Disconnect the buffer from its visited file
1182 ;; (in case the user has actually visited a file *mail*).
1183 ; (set-visited-file-name nil)
1184 (let (initialized)
1185 (and (not noerase)
1186 (or (not (buffer-modified-p))
1187 (y-or-n-p "Unsent message being composed; erase it? "))
1188 (progn (erase-buffer)
1189 (mail-setup to subject in-reply-to cc replybuffer actions)
1190 (setq initialized t)))
1191 (if (and buffer-auto-save-file-name
1192 (file-exists-p buffer-auto-save-file-name))
1193 (message "Auto save file for draft message exists; consider M-x mail-recover"))
1194 initialized)))
1195
1196 (defun mail-recover ()
1197 "Reread contents of current buffer from its last auto-save file."
1198 (interactive)
1199 (let ((file-name (let ((default-directory (expand-file-name "~/")))
1200 ;; put mail auto-save files in home dir instead of
1201 ;; scattering them around the file system.
1202 (make-auto-save-file-name))))
1203 (cond ((save-window-excursion
1204 (if (not (eq system-type 'vax-vms))
1205 (with-output-to-temp-buffer "*Directory*"
1206 (buffer-disable-undo standard-output)
1207 (let ((default-directory "/"))
1208 (call-process
1209 "ls" nil standard-output nil "-l" file-name))))
1210 (yes-or-no-p (format "Recover auto save file %s? " file-name)))
1211 (let ((buffer-read-only nil))
1212 (erase-buffer)
1213 (insert-file-contents file-name nil)))
1214 (t (error "mail-recover cancelled")))))
1215
1216 ;;;###autoload
1217 (defun mail-other-window (&optional noerase to subject in-reply-to cc replybuffer sendactions)
1218 "Like `mail' command, but display mail buffer in another window."
1219 (interactive "P")
1220 (let ((pop-up-windows t)
1221 (special-display-buffer-names nil)
1222 (special-display-regexps nil)
1223 (same-window-buffer-names nil)
1224 (same-window-regexps nil))
1225 (pop-to-buffer "*mail*"))
1226 (mail noerase to subject in-reply-to cc replybuffer sendactions))
1227
1228 ;;;###autoload
1229 (defun mail-other-frame (&optional noerase to subject in-reply-to cc
1230 replybuffer sendactions)
1231 "Like `mail' command, but display mail buffer in another frame."
1232 (interactive "P")
1233 (let ((pop-up-frames t)
1234 (special-display-buffer-names nil)
1235 (special-display-regexps nil)
1236 (same-window-buffer-names nil)
1237 (same-window-regexps nil))
1238 (pop-to-buffer "*mail*"))
1239 (mail noerase to subject in-reply-to cc replybuffer sendactions))
1240
1241 ;;; Do not execute these when sendmail.el is loaded,
1242 ;;; only in loaddefs.el.
1243 ;;;###autoload (define-key ctl-x-map "m" 'mail)
1244 ;;;###autoload (define-key ctl-x-4-map "m" 'mail-other-window)
1245 ;;;###autoload (define-key ctl-x-5-map "m" 'mail-other-frame)
1246
1247 ;;;###autoload (add-hook 'same-window-buffer-names "*mail*")
1248
1249 ;;; Do not add anything but external entries on this page.
1250
1251 (provide 'sendmail)
1252
1253 ;;; sendmail.el ends here