-(defun nnfolder-read-folder (file)
- (save-excursion
- (nnfolder-possibly-activate-groups nil)
- ;; We should be paranoid here and make sure the group is in the alist,
- ;; and add it if it isn't.
- ;;(if (not (assoc nnfoler-current-group nnfolder-group-alist)
- (set-buffer (setq nnfolder-current-buffer (find-file-noselect file)))
- (buffer-disable-undo (current-buffer))
- (let ((delim (concat "^" rmail-unix-mail-delimiter))
- (marker (concat "\n" nnfolder-article-marker))
- (number "[0-9]+")
- (active (car (cdr (assoc nnfolder-current-group
- nnfolder-group-alist))))
- activenumber activemin start end)
- (goto-char (point-min))
- ;;
- ;; Anytime the active number is 1 or 0, it is supect. In that case,
- ;; search the file manually to find the active number. Or, of course,
- ;; if we're being paranoid. (This would also be the place to build
- ;; other lists from the header markers, such as expunge lists, etc., if
- ;; we ever desired to abandon the active file entirely for mboxes.)
- (setq activenumber (cdr active))
- (if (or nnfolder-ignore-active-file
- (< activenumber 2))
- (progn
- (setq activemin (max (1- (lsh 1 23))
- (1- (lsh 1 24))
- (1- (lsh 1 25))))
- (while (and (search-forward marker nil t)
- (re-search-forward number nil t))
- (let ((newnum (string-to-number (buffer-substring
- (match-beginning 0)
- (match-end 0)))))
- (setq activenumber (max activenumber newnum))
- (setq activemin (min activemin newnum))))
- (setcar active (min activemin activenumber))
- (setcdr active activenumber)
- (goto-char (point-min))))
-
- ;; Keep track of the active number on our own, and insert it back into
- ;; the active list when we're done. Also, prime the pump to cut down on
- ;; the number of searches we do.
- (setq end (point-marker))
- (set-marker end (or (and (re-search-forward delim nil t)
- (match-beginning 0))
- (point-max)))
- (while (not (= end (point-max)))
- (setq start (marker-position end))
- (goto-char end)
- (end-of-line)
- (set-marker end (or (and (re-search-forward delim nil t)
- (match-beginning 0))
- (point-max)))
- (goto-char start)
- (if (not (search-forward marker end t))
- (progn
- (narrow-to-region start end)
- (nnmail-insert-lines)
- (setq activenumber (1+ activenumber))
- (nnfolder-insert-newsgroup-line (cons nil activenumber))
- (widen))))
-
- ;; Make absolutely sure that the active list reflects reality!
- (setcdr active activenumber)
- (nnmail-save-active nnfolder-group-alist nnfolder-active-file)
- (current-buffer))))
-
-(defun nnfolder-get-new-mail (&optional group)
- "Read new incoming mail."
- (let* ((spools (nnmail-get-spool-files group))
- (group-in group)
- incomings incoming)
- (if (or (not nnfolder-get-new-mail) (not nnmail-spool-file))
- ()
- ;; We first activate all the groups.
- (nnfolder-possibly-activate-groups nil)
- ;; The we go through all the existing spool files and split the
- ;; mail from each.
- (while spools
- (and
- (file-exists-p (car spools))
- (> (nth 7 (file-attributes (car spools))) 0)
- (progn
- (and gnus-verbose-backends
- (message "nnfolder: Reading incoming mail..."))
- (setq incoming
- (nnmail-move-inbox
- (car spools)
- (concat (file-name-as-directory nnfolder-directory)
- "Incoming")))
- (setq incomings (cons incoming incomings))
- (setq group (nnmail-get-split-group (car spools) group-in))
- (nnmail-split-incoming incoming 'nnfolder-save-mail nil group)))
- (setq spools (cdr spools)))
- ;; If we did indeed read any incoming spools, we save all info.
- (if incoming
- (progn
- (nnmail-save-active nnfolder-group-alist nnfolder-active-file)
- (run-hooks 'nnmail-read-incoming-hook)
- (and gnus-verbose-backends
- (message "nnfolder: Reading incoming mail...done"))))
- (let ((bufs nnfolder-buffer-alist))
- (save-excursion
- (while bufs
- (if (not (buffer-name (nth 1 (car bufs))))
- (setq nnfolder-buffer-alist
- (delq (car bufs) nnfolder-buffer-alist))
- (set-buffer (nth 1 (car bufs)))
- (and (buffer-modified-p) (save-buffer)))
- (setq bufs (cdr bufs)))))
- (while incomings
- (and
- nnmail-delete-incoming
- (file-writable-p incoming)
- (delete-file incoming))
- (setq incomings (cdr incomings))))))
+(defun nnfolder-read-folder (file &optional scanning)
+ ;; This is an attempt at a serious shortcut - don't even read in the file
+ ;; if we know we've seen it since the last time it was touched.
+ (let ((scantime (cadr (assoc nnfolder-current-group
+ nnfolder-scantime-alist)))
+ (modtime (nth 5 (or (file-attributes file) '(nil nil nil nil nil)))))
+ (if (and scanning scantime
+ (eq (car scantime) (car modtime))
+ (eq (cdr scantime) (cadr modtime)))
+ nil
+ (save-excursion
+ (nnfolder-possibly-activate-groups nil)
+ ;; Read in the file.
+ (set-buffer (setq nnfolder-current-buffer
+ (nnheader-find-file-noselect file nil 'raw)))
+ (buffer-disable-undo (current-buffer))
+ ;; If the file hasn't been touched since the last time we scanned it,
+ ;; don't bother doing anything with it.
+ (let ((delim (concat "^" message-unix-mail-delimiter))
+ (marker (concat "\n" nnfolder-article-marker))
+ (number "[0-9]+")
+ (active (or (cadr (assoc nnfolder-current-group
+ nnfolder-group-alist))
+ (cons 1 0)))
+ (scantime (assoc nnfolder-current-group nnfolder-scantime-alist))
+ (minid (lsh -1 -1))
+ maxid start end newscantime)
+
+ (setq maxid (or (cdr active) 0))
+ (goto-char (point-min))
+
+ ;; Anytime the active number is 1 or 0, it is suspect. In that
+ ;; case, search the file manually to find the active number. Or,
+ ;; of course, if we're being paranoid. (This would also be the
+ ;; place to build other lists from the header markers, such as
+ ;; expunge lists, etc., if we ever desired to abandon the active
+ ;; file entirely for mboxes.)
+ (when (or nnfolder-ignore-active-file
+ (< maxid 2))
+ (while (and (search-forward marker nil t)
+ (re-search-forward number nil t))
+ (let ((newnum (string-to-number (match-string 0))))
+ (setq maxid (max maxid newnum))
+ (setq minid (min minid newnum))))
+ (setcar active (max 1 (min minid maxid)))
+ (setcdr active (max maxid (cdr active)))
+ (goto-char (point-min)))
+
+ ;; As long as we trust that the user will only insert unmarked mail
+ ;; at the end, go to the end and search backwards for the last
+ ;; marker. Find the start of that message, and begin to search for
+ ;; unmarked messages from there.
+ (if (not (or nnfolder-distrust-mbox
+ (< maxid 2)))
+ (progn
+ (goto-char (point-max))
+ (if (not (re-search-backward marker nil t))
+ (goto-char (point-min))
+ (if (not (re-search-backward delim nil t))
+ (goto-char (point-min))))))
+
+ ;; Keep track of the active number on our own, and insert it back
+ ;; into the active list when we're done. Also, prime the pump to
+ ;; cut down on the number of searches we do.
+ (setq end (point-marker))
+ (set-marker end (or (and (re-search-forward delim nil t)
+ (match-beginning 0))
+ (point-max)))
+ (while (not (= end (point-max)))
+ (setq start (marker-position end))
+ (goto-char end)
+ ;; There may be more than one "From " line, so we skip past
+ ;; them.
+ (while (looking-at delim)
+ (forward-line 1))
+ (set-marker end (or (and (re-search-forward delim nil t)
+ (match-beginning 0))
+ (point-max)))
+ (goto-char start)
+ (if (not (search-forward marker end t))
+ (progn
+ (narrow-to-region start end)
+ (nnmail-insert-lines)
+ (nnfolder-insert-newsgroup-line
+ (cons nil (nnfolder-active-number nnfolder-current-group)))
+ (widen))))
+
+ ;; Make absolutely sure that the active list reflects reality!
+ (nnmail-save-active nnfolder-group-alist nnfolder-active-file)
+ ;; Set the scantime for this group.
+ (setq newscantime (visited-file-modtime))
+ (if scantime
+ (setcdr scantime (list newscantime))
+ (push (list nnfolder-current-group newscantime)
+ nnfolder-scantime-alist))
+ (current-buffer))))))
+
+;;;###autoload
+(defun nnfolder-generate-active-file ()
+ "Look for mbox folders in the nnfolder directory and make them into groups."
+ (interactive)
+ (nnmail-activate 'nnfolder)
+ (let ((files (directory-files nnfolder-directory))
+ file)
+ (while (setq file (pop files))
+ (when (and (not (backup-file-name-p file))
+ (nnheader-mail-file-mbox-p
+ (concat nnfolder-directory file)))
+ (nnheader-message 5 "Adding group %s..." file)
+ (push (list file (cons 1 0)) nnfolder-group-alist)
+ (nnfolder-possibly-change-group file)
+ (nnfolder-close-group file))
+ (message ""))))
+
+(defun nnfolder-group-pathname (group)
+ "Make pathname for GROUP."
+ (let ((dir (file-name-as-directory (expand-file-name nnfolder-directory))))
+ ;; If this file exists, we use it directly.
+ (if (or nnmail-use-long-file-names
+ (file-exists-p (concat dir group)))
+ (concat dir group)
+ ;; If not, we translate dots into slashes.
+ (concat dir (nnheader-replace-chars-in-string group ?. ?/)))))
+
+(defun nnfolder-save-buffer ()
+ "Save the buffer."
+ (when (buffer-modified-p)
+ (run-hooks 'nnfolder-save-buffer-hook)
+ (save-buffer)))