This variable is \"/usr/spool/mail/$user\" by default.
If this variable is nil, no mail backends will read incoming mail.
If this variable is a list, all files mentioned in this list will be
-used as incoming mailboxes.")
+used as incoming mailboxes.
+If this variable is a directory (i. e., it's name ends with a \"/\"),
+treat all files in that directory as incoming spool files.")
(defvar nnmail-crash-box "~/.gnus-crash-box"
"*File where Gnus will store mail while processing it.")
Eg.
\(add-hook 'nnmail-read-incoming-hook
- (lambda ()
+ (lambda ()
(start-process \"mailsend\" nil
\"/local/bin/mailsend\" \"read\" \"mbox\")))
(lambda ()
;; Update the displayed time, since that will clear out
;; the flag that says you have mail.
- (if (eq (process-status \"display-time\") 'run)
- (display-time-filter display-time-process \"\"))))")
+ (when (eq (process-status \"display-time\") 'run)
+ (display-time-filter display-time-process \"\"))))")
(when (eq system-type 'windows-nt)
(add-hook 'nnmail-prepare-incoming-hook 'nnheader-ms-strip-cr))
The format is this variable is SPLIT, where SPLIT can be one of
the following:
-GROUP: Mail will be stored in GROUP (a string).
+GROUP: Mail will be stored in GROUP (a string).
\(FIELD VALUE SPLIT): If the message field FIELD (a regexp) contains
VALUE (a regexp), store the messages as specified by SPLIT.
\(& SPLIT...): Process each SPLIT expression.
+\(: FUNCTION optional args): Call FUNCTION with the optional args, in
+ the buffer containing the message headers. The return value FUNCTION
+ should be a split, which is then recursively processed.
+
FIELD must match a complete field name. VALUE must match a complete
word according to the `nnmail-split-fancy-syntax-table' syntax table.
You can use .* in the regexps to match partial field names or words.
FIELD and VALUE can also be lisp symbols, in that case they are expanded
as specified in `nnmail-split-abbrev-alist'.
+GROUP can contain \\& and \\N which will substitute from matching
+\\(\\) patterns in the previous VALUE.
+
Example:
\(setq nnmail-split-methods 'nnmail-split-fancy
nnmail-split-fancy
- ;; Messages from the mailer deamon are not crossposted to any of
+ ;; Messages from the mailer daemon are not crossposted to any of
;; the ordinary groups. Warnings are put in a separate group
;; from real errors.
'(| (\"from\" mail (| (\"subject\" \"warn.*\" \"mail.warning\")
(defvar nnmail-split-abbrev-alist
'((any . "from\\|to\\|cc\\|sender\\|apparently-to\\|resent-from\\|resent-to\\|resent-cc")
- (mail . "mailer-daemon\\|postmaster"))
+ (mail . "mailer-daemon\\|postmaster\\|uucp"))
"*Alist of abbreviations allowed in `nnmail-split-fancy'.")
(defvar nnmail-delete-incoming nil
(defun nnmail-date-to-time (date)
"Convert DATE into time."
- (let* ((d1 (timezone-parse-date date))
- (t1 (timezone-parse-time (aref d1 3))))
- (apply 'encode-time
- (mapcar (lambda (el)
- (and el (string-to-number el)))
- (list
- (aref t1 2) (aref t1 1) (aref t1 0)
- (aref d1 2) (aref d1 1) (aref d1 0)
- (aref d1 4))))))
+ (condition-case ()
+ (let* ((d1 (timezone-parse-date date))
+ (t1 (timezone-parse-time (aref d1 3))))
+ (apply 'encode-time
+ (mapcar (lambda (el)
+ (and el (string-to-number el)))
+ (list
+ (aref t1 2) (aref t1 1) (aref t1 0)
+ (aref d1 2) (aref d1 1) (aref d1 0)
+ (aref d1 4)))))
+ ;; If we get an error, then we just return a 0 time.
+ (error (list 0 0))))
(defun nnmail-time-less (t1 t2)
"Say whether time T1 is less than time T2."
"Convert DAYS into time."
(let* ((seconds (* 1.0 days 60 60 24))
(rest (expt 2 16))
- (ms (condition-case nil (round (/ seconds rest))
+ (ms (condition-case nil (round (/ seconds rest))
(range-error (expt 2 16)))))
(list ms (condition-case nil (round (- seconds (* ms rest)))
(range-error (expt 2 16))))))
;; Convert date strings to internal time.
(setq time (nnmail-date-to-time time)))
(let* ((current (current-time))
- (rest (if (< (nth 1 current) (nth 1 time)) (expt 2 16))))
+ (rest (when (< (nth 1 current) (nth 1 time))
+ (expt 2 16))))
(list (- (+ (car current) (if rest -1 0)) (car time))
(- (+ (or rest 0) (nth 1 current)) (nth 1 time)))))
(if (not (file-writable-p nnmail-crash-box))
(gnus-error 1 "Can't write to crash box %s. Not moving mail."
nnmail-crash-box)
+ ;; If the crash box exists and is empty, we delete it.
+ (when (and (file-exists-p nnmail-crash-box)
+ (zerop (nnheader-file-size (file-truename nnmail-crash-box))))
+ (delete-file nnmail-crash-box))
(let ((inbox (file-truename (expand-file-name inbox)))
(tofile (file-truename (expand-file-name nnmail-crash-box)))
movemail popmail errors)
- ;; If getting from mail spool directory,
- ;; use movemail to move rather than just renaming,
- ;; so as to interlock with the mailer.
- (unless (setq popmail (string-match "^po:" (file-name-nondirectory inbox)))
- (setq movemail t))
- (when popmail
- (setq inbox (file-name-nondirectory inbox)))
- (when (and movemail
- ;; On some systems, /usr/spool/mail/foo is a directory
- ;; and the actual inbox is /usr/spool/mail/foo/foo.
- (file-directory-p inbox))
- (setq inbox (expand-file-name (user-login-name) inbox)))
+ (if (setq popmail (string-match
+ "^po:" (file-name-nondirectory inbox)))
+ (setq inbox (file-name-nondirectory inbox))
+ (setq movemail t)
+ ;; On some systems, /usr/spool/mail/foo is a directory
+ ;; and the actual inbox is /usr/spool/mail/foo/foo.
+ (when (file-directory-p inbox)
+ (setq inbox (expand-file-name (user-login-name) inbox))))
(if (member inbox nnmail-moved-inboxes)
+ ;; We don't try to move an already moced inbox.
nil
(if popmail
(progn
(setq nnmail-internal-password nnmail-pop-password)
- (when (and nnmail-pop-password-required (not nnmail-pop-password))
+ (when (and nnmail-pop-password-required
+ (not nnmail-pop-password))
(setq nnmail-internal-password
(nnmail-read-passwd
(format "Password for %s: "
(not (file-exists-p inbox)))
;; There is no inbox.
(setq tofile nil))
- ((and (not movemail) (not popmail))
- ;; Try copying. If that fails (perhaps no space),
- ;; rename instead.
- (condition-case nil
- (copy-file inbox tofile nil)
- (error
- ;; Third arg is t so we can replace existing file TOFILE.
- (rename-file inbox tofile t)))
- (push inbox nnmail-moved-inboxes)
- ;; Make the real inbox file empty.
- ;; Leaving it deleted could cause lossage
- ;; because mailers often won't create the file.
- (condition-case ()
- (write-region (point) (point) inbox)
- (file-error nil)))
(t
- ;; Use movemail.
+ ;; If getting from mail spool directory, use movemail to move
+ ;; rather than just renaming, so as to interlock with the
+ ;; mailer.
(unwind-protect
(save-excursion
(setq errors (generate-new-buffer " *nnmail loss*"))
'call-process
(append
(list
- (expand-file-name nnmail-movemail-program exec-directory)
+ (expand-file-name nnmail-movemail-program
+ exec-directory)
nil errors nil inbox tofile)
(when nnmail-internal-password
(list nnmail-internal-password))))))
(if (not (buffer-modified-p errors))
;; No output => movemail won
(progn
- (or popmail
- (set-file-modes tofile nnmail-default-file-modes))
+ (unless popmail
+ (set-file-modes tofile nnmail-default-file-modes))
(push inbox nnmail-moved-inboxes))
(set-buffer errors)
;; There may be a warning about older revisions. We
(goto-char (point-min))
(if (search-forward "older revision" nil t)
(progn
- (or popmail
- (set-file-modes tofile nnmail-default-file-modes))
+ (unless popmail
+ (set-file-modes tofile nnmail-default-file-modes))
(push inbox nnmail-moved-inboxes))
;; Probably a real error.
(subst-char-in-region (point-min) (point-max) ?\n ?\ )
(defun nnmail-save-active (group-assoc file-name)
"Save GROUP-ASSOC in ACTIVE-FILE."
(when file-name
- (let (group)
- (save-excursion
- (set-buffer (get-buffer-create " *nnmail active*"))
- (buffer-disable-undo (current-buffer))
- (erase-buffer)
- (while group-assoc
- (setq group (pop group-assoc))
- (insert (format "%s %d %d y\n" (car group) (cdadr group)
- (caadr group))))
- (unless (file-exists-p (file-name-directory file-name))
- (make-directory (file-name-directory file-name) t))
- (nnmail-write-region
- 1 (point-max) (expand-file-name file-name) nil 'nomesg)
- (kill-buffer (current-buffer))))))
+ (nnheader-temp-write file-name
+ (nnmail-generate-active group-assoc))))
+
+(defun nnmail-generate-active (alist)
+ "Generate an active file from group-alist ALIST."
+ (erase-buffer)
+ (let (group)
+ (while (setq group (pop alist))
+ (insert (format "%s %d %d y\n" (car group) (cdadr group)
+ (caadr group))))))
(defun nnmail-get-split-group (file group)
"Find out whether this FILE is to be split into GROUP only.
(goto-char end))))
(defun nnmail-search-unix-mail-delim ()
- "Put point at the beginning of the next message."
- (let ((case-fold-search t)
- (delim (concat "^" message-unix-mail-delimiter))
+ "Put point at the beginning of the next Unix mbox message."
+ ;; Algorithm used to find the the next article in the
+ ;; brain-dead Unix mbox format:
+ ;;
+ ;; 1) Search for "^From ".
+ ;; 2) If we find it, then see whether the previous
+ ;; line is blank and the next line looks like a header.
+ ;; Then it's possible that this is a mail delim, and we use it.
+ (let ((case-fold-search nil)
found)
(while (not found)
- (if (re-search-forward delim nil t)
- (when (or (looking-at "[^\n :]+ *:")
- (looking-at delim)
- (looking-at (concat ">" message-unix-mail-delimiter)))
- (forward-line -1)
- (setq found 'yes))
- (setq found 'no)))
+ (if (not (re-search-forward "^From " nil t))
+ (setq found 'no)
+ (save-excursion
+ (beginning-of-line)
+ (when (and (or (bobp)
+ (save-excursion
+ (forward-line -1)
+ (= (following-char) ?\n)))
+ (save-excursion
+ (forward-line 1)
+ (while (looking-at ">From ")
+ (forward-line 1))
+ (looking-at "[^ \t:]+[ \t]*:")))
+ (setq found 'yes)))))
+ (beginning-of-line)
(eq found 'yes)))
(defun nnmail-process-unix-mail-format (func artnum-func)
(let ((case-fold-search t)
- (delim (concat "^" message-unix-mail-delimiter))
start message-id content-length end skip head-end)
(goto-char (point-min))
- (if (not (and (re-search-forward delim nil t)
+ (if (not (and (re-search-forward "^From " nil t)
(goto-char (match-beginning 0))))
;; Possibly wrong format?
(error "Error, unknown mail format! (Possibly corrupted.)")
(cond ((or (= skip (point-max))
(= (1+ skip) (point-max)))
(setq end (point-max)))
- ((looking-at delim)
+ ((looking-at "From ")
(setq end skip))
- ((looking-at
- (concat "[ \t]*\n\\(" delim "\\)"))
+ ((looking-at "[ \t]*\n\\(From \\)")
(setq end (match-beginning 1)))
(t (setq end nil))))
(if end
(nnmail-process-mmdf-mail-format func artnum-func))
(t
(nnmail-process-unix-mail-format func artnum-func))))
- (if exit-func (funcall exit-func))
+ (when exit-func
+ (funcall exit-func))
(kill-buffer (current-buffer)))))
;; Mail crossposts suggested by Brian Edmonds <edmonds@cs.ubc.ca>.
(if (or methods
(not (equal "" (nth 1 method))))
(when (and
- (condition-case ()
- (if (stringp (nth 1 method))
- (re-search-backward (cadr method) nil t)
- ;; Function to say whether this is a match.
- (funcall (nth 1 method) (car method)))
- (error nil))
+ (ignore-errors
+ (if (stringp (nth 1 method))
+ (re-search-backward (cadr method) nil t)
+ ;; Function to say whether this is a match.
+ (funcall (nth 1 method) (car method))))
;; Don't enter the article into the same
;; group twice.
(not (assoc (car method) group-art)))
- (push (cons (car method) (funcall func (car method)))
+ (push (cons (car method) (funcall func (car method)))
group-art))
;; This is the final group, which is used as a
;; catch-all.
(unless group-art
(setq group-art
- (list (cons (car method)
+ (list (cons (car method)
(funcall func (car method)))))))))
;; See whether the split methods returned `junk'.
(if (equal group-art '(junk))
(let (lines chars)
(save-excursion
(goto-char (point-min))
- (when (search-forward "\n\n" nil t)
+ (when (search-forward "\n\n" nil t)
(setq chars (- (point-max) (point)))
(setq lines (count-lines (point) (point-max)))
(forward-char -1)
"Insert an Xref line based on the (group . article) alist."
(save-excursion
(goto-char (point-min))
- (when (search-forward "\n\n" nil t)
+ (when (search-forward "\n\n" nil t)
(forward-char -1)
(when (re-search-backward "^Xref: " nil t)
- (delete-region (match-beginning 0)
+ (delete-region (match-beginning 0)
(progn (forward-line 1) (point))))
(insert (format "Xref: %s" (system-name)))
(while group-alist
(defun nnmail-split-it (split)
;; Return a list of groups matching SPLIT.
(cond
+ ;; nil split
+ ((null split)
+ nil)
+
+ ;; A group name. Do the \& and \N subs into the string.
((stringp split)
- ;; A group.
- (list split))
+ (list (nnmail-expand-newtext split)))
+
+ ;; Junk the message.
((eq split 'junk)
- ;; Junk this.
(list 'junk))
+
+ ;; Builtin & operation.
((eq (car split) '&)
(apply 'nconc (mapcar 'nnmail-split-it (cdr split))))
+
+ ;; Builtin | operation.
((eq (car split) '|)
(let (done)
(while (and (not done) (cdr split))
(setq split (cdr split)
done (nnmail-split-it (car split))))
done))
+
+ ;; Builtin : operation.
+ ((eq (car split) ':)
+ (nnmail-split-it (eval (cdr split))))
+
+ ;; Check the cache for the regexp for this split.
+ ;; FIX FIX FIX could avoid calling assq twice here
((assq split nnmail-split-cache)
- ;; A compiled match expression.
(goto-char (point-max))
- (if (re-search-backward (cdr (assq split nnmail-split-cache)) nil t)
- (nnmail-split-it (nth 2 split))))
+ ;; FIX FIX FIX problem with re-search-backward is that if you have
+ ;; a split: (from "foo-\\(bar\\|baz\\)@gnus.org "mail.foo.\\1")
+ ;; and someone mails a message with 'To: foo-bar@gnus.org' and
+ ;; 'CC: foo-baz@gnus.org', we'll pick 'mail.foo.baz' as the group
+ ;; if the cc line is a later header, even though the other choice
+ ;; is probably better. Also, this routine won't do a crosspost
+ ;; when there are two different matches.
+ ;; I guess you could just make this more determined, and it could
+ ;; look for still more matches prior to this one, and recurse
+ ;; on each of the multiple matches hit. Of course, then you'd
+ ;; want to make sure that nnmail-article-group or nnmail-split-fancy
+ ;; removed duplicates, since there might be more of those.
+ ;; I guess we could also remove duplicates in the & split case, since
+ ;; that's the only thing that can introduce them.
+ (when (re-search-backward (cdr (assq split nnmail-split-cache)) nil t)
+ ;; Someone might want to do a \N sub on this match, so get the
+ ;; correct match positions.
+ (goto-char (match-end 0))
+ (let ((value (nth 1 split)))
+ (re-search-backward (if (symbolp value)
+ (cdr (assq value nnmail-split-abbrev-alist))
+ value)
+ (match-end 1)))
+ (nnmail-split-it (nth 2 split))))
+
+ ;; Not in cache, compute a regexp for the field/value pair.
(t
- ;; An uncompiled match.
(let* ((field (nth 0 split))
(value (nth 1 split))
- (regexp (concat "^\\("
+ (regexp (concat "^\\(\\("
(if (symbolp field)
(cdr (assq field nnmail-split-abbrev-alist))
field)
- "\\):.*\\<\\("
+ "\\):.*\\)\\<\\("
(if (symbolp value)
(cdr (assq value nnmail-split-abbrev-alist))
value)
"\\)\\>")))
- (setq nnmail-split-cache
- (cons (cons split regexp) nnmail-split-cache))
- (goto-char (point-max))
- (if (re-search-backward regexp nil t)
- (nnmail-split-it (nth 2 split)))))))
+ (push (cons split regexp) nnmail-split-cache)
+ ;; Now that it's in the cache, just call nnmail-split-it again
+ ;; on the same split, which will find it immediately in the cache.
+ (nnmail-split-it split)))))
+
+(defun nnmail-expand-newtext (newtext)
+ (let ((len (length newtext))
+ (pos 0)
+ c expanded beg N did-expand)
+ (while (< pos len)
+ (setq beg pos)
+ (while (and (< pos len)
+ (not (= (aref newtext pos) ?\\)))
+ (setq pos (1+ pos)))
+ (unless (= beg pos)
+ (push (substring newtext beg pos) expanded))
+ (when (< pos len)
+ ;; we hit a \, expand it.
+ (setq did-expand t)
+ (setq pos (1+ pos))
+ (setq c (aref newtext pos))
+ (if (not (or (= c ?\&)
+ (and (>= c ?1)
+ (<= c ?9))))
+ ;; \ followed by some character we don't expand
+ (push (char-to-string c) expanded)
+ ;; \& or \N
+ (if (= c ?\&)
+ (setq N 0)
+ (setq N (- c ?0)))
+ (when (match-beginning N)
+ (push (buffer-substring (match-beginning N) (match-end N))
+ expanded))))
+ (setq pos (1+ pos)))
+ (if did-expand
+ (apply 'concat (nreverse expanded))
+ newtext)))
;; Get a list of spool files to read.
(defun nnmail-get-spool-files (&optional group)
(p procmails)
(crash (when (and (file-exists-p nnmail-crash-box)
(> (nnheader-file-size
- (file-truename nnmail-crash-box)) 0))
+ (file-truename nnmail-crash-box))
+ 0))
(list nnmail-crash-box))))
- ;; Remove any directories that inadvertantly match the procmail
+ ;; Remove any directories that inadvertently match the procmail
;; suffix, which might happen if the suffix is "".
(while p
(when (file-directory-p (car p))
(eq nnmail-spool-file 'procmail))
nil)
((listp nnmail-spool-file)
- (append nnmail-spool-file procmails))
- ((stringp nnmail-spool-file)
+ (nconc
+ (apply
+ 'nconc
+ (mapcar
+ (lambda (file)
+ (if (file-directory-p file)
+ (nnheader-directory-regular-files file)
+ (list file)))
+ nnmail-spool-file))
+ procmails))
+ ((and (stringp nnmail-spool-file)
+ (not (file-directory-p nnmail-spool-file)))
(cons nnmail-spool-file procmails))
+ ((and (stringp nnmail-spool-file)
+ (file-directory-p nnmail-spool-file))
+ (nconc
+ (nnheader-directory-regular-files nnmail-spool-file)
+ procmails))
((eq nnmail-spool-file 'pop)
(cons (format "po:%s" (user-login-name)) procmails))
(t
(let (file timestamp file-time)
(if (or (not (symbol-value (intern (format "%s-group-alist" backend))))
force
- (and (setq file (condition-case ()
- (symbol-value (intern (format "%s-active-file"
- backend)))
- (error nil)))
+ (and (setq file (ignore-errors
+ (symbol-value (intern (format "%s-active-file"
+ backend)))))
(setq file-time (nth 5 (file-attributes file)))
(or (not
(setq timestamp
(save-excursion
(or (eq timestamp 'none)
(set (intern (format "%s-active-timestamp" backend))
- (current-time)))
+;;; dmoore@ucsd.edu 25.10.96
+;;; it's not always the case that current-time
+;;; does correspond to changes in the file's time. So just compare
+;;; the file's new time against its own previous time.
+;;; (current-time)
+ file-time
+ ))
(funcall (intern (format "%s-request-list" backend)))
- (set (intern (format "%s-group-alist" backend))
- (nnmail-get-active))))
+;;; dmoore@ucsd.edu 25.10.96
+;;; BACKEND-request-list already does this itself!
+;;; (set (intern (format "%s-group-alist" backend))
+;;; (nnmail-get-active))
+ ))
t))
(defun nnmail-message-id ()
(setq nnmail-cache-buffer
(get-buffer-create " *nnmail message-id cache*")))
(buffer-disable-undo (current-buffer))
- (and (file-exists-p nnmail-message-id-cache-file)
- (insert-file-contents nnmail-message-id-cache-file))
+ (when (file-exists-p nnmail-message-id-cache-file)
+ (insert-file-contents nnmail-message-id-cache-file))
(set-buffer-modified-p nil)
(current-buffer))))
(set-buffer nnmail-cache-buffer)
;; Weed out the excess number of Message-IDs.
(goto-char (point-max))
- (and (search-backward "\n" nil t nnmail-message-id-cache-length)
- (progn
- (beginning-of-line)
- (delete-region (point-min) (point))))
+ (when (search-backward "\n" nil t nnmail-message-id-cache-length)
+ (progn
+ (beginning-of-line)
+ (delete-region (point-min) (point))))
;; Save the buffer.
(or (file-exists-p (file-name-directory nnmail-message-id-cache-file))
(make-directory (file-name-directory nnmail-message-id-cache-file)
(run-hooks 'nnmail-prepare-incoming-message-hook)
;; If this is a duplicate message, then we do not save it.
(let* ((duplication (nnmail-cache-id-exists-p message-id))
+ (case-fold-search t)
(action (when duplication
(cond
((memq nnmail-treat-duplicates '(warn delete))
(funcall nnmail-treat-duplicates message-id))
(t
nnmail-treat-duplicates))))
- (group-art (nreverse (nnmail-article-group artnum-func))))
+ group-art)
;; Let the backend save the article (or not).
(cond
- ((null group-art)
- (delete-region (point-min) (point-max)))
((not duplication)
(nnmail-cache-insert message-id)
- (funcall func group-art))
+ (funcall func (setq group-art
+ (nreverse (nnmail-article-group artnum-func)))))
((eq action 'delete)
- (delete-region (point-min) (point-max))
(setq group-art nil))
((eq action 'warn)
;; We insert a warning.
"Message-ID: " newid "\n"
"Gnus-Warning: This is a duplicate of message " message-id "\n")
(nnmail-cache-insert newid)
- (funcall func group-art)))
+ (funcall func (setq group-art
+ (nreverse (nnmail-article-group artnum-func))))))
(t
- (funcall func group-art)))
+ (funcall func (setq group-art
+ (nreverse (nnmail-article-group artnum-func))))))
;; Add the group-art list to the history list.
- (push group-art nnmail-split-history)))
+ (if group-art
+ (push group-art nnmail-split-history)
+ (delete-region (point-min) (point-max)))))
;;; Get new mail.
&optional group spool-func)
"Read new incoming mail."
;; Nix out the previous split history.
- (setq nnmail-split-history nil)
+ (unless group
+ (setq nnmail-split-history nil))
(let* ((spools (nnmail-get-spool-files group))
(group-in group)
incoming incomings spool)
(setq spool (pop spools))
;; We read each spool file if either the spool is a POP-mail
;; spool, or the file exists. We can't check for the
- ;; existance of POPped mail.
+ ;; existence of POPped mail.
(when (or (string-match "^po:" spool)
(and (file-exists-p spool)
(> (nnheader-file-size (file-truename spool)) 0)))
(setq group (nnmail-get-split-group spool group-in))
;; We split the mail
(nnmail-split-incoming
- nnmail-crash-box (intern (format "%s-save-mail" method))
+ nnmail-crash-box (intern (format "%s-save-mail" method))
spool-func group (intern (format "%s-active-number" method)))
;; Check whether the inbox is to be moved to the special tmp dir.
(setq incoming
(nnmail-time-less days (nnmail-time-since time)))))))
(defvar nnmail-read-passwd nil)
-(defun nnmail-read-passwd (prompt)
- (unless nnmail-read-passwd
- (if (load "passwd" t)
- (setq nnmail-read-passwd 'read-passwd)
- (autoload 'ange-ftp-read-passwd "ange-ftp")
- (setq nnmail-read-passwd 'ange-ftp-read-passwd)))
- (funcall nnmail-read-passwd prompt))
+(defun nnmail-read-passwd (prompt &rest args)
+ "Read a password using PROMPT.
+If ARGS, PROMPT is used as an argument to `format'."
+ (let ((prompt
+ (if args
+ (apply 'format prompt args)
+ prompt)))
+ (unless nnmail-read-passwd
+ (if (load "passwd" t)
+ (setq nnmail-read-passwd 'read-passwd)
+ (autoload 'ange-ftp-read-passwd "ange-ftp")
+ (setq nnmail-read-passwd 'ange-ftp-read-passwd)))
+ (funcall nnmail-read-passwd prompt)))
(defun nnmail-check-syntax ()
"Check (and modify) the syntax of the message in the current buffer."
(save-restriction
(message-narrow-to-head)
(let ((case-fold-search t))
- (unless (re-search-forward "^Message-Id:" nil t)
+ (unless (re-search-forward "^Message-ID:" nil t)
(insert "Message-ID: " (nnmail-message-id) "\n")))))
(defun nnmail-write-region (start end filename &optional append visit lockname)
(buffer-disable-undo (current-buffer))
(erase-buffer)
(let ((history nnmail-split-history)
- elem ga)
+ elem)
(while (setq elem (pop history))
- (insert (mapcar (lambda (ga)
- (concat (car ga) ":" (int-to-string (cdr ga))))
- elem
- ", ")
+ (insert (mapconcat (lambda (ga)
+ (concat (car ga) ":" (int-to-string (cdr ga))))
+ elem
+ ", ")
"\n"))
(goto-char (point-min))))
+
+(defun nnmail-new-mail-p (group)
+ "Say whether GROUP has new mail."
+ (let ((his nnmail-split-history)
+ found)
+ (while his
+ (when (assoc group (pop his))
+ (setq found t
+ his nil)))
+ found))
(run-hooks 'nnmail-load-hook)