;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING. If not, write to
-;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
;;; Commentary:
;;; Code:
-(defvar mail-aliases t
- "Alias of mail address aliases,
-or t meaning should be initialized from `~/.mailrc'.")
+(require 'sendmail)
;; Called from sendmail-send-it, or similar functions,
;; only if some mail aliases are defined.
(defun expand-mail-aliases (beg end &optional exclude)
"Expand all mail aliases in suitable header fields found between BEG and END.
-Suitable header fields are `To', `Cc' and `Bcc' and their `Resent-' variants.
+Suitable header fields are `To', `From', `CC' and `BCC', `Reply-to', and
+their `Resent-' variants.
+
Optional second arg EXCLUDE may be a regular expression defining text to be
removed from alias expansions."
+ (sendmail-sync-aliases)
(if (eq mail-aliases t)
(progn (setq mail-aliases nil) (build-mail-aliases)))
(goto-char beg)
(setq end (set-marker (make-marker) end))
(let ((case-fold-search nil))
(while (let ((case-fold-search t))
- (re-search-forward "^\\(to\\|cc\\|bcc\\|resent-to\\|resent-cc\\|resent-bcc\\):" end t))
+ (re-search-forward "^\\(Resent-\\)?\\(To\\|From\\|CC\\|BCC\\|Reply-to\\):" end t))
(skip-chars-forward " \t")
(let ((beg1 (point))
end1 pos epos seplen
seplen (- (point) epos))
(setq epos (marker-position end1) seplen 0))
(let (translation
- (string (buffer-substring pos epos)))
+ (string (buffer-substring-no-properties pos epos)))
(if (and (not (assoc string disabled-aliases))
(setq translation
(cdr (assoc string mail-aliases))))
(set-marker end1 nil)))
(set-marker end nil)))
-;; Called by mail-setup, or similar functions, only if ~/.mailrc exists.
+;; Called by mail-setup, or similar functions, only if the file specified
+;; by mail-personal-alias-file (usually `~/.mailrc') exists.
(defun build-mail-aliases (&optional file)
- "Read mail aliases from `~/.mailrc' and set `mail-aliases'."
- (setq file (expand-file-name (or file (or (getenv "MAILRC") "~/.mailrc"))))
+ "Read mail aliases from personal aliases file and set `mail-aliases'.
+By default, this is the file specified by `mail-personal-alias-file'."
+ (setq file (expand-file-name (or file mail-personal-alias-file)))
(let ((buffer nil)
(obuf (current-buffer)))
(unwind-protect
(cond ((get-file-buffer file)
(insert (save-excursion
(set-buffer (get-file-buffer file))
- (buffer-substring (point-min) (point-max)))))
+ (buffer-substring-no-properties
+ (point-min) (point-max)))))
((file-exists-p file) (insert-file-contents file))
((file-exists-p (setq file (concat "~/" file)))
(insert-file-contents file))
;; handle `source' directives -- Eddy/1994/May/25
(cond ((re-search-forward "^source[ \t]+" nil t)
(re-search-forward "\\S-+")
- (setq file
- (buffer-substring (match-beginning 0) (match-end 0)))
+ (setq file (buffer-substring-no-properties
+ (match-beginning 0) (match-end 0)))
(beginning-of-line)
(insert "# ") ; to ensure we don't re-process this file
(beginning-of-line))
(t (setq file nil))))
(goto-char (point-min))
- (while (or (re-search-forward "^a\\(lias\\|\\)[ \t]+" nil t)
- (re-search-forward "^g\\(roup\\|\\)[ \t]+" nil t))
- (re-search-forward "[^ \t]+")
- (let* ((name (buffer-substring (match-beginning 0) (match-end 0)))
+ (while (re-search-forward
+ "^\\(a\\|alias\\|g\\|group\\)[ \t]+\\([^ \t]+\\)" nil t)
+ (let* ((name (match-string 2))
(start (progn (skip-chars-forward " \t") (point))))
(end-of-line)
(define-mail-alias
name
- (buffer-substring start (point)))))
+ (buffer-substring-no-properties start (point))
+ t)))
mail-aliases)
(if buffer (kill-buffer buffer))
(set-buffer obuf))))
;; Always autoloadable in case the user wants to define aliases
;; interactively or in .emacs.
;;;###autoload
-(defun define-mail-alias (name definition)
+(defun define-mail-alias (name definition &optional from-mailrc-file)
"Define NAME as a mail alias that translates to DEFINITION.
This means that sending a message to NAME will actually send to DEFINITION.
-DEFINITION can be one or more mail addresses separated by commas."
+
+Normally, the addresses in DEFINITION must be separated by commas.
+If FROM-MAILRC-FILE is non-nil, then addresses in DEFINITION
+can be separated by spaces; an address can contain spaces
+if it is quoted with double-quotes."
+
(interactive "sDefine mail alias: \nsDefine %s as mail alias for: ")
;; Read the defaults first, if we have not done so.
+ (sendmail-sync-aliases)
(if (eq mail-aliases t)
(progn
(setq mail-aliases nil)
- (if (file-exists-p "~/.mailrc")
+ (if (file-exists-p mail-personal-alias-file)
(build-mail-aliases))))
;; strip garbage from front and end
(if (string-match "\\`[ \t\n,]+" definition)
(setq definition (substring definition (match-end 0))))
(if (string-match "[ \t\n,]+\\'" definition)
(setq definition (substring definition 0 (match-beginning 0))))
- (let ((first (aref definition 0))
- (last (aref definition (1- (length definition))))
- tem)
- (if (and (= first last) (memq first '(?\' ?\")))
- ;; Strip quotation marks.
- (setq definition (substring definition 1 (1- (length definition))))
- ;; ~/.mailrc contains addresses separated by spaces.
- ;; mailers should expect addresses separated by commas.
- (while (setq tem (string-match "[^ \t,][ \t,]+" definition tem))
- (if (= (match-end 0) (length definition))
- (setq definition (substring definition 0 (1+ tem)))
- (setq definition (concat (substring definition
- 0 (1+ tem))
- ", "
- (substring definition (match-end 0))))
- (setq tem (+ 3 tem)))))
+ (let ((result '())
+ ;; If DEFINITION is null string, avoid looping even once.
+ (start (and (not (equal definition "")) 0))
+ (L (length definition))
+ end tem)
+ (while start
+ ;; If we're reading from the mailrc file, then addresses are delimited
+ ;; by spaces, and addresses with embedded spaces must be surrounded by
+ ;; double-quotes. Otherwise, addresses are separated by commas.
+ (if from-mailrc-file
+ (if (eq ?\" (aref definition start))
+ (setq start (1+ start)
+ end (string-match "\"[ \t,]*" definition start))
+ (setq end (string-match "[ \t,]+" definition start)))
+ (setq end (string-match "[ \t\n,]*,[ \t\n,]*" definition start)))
+ (setq result (cons (substring definition start end) result))
+ (setq start (and end
+ (/= (match-end 0) L)
+ (match-end 0))))
+ (setq definition (mapconcat (function identity)
+ (nreverse result)
+ ", "))
(setq tem (assoc name mail-aliases))
(if tem
(rplacd tem definition)