If nil, groups like \"mail.misc\" will end up in directories like
\"mail/misc/\".")
-(defvar nnmail-default-file-modes ?\600
+(defvar nnmail-default-file-modes 384
"Set the mode bits of all new mail files to this integer.")
(defvar nnmail-expiry-wait 7
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))
(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 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)))
+ (unless (setq popmail (string-match
+ "^po:" (file-name-nondirectory inbox)))
(setq movemail t))
(when popmail
(setq inbox (file-name-nondirectory inbox)))
(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: "
'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))))))
(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)
+ (beginning-of-line)
+ (when (and (or (bobp)
+ (save-excursion
+ (forward-line -1)
+ (= (following-char) ?\n)))
+ (save-excursion
+ (forward-line 1)
+ (looking-at "[^ \t:]+[ \t]*:")))
+ (setq found 'yes))))
(eq found 'yes)))
(defun nnmail-process-unix-mail-format (func artnum-func)
- (let ((case-fold-search t)
- (delim (concat "^" message-unix-mail-delimiter))
+ (let ((case-fold-search nil)
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 ()
+ (condition-case ()
(if (stringp (nth 1 method))
(re-search-backward (cadr method) nil t)
;; Function to say whether this is a match.
;; 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
((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))))
+ (when (re-search-backward (cdr (assq split nnmail-split-cache)) nil t)
+ (nnmail-split-it (nth 2 split))))
(t
;; An uncompiled match.
(let* ((field (nth 0 split))
(cdr (assq value nnmail-split-abbrev-alist))
value)
"\\)\\>")))
- (setq nnmail-split-cache
- (cons (cons split regexp) nnmail-split-cache))
+ (push (cons split regexp) nnmail-split-cache)
(goto-char (point-max))
- (if (re-search-backward regexp nil t)
- (nnmail-split-it (nth 2 split)))))))
+ (when (re-search-backward regexp nil t)
+ (nnmail-split-it (nth 2 split)))))))
;; 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 inadvertently match the procmail
;; suffix, which might happen if the suffix is "".
(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
(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))
&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 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."
", ")
"\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)