Mercurial > hg > xemacs-beta
comparison lisp/gnus/nnfolder.el @ 70:131b0175ea99 r20-0b30
Import from CVS: tag r20-0b30
author | cvs |
---|---|
date | Mon, 13 Aug 2007 09:02:59 +0200 |
parents | 8d2a9b52c682 |
children | 0d2f883870bc |
comparison
equal
deleted
inserted
replaced
69:804d1389bcd6 | 70:131b0175ea99 |
---|---|
1 ;;; nnfolder.el --- mail folder access for Gnus | 1 ;;; nnfolder.el --- mail folder access for Gnus |
2 ;; Copyright (C) 1995,96,97 Free Software Foundation, Inc. | 2 ;; Copyright (C) 1995,96 Free Software Foundation, Inc. |
3 | 3 |
4 ;; Author: Scott Byer <byer@mv.us.adobe.com> | 4 ;; Author: Scott Byer <byer@mv.us.adobe.com> |
5 ;; Lars Magne Ingebrigtsen <larsi@ifi.uio.no> | 5 ;; Lars Magne Ingebrigtsen <larsi@ifi.uio.no> |
6 ;; Masanobu UMEDA <umerin@flab.flab.fujitsu.junet> | 6 ;; Masanobu UMEDA <umerin@flab.flab.fujitsu.junet> |
7 ;; Keywords: mail | 7 ;; Keywords: mail |
23 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, | 23 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
24 ;; Boston, MA 02111-1307, USA. | 24 ;; Boston, MA 02111-1307, USA. |
25 | 25 |
26 ;;; Commentary: | 26 ;;; Commentary: |
27 | 27 |
28 ;; For an overview of what the interface functions do, please see the | |
29 ;; Gnus sources. | |
30 | |
31 ;; Various enhancements by byer@mv.us.adobe.com (Scott Byer). | |
32 | |
28 ;;; Code: | 33 ;;; Code: |
29 | 34 |
30 (require 'nnheader) | 35 (require 'nnheader) |
31 (require 'message) | 36 (require 'message) |
32 (require 'nnmail) | 37 (require 'nnmail) |
33 (require 'nnoo) | 38 (require 'nnoo) |
34 (require 'cl) | 39 (eval-when-compile (require 'cl)) |
35 (require 'gnus-util) | |
36 | 40 |
37 (nnoo-declare nnfolder) | 41 (nnoo-declare nnfolder) |
38 | 42 |
39 (defvoo nnfolder-directory (expand-file-name message-directory) | 43 (defvoo nnfolder-directory (expand-file-name message-directory) |
40 "The name of the nnfolder directory.") | 44 "The name of the nnfolder directory.") |
41 | 45 |
42 (defvoo nnfolder-active-file | 46 (defvoo nnfolder-active-file |
43 (nnheader-concat nnfolder-directory "active") | 47 (nnheader-concat nnfolder-directory "active") |
44 "The name of the active file.") | 48 "The name of the active file.") |
45 | 49 |
46 ;; I renamed this variable to something more in keeping with the general GNU | 50 ;; I renamed this variable to something more in keeping with the general GNU |
47 ;; style. -SLB | 51 ;; style. -SLB |
48 | 52 |
49 (defvoo nnfolder-ignore-active-file nil | 53 (defvoo nnfolder-ignore-active-file nil |
50 "If non-nil, causes nnfolder to do some extra work in order to determine | 54 "If non-nil, causes nnfolder to do some extra work in order to determine |
51 the true active ranges of an mbox file. Note that the active file is still | 55 the true active ranges of an mbox file. Note that the active file is still |
52 saved, but it's values are not used. This costs some extra time when | 56 saved, but it's values are not used. This costs some extra time when |
53 scanning an mbox when opening it.") | 57 scanning an mbox when opening it.") |
54 | 58 |
55 (defvoo nnfolder-distrust-mbox nil | 59 (defvoo nnfolder-distrust-mbox nil |
56 "If non-nil, causes nnfolder to not trust the user with respect to | 60 "If non-nil, causes nnfolder to not trust the user with respect to |
57 inserting unaccounted for mail in the middle of an mbox file. This can greatly | 61 inserting unaccounted for mail in the middle of an mbox file. This can greatly |
58 slow down scans, which now must scan the entire file for unmarked messages. | 62 slow down scans, which now must scan the entire file for unmarked messages. |
59 When nil, scans occur forward from the last marked message, a huge | 63 When nil, scans occur forward from the last marked message, a huge |
60 time saver for large mailboxes.") | 64 time saver for large mailboxes.") |
61 | 65 |
62 (defvoo nnfolder-newsgroups-file | 66 (defvoo nnfolder-newsgroups-file |
63 (concat (file-name-as-directory nnfolder-directory) "newsgroups") | 67 (concat (file-name-as-directory nnfolder-directory) "newsgroups") |
64 "Mail newsgroups description file.") | 68 "Mail newsgroups description file.") |
65 | 69 |
66 (defvoo nnfolder-get-new-mail t | 70 (defvoo nnfolder-get-new-mail t |
67 "If non-nil, nnfolder will check the incoming mail file and split the mail.") | 71 "If non-nil, nnfolder will check the incoming mail file and split the mail.") |
87 (defvoo nnfolder-current-buffer nil) | 91 (defvoo nnfolder-current-buffer nil) |
88 (defvoo nnfolder-status-string "") | 92 (defvoo nnfolder-status-string "") |
89 (defvoo nnfolder-group-alist nil) | 93 (defvoo nnfolder-group-alist nil) |
90 (defvoo nnfolder-buffer-alist nil) | 94 (defvoo nnfolder-buffer-alist nil) |
91 (defvoo nnfolder-scantime-alist nil) | 95 (defvoo nnfolder-scantime-alist nil) |
92 (defvoo nnfolder-active-timestamp nil) | |
93 | 96 |
94 | 97 |
95 | 98 |
96 ;;; Interface functions | 99 ;;; Interface functions |
97 | 100 |
99 | 102 |
100 (deffoo nnfolder-retrieve-headers (articles &optional group server fetch-old) | 103 (deffoo nnfolder-retrieve-headers (articles &optional group server fetch-old) |
101 (save-excursion | 104 (save-excursion |
102 (set-buffer nntp-server-buffer) | 105 (set-buffer nntp-server-buffer) |
103 (erase-buffer) | 106 (erase-buffer) |
104 (let (article art-string start stop) | 107 (let ((delim-string (concat "^" message-unix-mail-delimiter)) |
108 article art-string start stop) | |
105 (nnfolder-possibly-change-group group server) | 109 (nnfolder-possibly-change-group group server) |
106 (when nnfolder-current-buffer | 110 (when nnfolder-current-buffer |
107 (set-buffer nnfolder-current-buffer) | 111 (set-buffer nnfolder-current-buffer) |
108 (goto-char (point-min)) | 112 (goto-char (point-min)) |
109 (if (stringp (car articles)) | 113 (if (stringp (car articles)) |
110 'headers | 114 'headers |
111 (while articles | 115 (while articles |
112 (setq article (car articles)) | 116 (setq article (car articles)) |
113 (setq art-string (nnfolder-article-string article)) | 117 (setq art-string (nnfolder-article-string article)) |
114 (set-buffer nnfolder-current-buffer) | 118 (set-buffer nnfolder-current-buffer) |
115 (when (or (search-forward art-string nil t) | 119 (if (or (search-forward art-string nil t) |
116 ;; Don't search the whole file twice! Also, articles | 120 ;; Don't search the whole file twice! Also, articles |
117 ;; probably have some locality by number, so searching | 121 ;; probably have some locality by number, so searching |
118 ;; backwards will be faster. Especially if we're at the | 122 ;; backwards will be faster. Especially if we're at the |
119 ;; beginning of the buffer :-). -SLB | 123 ;; beginning of the buffer :-). -SLB |
120 (search-backward art-string nil t)) | 124 (search-backward art-string nil t)) |
121 (nnmail-search-unix-mail-delim-backward) | 125 (progn |
122 (setq start (point)) | 126 (setq start (or (re-search-backward delim-string nil t) |
123 (search-forward "\n\n" nil t) | 127 (point))) |
124 (setq stop (1- (point))) | 128 (search-forward "\n\n" nil t) |
125 (set-buffer nntp-server-buffer) | 129 (setq stop (1- (point))) |
126 (insert (format "221 %d Article retrieved.\n" article)) | 130 (set-buffer nntp-server-buffer) |
127 (insert-buffer-substring nnfolder-current-buffer start stop) | 131 (insert (format "221 %d Article retrieved.\n" article)) |
128 (goto-char (point-max)) | 132 (insert-buffer-substring nnfolder-current-buffer start stop) |
129 (insert ".\n")) | 133 (goto-char (point-max)) |
134 (insert ".\n"))) | |
130 (setq articles (cdr articles))) | 135 (setq articles (cdr articles))) |
131 | 136 |
132 (set-buffer nntp-server-buffer) | 137 (set-buffer nntp-server-buffer) |
133 (nnheader-fold-continuation-lines) | 138 (nnheader-fold-continuation-lines) |
134 'headers))))) | 139 'headers))))) |
135 | 140 |
136 (deffoo nnfolder-open-server (server &optional defs) | 141 (deffoo nnfolder-open-server (server &optional defs) |
137 (nnoo-change-server 'nnfolder server defs) | 142 (nnoo-change-server 'nnfolder server defs) |
138 (nnmail-activate 'nnfolder t) | 143 (when (not (file-exists-p nnfolder-directory)) |
139 (gnus-make-directory nnfolder-directory) | 144 (condition-case () |
140 (cond | 145 (make-directory nnfolder-directory t) |
146 (error t))) | |
147 (cond | |
141 ((not (file-exists-p nnfolder-directory)) | 148 ((not (file-exists-p nnfolder-directory)) |
142 (nnfolder-close-server) | 149 (nnfolder-close-server) |
143 (nnheader-report 'nnfolder "Couldn't create directory: %s" | 150 (nnheader-report 'nnfolder "Couldn't create directory: %s" |
144 nnfolder-directory)) | 151 nnfolder-directory)) |
145 ((not (file-directory-p (file-truename nnfolder-directory))) | 152 ((not (file-directory-p (file-truename nnfolder-directory))) |
146 (nnfolder-close-server) | 153 (nnfolder-close-server) |
147 (nnheader-report 'nnfolder "Not a directory: %s" nnfolder-directory)) | 154 (nnheader-report 'nnfolder "Not a directory: %s" nnfolder-directory)) |
148 (t | 155 (t |
149 (nnmail-activate 'nnfolder) | |
150 (nnheader-report 'nnfolder "Opened server %s using directory %s" | 156 (nnheader-report 'nnfolder "Opened server %s using directory %s" |
151 server nnfolder-directory) | 157 server nnfolder-directory) |
152 t))) | 158 t))) |
153 | 159 |
154 (deffoo nnfolder-request-close () | 160 (deffoo nnfolder-request-close () |
163 (deffoo nnfolder-request-article (article &optional group server buffer) | 169 (deffoo nnfolder-request-article (article &optional group server buffer) |
164 (nnfolder-possibly-change-group group server) | 170 (nnfolder-possibly-change-group group server) |
165 (save-excursion | 171 (save-excursion |
166 (set-buffer nnfolder-current-buffer) | 172 (set-buffer nnfolder-current-buffer) |
167 (goto-char (point-min)) | 173 (goto-char (point-min)) |
168 (when (search-forward (nnfolder-article-string article) nil t) | 174 (if (search-forward (nnfolder-article-string article) nil t) |
169 (let (start stop) | 175 (let (start stop) |
170 (nnmail-search-unix-mail-delim-backward) | 176 (re-search-backward (concat "^" message-unix-mail-delimiter) nil t) |
171 (setq start (point)) | 177 (setq start (point)) |
172 (forward-line 1) | 178 (forward-line 1) |
173 (unless (and (nnmail-search-unix-mail-delim) | 179 (or (and (re-search-forward |
174 (forward-line -1)) | 180 (concat "^" message-unix-mail-delimiter) nil t) |
175 (goto-char (point-max))) | 181 (forward-line -1)) |
176 (setq stop (point)) | 182 (goto-char (point-max))) |
177 (let ((nntp-server-buffer (or buffer nntp-server-buffer))) | 183 (setq stop (point)) |
178 (set-buffer nntp-server-buffer) | 184 (let ((nntp-server-buffer (or buffer nntp-server-buffer))) |
179 (erase-buffer) | 185 (set-buffer nntp-server-buffer) |
180 (insert-buffer-substring nnfolder-current-buffer start stop) | 186 (erase-buffer) |
181 (goto-char (point-min)) | 187 (insert-buffer-substring nnfolder-current-buffer start stop) |
182 (while (looking-at "From ") | |
183 (delete-char 5) | |
184 (insert "X-From-Line: ") | |
185 (forward-line 1)) | |
186 (if (numberp article) | |
187 (cons nnfolder-current-group article) | |
188 (goto-char (point-min)) | 188 (goto-char (point-min)) |
189 (search-forward (concat "\n" nnfolder-article-marker)) | 189 (while (looking-at "From ") |
190 (cons nnfolder-current-group | 190 (delete-char 5) |
191 (string-to-int | 191 (insert "X-From-Line: ") |
192 (buffer-substring | 192 (forward-line 1)) |
193 (point) (progn (end-of-line) (point))))))))))) | 193 (if (numberp article) |
194 (cons nnfolder-current-group article) | |
195 (goto-char (point-min)) | |
196 (search-forward (concat "\n" nnfolder-article-marker)) | |
197 (cons nnfolder-current-group | |
198 (string-to-int | |
199 (buffer-substring | |
200 (point) (progn (end-of-line) (point))))))))))) | |
194 | 201 |
195 (deffoo nnfolder-request-group (group &optional server dont-check) | 202 (deffoo nnfolder-request-group (group &optional server dont-check) |
196 (nnfolder-possibly-change-group group server t) | 203 (save-excursion |
197 (save-excursion | 204 (nnmail-activate 'nnfolder) |
198 (if (not (assoc group nnfolder-group-alist)) | 205 (if (not (assoc group nnfolder-group-alist)) |
199 (nnheader-report 'nnfolder "No such group: %s" group) | 206 (nnheader-report 'nnfolder "No such group: %s" group) |
207 (nnfolder-possibly-change-group group server) | |
200 (if dont-check | 208 (if dont-check |
201 (progn | 209 (progn |
202 (nnheader-report 'nnfolder "Selected group %s" group) | 210 (nnheader-report 'nnfolder "Selected group %s" group) |
203 t) | 211 t) |
204 (let* ((active (assoc group nnfolder-group-alist)) | 212 (let* ((active (assoc group nnfolder-group-alist)) |
205 (group (car active)) | 213 (group (car active)) |
206 (range (cadr active))) | 214 (range (cadr active))) |
207 (cond | 215 (cond |
208 ((null active) | 216 ((null active) |
209 (nnheader-report 'nnfolder "No such group: %s" group)) | 217 (nnheader-report 'nnfolder "No such group: %s" group)) |
210 ((null nnfolder-current-group) | 218 ((null nnfolder-current-group) |
211 (nnheader-report 'nnfolder "Empty group: %s" group)) | 219 (nnheader-report 'nnfolder "Empty group: %s" group)) |
212 (t | 220 (t |
213 (nnheader-report 'nnfolder "Selected group %s" group) | 221 (nnheader-report 'nnfolder "Selected group %s" group) |
214 (nnheader-insert "211 %d %d %d %s\n" | 222 (nnheader-insert "211 %d %d %d %s\n" |
215 (1+ (- (cdr range) (car range))) | 223 (1+ (- (cdr range) (car range))) |
216 (car range) (cdr range) group)))))))) | 224 (car range) (cdr range) group)))))))) |
217 | 225 |
218 (deffoo nnfolder-request-scan (&optional group server) | 226 (deffoo nnfolder-request-scan (&optional group server) |
219 (nnfolder-possibly-change-group nil server) | 227 (nnfolder-possibly-change-group group server t) |
220 (when nnfolder-get-new-mail | 228 (nnmail-get-new-mail |
221 (nnfolder-possibly-change-group group server) | 229 'nnfolder |
222 (nnmail-get-new-mail | 230 (lambda () |
223 'nnfolder | 231 (let ((bufs nnfolder-buffer-alist)) |
224 (lambda () | 232 (save-excursion |
225 (let ((bufs nnfolder-buffer-alist)) | 233 (while bufs |
226 (save-excursion | 234 (if (not (buffer-name (nth 1 (car bufs)))) |
227 (while bufs | 235 (setq nnfolder-buffer-alist |
228 (if (not (gnus-buffer-live-p (nth 1 (car bufs)))) | 236 (delq (car bufs) nnfolder-buffer-alist)) |
229 (setq nnfolder-buffer-alist | 237 (set-buffer (nth 1 (car bufs))) |
230 (delq (car bufs) nnfolder-buffer-alist)) | 238 (nnfolder-save-buffer) |
231 (set-buffer (nth 1 (car bufs))) | 239 (kill-buffer (current-buffer))) |
232 (nnfolder-save-buffer) | 240 (setq bufs (cdr bufs)))))) |
233 (kill-buffer (current-buffer))) | 241 nnfolder-directory |
234 (setq bufs (cdr bufs)))))) | 242 group)) |
235 nnfolder-directory | |
236 group))) | |
237 | 243 |
238 ;; Don't close the buffer if we're not shutting down the server. This way, | 244 ;; Don't close the buffer if we're not shutting down the server. This way, |
239 ;; we can keep the buffer in the group buffer cache, and not have to grovel | 245 ;; we can keep the buffer in the group buffer cache, and not have to grovel |
240 ;; over the buffer again unless we add new mail to it or modify it in some | 246 ;; over the buffer again unless we add new mail to it or modify it in some |
241 ;; way. | 247 ;; way. |
244 ;; Make sure we _had_ the group open. | 250 ;; Make sure we _had_ the group open. |
245 (when (or (assoc group nnfolder-buffer-alist) | 251 (when (or (assoc group nnfolder-buffer-alist) |
246 (equal group nnfolder-current-group)) | 252 (equal group nnfolder-current-group)) |
247 (let ((inf (assoc group nnfolder-buffer-alist))) | 253 (let ((inf (assoc group nnfolder-buffer-alist))) |
248 (when inf | 254 (when inf |
249 (when (and nnfolder-current-group | 255 (when nnfolder-current-group |
250 nnfolder-current-buffer) | |
251 (push (list nnfolder-current-group nnfolder-current-buffer) | 256 (push (list nnfolder-current-group nnfolder-current-buffer) |
252 nnfolder-buffer-alist)) | 257 nnfolder-buffer-alist)) |
253 (setq nnfolder-buffer-alist | 258 (setq nnfolder-buffer-alist |
254 (delq inf nnfolder-buffer-alist)) | 259 (delq inf nnfolder-buffer-alist)) |
255 (setq nnfolder-current-buffer (cadr inf) | 260 (setq nnfolder-current-buffer (cadr inf) |
268 nnfolder-buffer-alist))))) | 273 nnfolder-buffer-alist))))) |
269 (setq nnfolder-current-group nil | 274 (setq nnfolder-current-group nil |
270 nnfolder-current-buffer nil) | 275 nnfolder-current-buffer nil) |
271 t) | 276 t) |
272 | 277 |
273 (deffoo nnfolder-request-create-group (group &optional server args) | 278 (deffoo nnfolder-request-create-group (group &optional server) |
274 (nnfolder-possibly-change-group nil server) | 279 (nnfolder-possibly-change-group nil server) |
275 (nnmail-activate 'nnfolder) | 280 (nnmail-activate 'nnfolder) |
276 (when group | 281 (when group |
277 (unless (assoc group nnfolder-group-alist) | 282 (unless (assoc group nnfolder-group-alist) |
278 (push (list group (cons 1 0)) nnfolder-group-alist) | 283 (push (list group (cons 1 0)) nnfolder-group-alist) |
279 (nnmail-save-active nnfolder-group-alist nnfolder-active-file))) | 284 (nnmail-save-active nnfolder-group-alist nnfolder-active-file))) |
280 t) | 285 t) |
281 | 286 |
282 (deffoo nnfolder-request-list (&optional server) | 287 (deffoo nnfolder-request-list (&optional server) |
283 (nnfolder-possibly-change-group nil server) | 288 (nnfolder-possibly-change-group nil server) |
284 (save-excursion | 289 (save-excursion |
285 (nnmail-find-file nnfolder-active-file) | 290 (nnmail-find-file nnfolder-active-file) |
286 (setq nnfolder-group-alist (nnmail-get-active)) | 291 (setq nnfolder-group-alist (nnmail-get-active)))) |
287 t)) | |
288 | 292 |
289 (deffoo nnfolder-request-newgroups (date &optional server) | 293 (deffoo nnfolder-request-newgroups (date &optional server) |
290 (nnfolder-possibly-change-group nil server) | 294 (nnfolder-possibly-change-group nil server) |
291 (nnfolder-request-list server)) | 295 (nnfolder-request-list server)) |
292 | 296 |
293 (deffoo nnfolder-request-list-newsgroups (&optional server) | 297 (deffoo nnfolder-request-list-newsgroups (&optional server) |
294 (nnfolder-possibly-change-group nil server) | 298 (nnfolder-possibly-change-group nil server) |
295 (save-excursion | 299 (save-excursion |
296 (nnmail-find-file nnfolder-newsgroups-file))) | 300 (nnmail-find-file nnfolder-newsgroups-file))) |
297 | 301 |
298 (deffoo nnfolder-request-expire-articles | 302 (deffoo nnfolder-request-expire-articles |
299 (articles newsgroup &optional server force) | 303 (articles newsgroup &optional server force) |
300 (nnfolder-possibly-change-group newsgroup server) | 304 (nnfolder-possibly-change-group newsgroup server) |
301 (let* ((is-old t) | 305 (let* ((is-old t) |
302 rest) | 306 rest) |
303 (nnmail-activate 'nnfolder) | 307 (nnmail-activate 'nnfolder) |
304 | 308 |
305 (save-excursion | 309 (save-excursion |
306 (set-buffer nnfolder-current-buffer) | 310 (set-buffer nnfolder-current-buffer) |
307 (while (and articles is-old) | 311 (while (and articles is-old) |
308 (goto-char (point-min)) | 312 (goto-char (point-min)) |
309 (when (search-forward (nnfolder-article-string (car articles)) nil t) | 313 (if (search-forward (nnfolder-article-string (car articles)) nil t) |
310 (if (setq is-old | 314 (if (setq is-old |
311 (nnmail-expired-article-p | 315 (nnmail-expired-article-p |
312 newsgroup | 316 newsgroup |
313 (buffer-substring | 317 (buffer-substring |
314 (point) (progn (end-of-line) (point))) | 318 (point) (progn (end-of-line) (point))) |
315 force nnfolder-inhibit-expiry)) | 319 force nnfolder-inhibit-expiry)) |
316 (progn | 320 (progn |
317 (nnheader-message 5 "Deleting article %d..." | 321 (nnheader-message 5 "Deleting article %d..." |
318 (car articles) newsgroup) | 322 (car articles) newsgroup) |
319 (nnfolder-delete-mail)) | 323 (nnfolder-delete-mail)) |
320 (push (car articles) rest))) | 324 (setq rest (cons (car articles) rest)))) |
321 (setq articles (cdr articles))) | 325 (setq articles (cdr articles))) |
322 (unless nnfolder-inhibit-expiry | |
323 (nnheader-message 5 "Deleting articles...done")) | |
324 (nnfolder-save-buffer) | 326 (nnfolder-save-buffer) |
325 (nnfolder-adjust-min-active newsgroup) | 327 ;; Find the lowest active article in this group. |
328 (let* ((active (cadr (assoc newsgroup nnfolder-group-alist))) | |
329 (marker (concat "\n" nnfolder-article-marker)) | |
330 (number "[0-9]+") | |
331 (activemin (cdr active))) | |
332 (goto-char (point-min)) | |
333 (while (and (search-forward marker nil t) | |
334 (re-search-forward number nil t)) | |
335 (setq activemin (min activemin | |
336 (string-to-number (buffer-substring | |
337 (match-beginning 0) | |
338 (match-end 0)))))) | |
339 (setcar active activemin)) | |
326 (nnmail-save-active nnfolder-group-alist nnfolder-active-file) | 340 (nnmail-save-active nnfolder-group-alist nnfolder-active-file) |
327 (nconc rest articles)))) | 341 (nconc rest articles)))) |
328 | 342 |
329 (deffoo nnfolder-request-move-article | 343 (deffoo nnfolder-request-move-article |
330 (article group server accept-form &optional last) | 344 (article group server accept-form &optional last) |
345 (nnfolder-possibly-change-group group server) | |
331 (let ((buf (get-buffer-create " *nnfolder move*")) | 346 (let ((buf (get-buffer-create " *nnfolder move*")) |
332 result) | 347 result) |
333 (and | 348 (and |
334 (nnfolder-request-article article group server) | 349 (nnfolder-request-article article group server) |
335 (save-excursion | 350 (save-excursion |
336 (set-buffer buf) | 351 (set-buffer buf) |
337 (buffer-disable-undo (current-buffer)) | 352 (buffer-disable-undo (current-buffer)) |
338 (erase-buffer) | 353 (erase-buffer) |
339 (insert-buffer-substring nntp-server-buffer) | 354 (insert-buffer-substring nntp-server-buffer) |
340 (goto-char (point-min)) | 355 (goto-char (point-min)) |
341 (while (re-search-forward | 356 (while (re-search-forward |
342 (concat "^" nnfolder-article-marker) | 357 (concat "^" nnfolder-article-marker) |
343 (save-excursion (search-forward "\n\n" nil t) (point)) t) | 358 (save-excursion (search-forward "\n\n" nil t) (point)) t) |
344 (delete-region (progn (beginning-of-line) (point)) | 359 (delete-region (progn (beginning-of-line) (point)) |
345 (progn (forward-line 1) (point)))) | 360 (progn (forward-line 1) (point)))) |
346 (setq result (eval accept-form)) | 361 (setq result (eval accept-form)) |
348 result) | 363 result) |
349 (save-excursion | 364 (save-excursion |
350 (nnfolder-possibly-change-group group server) | 365 (nnfolder-possibly-change-group group server) |
351 (set-buffer nnfolder-current-buffer) | 366 (set-buffer nnfolder-current-buffer) |
352 (goto-char (point-min)) | 367 (goto-char (point-min)) |
353 (when (search-forward (nnfolder-article-string article) nil t) | 368 (if (search-forward (nnfolder-article-string article) nil t) |
354 (nnfolder-delete-mail)) | 369 (nnfolder-delete-mail)) |
355 (when last | 370 (and last (nnfolder-save-buffer)))) |
356 (nnfolder-save-buffer) | |
357 (nnfolder-adjust-min-active group) | |
358 (nnmail-save-active nnfolder-group-alist nnfolder-active-file)))) | |
359 result)) | 371 result)) |
360 | 372 |
361 (deffoo nnfolder-request-accept-article (group &optional server last) | 373 (deffoo nnfolder-request-accept-article (group &optional server last) |
362 (nnfolder-possibly-change-group group server) | 374 (nnfolder-possibly-change-group group server) |
363 (nnmail-check-syntax) | 375 (nnmail-check-syntax) |
376 (and (stringp group) (nnfolder-possibly-change-group group)) | |
364 (let ((buf (current-buffer)) | 377 (let ((buf (current-buffer)) |
365 result art-group) | 378 result) |
366 (goto-char (point-min)) | 379 (goto-char (point-min)) |
367 (when (looking-at "X-From-Line: ") | 380 (when (looking-at "X-From-Line: ") |
368 (replace-match "From ")) | 381 (replace-match "From ")) |
369 (and | 382 (and |
370 (nnfolder-request-list) | 383 (nnfolder-request-list) |
371 (save-excursion | 384 (save-excursion |
372 (set-buffer buf) | 385 (set-buffer buf) |
373 (goto-char (point-min)) | 386 (goto-char (point-min)) |
374 (search-forward "\n\n" nil t) | 387 (search-forward "\n\n" nil t) |
375 (forward-line -1) | 388 (forward-line -1) |
376 (while (re-search-backward (concat "^" nnfolder-article-marker) nil t) | 389 (while (re-search-backward (concat "^" nnfolder-article-marker) nil t) |
377 (delete-region (point) (progn (forward-line 1) (point)))) | 390 (delete-region (point) (progn (forward-line 1) (point)))) |
378 (when nnmail-cache-accepted-message-ids | 391 (setq result (car (nnfolder-save-mail (and (stringp group) group))))) |
379 (nnmail-cache-insert (nnmail-fetch-field "message-id"))) | 392 (save-excursion |
380 (setq result (if (stringp group) | 393 (set-buffer nnfolder-current-buffer) |
381 (list (cons group (nnfolder-active-number group))) | 394 (and last (nnfolder-save-buffer)))) |
382 (setq art-group | |
383 (nnmail-article-group 'nnfolder-active-number)))) | |
384 (if (null result) | |
385 (setq result 'junk) | |
386 (setq result | |
387 (car (nnfolder-save-mail result))))) | |
388 (when last | |
389 (save-excursion | |
390 (nnfolder-possibly-change-folder (or (caar art-group) group)) | |
391 (nnfolder-save-buffer) | |
392 (when nnmail-cache-accepted-message-ids | |
393 (nnmail-cache-close))))) | |
394 (nnmail-save-active nnfolder-group-alist nnfolder-active-file) | 395 (nnmail-save-active nnfolder-group-alist nnfolder-active-file) |
395 (unless result | 396 (unless result |
396 (nnheader-report 'nnfolder "Couldn't store article")) | 397 (nnheader-report 'nnfolder "Couldn't store article")) |
397 result)) | 398 result)) |
398 | 399 |
412 (nnfolder-close-group group server t) | 413 (nnfolder-close-group group server t) |
413 ;; Delete all articles in GROUP. | 414 ;; Delete all articles in GROUP. |
414 (if (not force) | 415 (if (not force) |
415 () ; Don't delete the articles. | 416 () ; Don't delete the articles. |
416 ;; Delete the file that holds the group. | 417 ;; Delete the file that holds the group. |
417 (ignore-errors | 418 (condition-case nil |
418 (delete-file (nnfolder-group-pathname group)))) | 419 (delete-file (nnfolder-group-pathname group)) |
420 (error nil))) | |
419 ;; Remove the group from all structures. | 421 ;; Remove the group from all structures. |
420 (setq nnfolder-group-alist | 422 (setq nnfolder-group-alist |
421 (delq (assoc group nnfolder-group-alist) nnfolder-group-alist) | 423 (delq (assoc group nnfolder-group-alist) nnfolder-group-alist) |
422 nnfolder-current-group nil | 424 nnfolder-current-group nil |
423 nnfolder-current-buffer nil) | 425 nnfolder-current-buffer nil) |
424 ;; Save the active file. | 426 ;; Save the active file. |
425 (nnmail-save-active nnfolder-group-alist nnfolder-active-file) | 427 (nnmail-save-active nnfolder-group-alist nnfolder-active-file) |
428 (deffoo nnfolder-request-rename-group (group new-name &optional server) | 430 (deffoo nnfolder-request-rename-group (group new-name &optional server) |
429 (nnfolder-possibly-change-group group server) | 431 (nnfolder-possibly-change-group group server) |
430 (save-excursion | 432 (save-excursion |
431 (set-buffer nnfolder-current-buffer) | 433 (set-buffer nnfolder-current-buffer) |
432 (and (file-writable-p buffer-file-name) | 434 (and (file-writable-p buffer-file-name) |
433 (ignore-errors | 435 (condition-case () |
434 (rename-file | 436 (progn |
435 buffer-file-name | 437 (rename-file |
436 (nnfolder-group-pathname new-name)) | 438 buffer-file-name |
437 t) | 439 (nnfolder-group-pathname new-name)) |
440 t) | |
441 (error nil)) | |
438 ;; That went ok, so we change the internal structures. | 442 ;; That went ok, so we change the internal structures. |
439 (let ((entry (assoc group nnfolder-group-alist))) | 443 (let ((entry (assoc group nnfolder-group-alist))) |
440 (and entry (setcar entry new-name)) | 444 (and entry (setcar entry new-name)) |
441 (setq nnfolder-current-buffer nil | 445 (setq nnfolder-current-buffer nil |
442 nnfolder-current-group nil) | 446 nnfolder-current-group nil) |
447 t)))) | 451 t)))) |
448 | 452 |
449 | 453 |
450 ;;; Internal functions. | 454 ;;; Internal functions. |
451 | 455 |
452 (defun nnfolder-adjust-min-active (group) | |
453 ;; Find the lowest active article in this group. | |
454 (let* ((active (cadr (assoc group nnfolder-group-alist))) | |
455 (marker (concat "\n" nnfolder-article-marker)) | |
456 (number "[0-9]+") | |
457 (activemin (cdr active))) | |
458 (save-excursion | |
459 (set-buffer nnfolder-current-buffer) | |
460 (goto-char (point-min)) | |
461 (while (and (search-forward marker nil t) | |
462 (re-search-forward number nil t)) | |
463 (setq activemin (min activemin | |
464 (string-to-number (buffer-substring | |
465 (match-beginning 0) | |
466 (match-end 0)))))) | |
467 (setcar active activemin)))) | |
468 | |
469 (defun nnfolder-article-string (article) | 456 (defun nnfolder-article-string (article) |
470 (if (numberp article) | 457 (if (numberp article) |
471 (concat "\n" nnfolder-article-marker (int-to-string article) " ") | 458 (concat "\n" nnfolder-article-marker (int-to-string article) " ") |
472 (concat "\nMessage-ID: " article))) | 459 (concat "\nMessage-ID: " article))) |
473 | 460 |
474 (defun nnfolder-delete-mail (&optional force leave-delim) | 461 (defun nnfolder-delete-mail (&optional force leave-delim) |
475 "Delete the message that point is in." | 462 "Delete the message that point is in." |
476 (save-excursion | 463 (save-excursion |
477 (delete-region | 464 (delete-region |
478 (save-excursion | 465 (save-excursion |
479 (nnmail-search-unix-mail-delim-backward) | 466 (re-search-backward (concat "^" message-unix-mail-delimiter) nil t) |
480 (if leave-delim (progn (forward-line 1) (point)) | 467 (if leave-delim (progn (forward-line 1) (point)) |
481 (point))) | 468 (match-beginning 0))) |
482 (progn | 469 (progn |
483 (forward-line 1) | 470 (forward-line 1) |
484 (if (nnmail-search-unix-mail-delim) | 471 (if (re-search-forward (concat "^" message-unix-mail-delimiter) nil t) |
485 (if (and (not (bobp)) leave-delim) | 472 (if (and (not (bobp)) leave-delim) |
486 (progn (forward-line -2) (point)) | 473 (progn (forward-line -2) (point)) |
487 (point)) | 474 (match-beginning 0)) |
488 (point-max)))))) | 475 (point-max)))))) |
489 | 476 |
490 (defun nnfolder-possibly-change-group (group &optional server dont-check) | 477 ;; When scanning, we're not looking t immediately switch into the group - if |
491 ;; Change servers. | 478 ;; we know our information is up to date, don't even bother reading the file. |
479 (defun nnfolder-possibly-change-group (group &optional server scanning) | |
492 (when (and server | 480 (when (and server |
493 (not (nnfolder-server-opened server))) | 481 (not (nnfolder-server-opened server))) |
494 (nnfolder-open-server server)) | 482 (nnfolder-open-server server)) |
495 (unless (gnus-buffer-live-p nnfolder-current-buffer) | 483 (when (and group (or nnfolder-current-buffer |
496 (setq nnfolder-current-buffer nil | 484 (not (equal group nnfolder-current-group)))) |
497 nnfolder-current-group nil)) | 485 (unless (file-exists-p nnfolder-directory) |
498 ;; Change group. | 486 (make-directory (directory-file-name nnfolder-directory) t)) |
499 (when (and group | 487 (nnfolder-possibly-activate-groups nil) |
500 (not (equal group nnfolder-current-group))) | 488 (or (assoc group nnfolder-group-alist) |
501 (nnmail-activate 'nnfolder) | 489 (not (file-exists-p |
502 (when (and (not (assoc group nnfolder-group-alist)) | 490 (nnfolder-group-pathname group))) |
503 (not (file-exists-p | 491 (progn |
504 (nnfolder-group-pathname group)))) | 492 (setq nnfolder-group-alist |
505 ;; The group doesn't exist, so we create a new entry for it. | 493 (cons (list group (cons 1 0)) nnfolder-group-alist)) |
506 (push (list group (cons 1 0)) nnfolder-group-alist) | 494 (nnmail-save-active nnfolder-group-alist nnfolder-active-file))) |
507 (nnmail-save-active nnfolder-group-alist nnfolder-active-file)) | 495 (let (inf file) |
508 | 496 (if (and (equal group nnfolder-current-group) |
509 (if dont-check | 497 nnfolder-current-buffer |
498 (buffer-name nnfolder-current-buffer)) | |
499 () | |
510 (setq nnfolder-current-group group) | 500 (setq nnfolder-current-group group) |
511 (let (inf file) | 501 |
512 ;; If we have to change groups, see if we don't already have the | 502 ;; If we have to change groups, see if we don't already have the mbox |
513 ;; folder in memory. If we do, verify the modtime and destroy | 503 ;; in memory. If we do, verify the modtime and destroy the mbox if |
514 ;; the folder if needed so we can rescan it. | 504 ;; needed so we can rescan it. |
515 (when (setq inf (assoc group nnfolder-buffer-alist)) | 505 (if (setq inf (assoc group nnfolder-buffer-alist)) |
516 (setq nnfolder-current-buffer (nth 1 inf))) | 506 (setq nnfolder-current-buffer (nth 1 inf))) |
517 | 507 |
518 ;; If the buffer is not live, make sure it isn't in the alist. If it | 508 ;; If the buffer is not live, make sure it isn't in the alist. If it |
519 ;; is live, verify that nobody else has touched the file since last | 509 ;; is live, verify that nobody else has touched the file since last |
520 ;; time. | 510 ;; time. |
521 (when (and nnfolder-current-buffer | 511 (if (or (not (and nnfolder-current-buffer |
522 (not (gnus-buffer-live-p nnfolder-current-buffer))) | 512 (buffer-name nnfolder-current-buffer))) |
523 (setq nnfolder-buffer-alist (delq inf nnfolder-buffer-alist) | 513 (not (and (bufferp nnfolder-current-buffer) |
524 nnfolder-current-buffer nil)) | 514 (verify-visited-file-modtime |
525 | 515 nnfolder-current-buffer)))) |
526 (setq nnfolder-current-group group) | 516 (progn |
527 | 517 (if (and nnfolder-current-buffer |
528 (when (or (not nnfolder-current-buffer) | 518 (buffer-name nnfolder-current-buffer) |
529 (not (verify-visited-file-modtime nnfolder-current-buffer))) | 519 (bufferp nnfolder-current-buffer)) |
520 (kill-buffer nnfolder-current-buffer)) | |
521 (setq nnfolder-buffer-alist (delq inf nnfolder-buffer-alist)) | |
522 (setq inf nil))) | |
523 | |
524 (if inf | |
525 () | |
530 (save-excursion | 526 (save-excursion |
531 (setq file (nnfolder-group-pathname group)) | 527 (setq file (nnfolder-group-pathname group)) |
532 ;; See whether we need to create the new file. | 528 (if (file-directory-p (file-truename file)) |
533 (unless (file-exists-p file) | 529 () |
534 (gnus-make-directory (file-name-directory file)) | 530 (unless (file-exists-p file) |
535 (nnmail-write-region 1 1 file t 'nomesg)) | 531 (unless (file-exists-p (file-name-directory file)) |
536 (when (setq nnfolder-current-buffer (nnfolder-read-folder group)) | 532 (make-directory (file-name-directory file) t)) |
537 (set-buffer nnfolder-current-buffer) | 533 (write-region 1 1 file t 'nomesg)) |
538 (push (list group nnfolder-current-buffer) | 534 (setq nnfolder-current-buffer |
539 nnfolder-buffer-alist)))))))) | 535 (nnfolder-read-folder file scanning)) |
540 | 536 (if nnfolder-current-buffer |
541 (defun nnfolder-save-mail (group-art-list) | 537 (progn |
538 (set-buffer nnfolder-current-buffer) | |
539 (setq nnfolder-buffer-alist | |
540 (cons (list group nnfolder-current-buffer) | |
541 nnfolder-buffer-alist))))))))) | |
542 (setq nnfolder-current-group group))) | |
543 | |
544 (defun nnfolder-save-mail (&optional group) | |
542 "Called narrowed to an article." | 545 "Called narrowed to an article." |
543 (let* (save-list group-art) | 546 (let* ((nnmail-split-methods |
547 (if group (list (list group "")) nnmail-split-methods)) | |
548 (group-art-list | |
549 (nreverse (nnmail-article-group 'nnfolder-active-number))) | |
550 (delim (concat "^" message-unix-mail-delimiter)) | |
551 save-list group-art) | |
544 (goto-char (point-min)) | 552 (goto-char (point-min)) |
545 ;; The From line may have been quoted by movemail. | 553 ;; The From line may have been quoted by movemail. |
546 (when (looking-at (concat ">" message-unix-mail-delimiter)) | 554 (when (looking-at (concat ">" message-unix-mail-delimiter)) |
547 (delete-char 1)) | 555 (delete-char 1)) |
548 ;; This might come from somewhere else. | 556 ;; This might come from somewhere else. |
549 (unless (looking-at message-unix-mail-delimiter) | 557 (unless (looking-at delim) |
550 (insert "From nobody " (current-time-string) "\n") | 558 (insert "From nobody " (current-time-string) "\n") |
551 (goto-char (point-min))) | 559 (goto-char (point-min))) |
552 ;; Quote all "From " lines in the article. | 560 ;; Quote all "From " lines in the article. |
553 (forward-line 1) | 561 (forward-line 1) |
554 (let (case-fold-search) | 562 (while (re-search-forward delim nil t) |
555 (while (re-search-forward "^From " nil t) | 563 (beginning-of-line) |
556 (beginning-of-line) | 564 (insert "> ")) |
557 (insert "> "))) | |
558 (setq save-list group-art-list) | 565 (setq save-list group-art-list) |
559 (nnmail-insert-lines) | 566 (nnmail-insert-lines) |
560 (nnmail-insert-xref group-art-list) | 567 (nnmail-insert-xref group-art-list) |
561 (run-hooks 'nnmail-prepare-save-mail-hook) | 568 (run-hooks 'nnmail-prepare-save-mail-hook) |
562 (run-hooks 'nnfolder-prepare-save-mail-hook) | 569 (run-hooks 'nnfolder-prepare-save-mail-hook) |
563 | 570 |
564 ;; Insert the mail into each of the destination groups. | 571 ;; Insert the mail into each of the destination groups. |
565 (while (setq group-art (pop group-art-list)) | 572 (while group-art-list |
566 ;; Kill any previous newsgroup markers. | 573 (setq group-art (car group-art-list) |
574 group-art-list (cdr group-art-list)) | |
575 | |
576 ;; Kill the previous newsgroup markers. | |
567 (goto-char (point-min)) | 577 (goto-char (point-min)) |
568 (search-forward "\n\n" nil t) | 578 (search-forward "\n\n" nil t) |
569 (forward-line -1) | 579 (forward-line -1) |
570 (while (search-backward (concat "\n" nnfolder-article-marker) nil t) | 580 (while (search-backward (concat "\n" nnfolder-article-marker) nil t) |
571 (delete-region (1+ (point)) (progn (forward-line 2) (point)))) | 581 (delete-region (1+ (point)) (progn (forward-line 2) (point)))) |
572 | 582 |
583 (nnfolder-possibly-change-group (car group-art)) | |
573 ;; Insert the new newsgroup marker. | 584 ;; Insert the new newsgroup marker. |
574 (nnfolder-insert-newsgroup-line group-art) | 585 (nnfolder-insert-newsgroup-line group-art) |
575 | 586 (unless nnfolder-current-buffer |
576 (save-excursion | 587 (nnfolder-close-group (car group-art)) |
577 (let ((beg (point-min)) | 588 (nnfolder-request-create-group (car group-art)) |
578 (end (point-max)) | 589 (nnfolder-possibly-change-group (car group-art))) |
579 (obuf (current-buffer))) | 590 (let ((beg (point-min)) |
580 (nnfolder-possibly-change-folder (car group-art)) | 591 (end (point-max)) |
581 (goto-char (point-max)) | 592 (obuf (current-buffer))) |
582 (unless (eolp) | 593 (set-buffer nnfolder-current-buffer) |
583 (insert "\n")) | 594 (goto-char (point-max)) |
584 (unless (bobp) | 595 (unless (eolp) |
585 (insert "\n")) | 596 (insert "\n")) |
586 (insert-buffer-substring obuf beg end)))) | 597 (insert "\n") |
598 (insert-buffer-substring obuf beg end) | |
599 (set-buffer obuf))) | |
587 | 600 |
588 ;; Did we save it anywhere? | 601 ;; Did we save it anywhere? |
589 save-list)) | 602 save-list)) |
590 | 603 |
591 (defun nnfolder-insert-newsgroup-line (group-art) | 604 (defun nnfolder-insert-newsgroup-line (group-art) |
592 (save-excursion | 605 (save-excursion |
593 (goto-char (point-min)) | 606 (goto-char (point-min)) |
594 (when (search-forward "\n\n" nil t) | 607 (if (search-forward "\n\n" nil t) |
595 (forward-char -1) | 608 (progn |
596 (insert (format (concat nnfolder-article-marker "%d %s\n") | 609 (forward-char -1) |
597 (cdr group-art) (current-time-string)))))) | 610 (insert (format (concat nnfolder-article-marker "%d %s\n") |
611 (cdr group-art) (current-time-string))))))) | |
612 | |
613 (defun nnfolder-possibly-activate-groups (&optional group) | |
614 (save-excursion | |
615 ;; If we're looking for the activation of a specific group, find out | |
616 ;; its real name and switch to it. | |
617 (if group (nnfolder-possibly-change-group group)) | |
618 ;; If the group alist isn't active, activate it now. | |
619 (nnmail-activate 'nnfolder))) | |
598 | 620 |
599 (defun nnfolder-active-number (group) | 621 (defun nnfolder-active-number (group) |
600 ;; Find the next article number in GROUP. | 622 (when group |
601 (let ((active (cadr (assoc group nnfolder-group-alist)))) | 623 (save-excursion |
602 (if active | 624 ;; Find the next article number in GROUP. |
603 (setcdr active (1+ (cdr active))) | 625 (prog1 |
604 ;; This group is new, so we create a new entry for it. | 626 (let ((active (cadr (assoc group nnfolder-group-alist)))) |
605 ;; This might be a bit naughty... creating groups on the drop of | 627 (if active |
606 ;; a hat, but I don't know... | 628 (setcdr active (1+ (cdr active))) |
607 (push (list group (setq active (cons 1 1))) | 629 ;; This group is new, so we create a new entry for it. |
608 nnfolder-group-alist)) | 630 ;; This might be a bit naughty... creating groups on the drop of |
609 (cdr active))) | 631 ;; a hat, but I don't know... |
610 | 632 (setq nnfolder-group-alist |
611 (defun nnfolder-possibly-change-folder (group) | 633 (cons (list group (setq active (cons 1 1))) |
612 (let ((inf (assoc group nnfolder-buffer-alist))) | 634 nnfolder-group-alist))) |
613 (if (and inf | 635 (cdr active)) |
614 (gnus-buffer-live-p (cadr inf))) | 636 (nnmail-save-active nnfolder-group-alist nnfolder-active-file) |
615 (set-buffer (cadr inf)) | 637 (nnfolder-possibly-activate-groups group))))) |
616 (when inf | 638 |
617 (setq nnfolder-buffer-alist (delq inf nnfolder-buffer-alist))) | |
618 (when nnfolder-group-alist | |
619 (nnmail-save-active nnfolder-group-alist nnfolder-active-file)) | |
620 (push (list group (nnfolder-read-folder group)) | |
621 nnfolder-buffer-alist)))) | |
622 | 639 |
623 ;; This method has a problem if you've accidentally let the active list get | 640 ;; This method has a problem if you've accidentally let the active list get |
624 ;; out of sync with the files. This could happen, say, if you've | 641 ;; out of sync with the files. This could happen, say, if you've |
625 ;; accidentally gotten new mail with something other than Gnus (but why | 642 ;; accidentally gotten new mail with something other than Gnus (but why |
626 ;; would _that_ ever happen? :-). In that case, we will be in the middle of | 643 ;; would _that_ ever happen? :-). In that case, we will be in the middle of |
633 ;; rest of the message looking for any more, possibly higher IDs. We'll | 650 ;; rest of the message looking for any more, possibly higher IDs. We'll |
634 ;; assume the maximum that we find is the highest active. Note that this | 651 ;; assume the maximum that we find is the highest active. Note that this |
635 ;; shouldn't cost us much extra time at all, but will be a lot less | 652 ;; shouldn't cost us much extra time at all, but will be a lot less |
636 ;; vulnerable to glitches between the mbox and the active file. | 653 ;; vulnerable to glitches between the mbox and the active file. |
637 | 654 |
638 (defun nnfolder-read-folder (group) | 655 (defun nnfolder-read-folder (file &optional scanning) |
639 (let* ((file (nnfolder-group-pathname group)) | 656 ;; This is an attempt at a serious shortcut - don't even read in the file |
640 (buffer (set-buffer (nnheader-find-file-noselect file)))) | 657 ;; if we know we've seen it since the last time it was touched. |
641 (if (equal (cadr (assoc group nnfolder-scantime-alist)) | 658 (let ((scantime (cadr (assoc nnfolder-current-group |
642 (nth 5 (file-attributes file))) | 659 nnfolder-scantime-alist))) |
643 ;; This looks up-to-date, so we don't do any scanning. | 660 (modtime (nth 5 (or (file-attributes file) '(nil nil nil nil nil))))) |
644 buffer | 661 (if (and scanning scantime |
645 ;; Parse the damn thing. | 662 (eq (car scantime) (car modtime)) |
663 (eq (cdr scantime) (cadr modtime))) | |
664 nil | |
646 (save-excursion | 665 (save-excursion |
647 (nnmail-activate 'nnfolder) | 666 (nnfolder-possibly-activate-groups nil) |
648 ;; Read in the file. | 667 ;; Read in the file. |
668 (set-buffer (setq nnfolder-current-buffer | |
669 (nnheader-find-file-noselect file nil 'raw))) | |
670 (buffer-disable-undo (current-buffer)) | |
671 ;; If the file hasn't been touched since the last time we scanned it, | |
672 ;; don't bother doing anything with it. | |
649 (let ((delim (concat "^" message-unix-mail-delimiter)) | 673 (let ((delim (concat "^" message-unix-mail-delimiter)) |
650 (marker (concat "\n" nnfolder-article-marker)) | 674 (marker (concat "\n" nnfolder-article-marker)) |
651 (number "[0-9]+") | 675 (number "[0-9]+") |
652 (active (or (cadr (assoc group nnfolder-group-alist)) | 676 (active (or (cadr (assoc nnfolder-current-group |
677 nnfolder-group-alist)) | |
653 (cons 1 0))) | 678 (cons 1 0))) |
654 (scantime (assoc group nnfolder-scantime-alist)) | 679 (scantime (assoc nnfolder-current-group nnfolder-scantime-alist)) |
655 (minid (lsh -1 -1)) | 680 (minid (lsh -1 -1)) |
656 maxid start end newscantime | 681 maxid start end newscantime) |
657 buffer-read-only) | 682 |
658 (buffer-disable-undo (current-buffer)) | 683 (setq maxid (or (cdr active) 0)) |
659 (setq maxid (cdr active)) | |
660 (goto-char (point-min)) | 684 (goto-char (point-min)) |
661 | 685 |
662 ;; Anytime the active number is 1 or 0, it is suspect. In that | 686 ;; Anytime the active number is 1 or 0, it is suspect. In that |
663 ;; case, search the file manually to find the active number. Or, | 687 ;; case, search the file manually to find the active number. Or, |
664 ;; of course, if we're being paranoid. (This would also be the | 688 ;; of course, if we're being paranoid. (This would also be the |
665 ;; place to build other lists from the header markers, such as | 689 ;; place to build other lists from the header markers, such as |
666 ;; expunge lists, etc., if we ever desired to abandon the active | 690 ;; expunge lists, etc., if we ever desired to abandon the active |
667 ;; file entirely for mboxes.) | 691 ;; file entirely for mboxes.) |
668 (when (or nnfolder-ignore-active-file | 692 (when (or nnfolder-ignore-active-file |
669 (< maxid 2)) | 693 (< maxid 2)) |
670 (while (and (search-forward marker nil t) | 694 (while (and (search-forward marker nil t) |
671 (re-search-forward number nil t)) | 695 (re-search-forward number nil t)) |
672 (let ((newnum (string-to-number (match-string 0)))) | 696 (let ((newnum (string-to-number (match-string 0)))) |
673 (setq maxid (max maxid newnum)) | 697 (setq maxid (max maxid newnum)) |
674 (setq minid (min minid newnum)))) | 698 (setq minid (min minid newnum)))) |
675 (setcar active (max 1 (min minid maxid))) | 699 (setcar active (max 1 (min minid maxid))) |
676 (setcdr active (max maxid (cdr active))) | 700 (setcdr active (max maxid (cdr active))) |
677 (goto-char (point-min))) | 701 (goto-char (point-min))) |
678 | 702 |
679 ;; As long as we trust that the user will only insert unmarked mail | 703 ;; As long as we trust that the user will only insert unmarked mail |
680 ;; at the end, go to the end and search backwards for the last | 704 ;; at the end, go to the end and search backwards for the last |
681 ;; marker. Find the start of that message, and begin to search for | 705 ;; marker. Find the start of that message, and begin to search for |
682 ;; unmarked messages from there. | 706 ;; unmarked messages from there. |
683 (when (not (or nnfolder-distrust-mbox | 707 (if (not (or nnfolder-distrust-mbox |
684 (< maxid 2))) | 708 (< maxid 2))) |
685 (goto-char (point-max)) | 709 (progn |
686 (unless (re-search-backward marker nil t) | 710 (goto-char (point-max)) |
687 (goto-char (point-min))) | 711 (if (not (re-search-backward marker nil t)) |
688 (when (nnmail-search-unix-mail-delim) | 712 (goto-char (point-min)) |
689 (goto-char (point-min)))) | 713 (if (not (re-search-backward delim nil t)) |
714 (goto-char (point-min)))))) | |
690 | 715 |
691 ;; Keep track of the active number on our own, and insert it back | 716 ;; Keep track of the active number on our own, and insert it back |
692 ;; into the active list when we're done. Also, prime the pump to | 717 ;; into the active list when we're done. Also, prime the pump to |
693 ;; cut down on the number of searches we do. | 718 ;; cut down on the number of searches we do. |
694 (unless (nnmail-search-unix-mail-delim) | |
695 (goto-char (point-max))) | |
696 (setq end (point-marker)) | 719 (setq end (point-marker)) |
720 (set-marker end (or (and (re-search-forward delim nil t) | |
721 (match-beginning 0)) | |
722 (point-max))) | |
697 (while (not (= end (point-max))) | 723 (while (not (= end (point-max))) |
698 (setq start (marker-position end)) | 724 (setq start (marker-position end)) |
699 (goto-char end) | 725 (goto-char end) |
700 ;; There may be more than one "From " line, so we skip past | 726 ;; There may be more than one "From " line, so we skip past |
701 ;; them. | 727 ;; them. |
702 (while (looking-at delim) | 728 (while (looking-at delim) |
703 (forward-line 1)) | 729 (forward-line 1)) |
704 (set-marker end (if (nnmail-search-unix-mail-delim) | 730 (set-marker end (or (and (re-search-forward delim nil t) |
705 (point) | 731 (match-beginning 0)) |
706 (point-max))) | 732 (point-max))) |
707 (goto-char start) | 733 (goto-char start) |
708 (when (not (search-forward marker end t)) | 734 (if (not (search-forward marker end t)) |
709 (narrow-to-region start end) | 735 (progn |
710 (nnmail-insert-lines) | 736 (narrow-to-region start end) |
711 (nnfolder-insert-newsgroup-line | 737 (nnmail-insert-lines) |
712 (cons nil (nnfolder-active-number nnfolder-current-group))) | 738 (nnfolder-insert-newsgroup-line |
713 (widen))) | 739 (cons nil (nnfolder-active-number nnfolder-current-group))) |
714 | 740 (widen)))) |
715 (set-marker end nil) | 741 |
716 ;; Make absolutely sure that the active list reflects reality! | 742 ;; Make absolutely sure that the active list reflects reality! |
717 (nnmail-save-active nnfolder-group-alist nnfolder-active-file) | 743 (nnmail-save-active nnfolder-group-alist nnfolder-active-file) |
718 ;; Set the scantime for this group. | 744 ;; Set the scantime for this group. |
719 (setq newscantime (visited-file-modtime)) | 745 (setq newscantime (visited-file-modtime)) |
720 (if scantime | 746 (if scantime |
721 (setcdr scantime (list newscantime)) | 747 (setcdr scantime (list newscantime)) |
722 (push (list nnfolder-current-group newscantime) | 748 (push (list nnfolder-current-group newscantime) |
723 nnfolder-scantime-alist)) | 749 nnfolder-scantime-alist)) |
724 (current-buffer)))))) | 750 (current-buffer)))))) |
725 | 751 |
726 ;;;###autoload | 752 ;;;###autoload |
727 (defun nnfolder-generate-active-file () | 753 (defun nnfolder-generate-active-file () |
728 "Look for mbox folders in the nnfolder directory and make them into groups." | 754 "Look for mbox folders in the nnfolder directory and make them into groups." |
729 (interactive) | 755 (interactive) |
730 (nnmail-activate 'nnfolder) | 756 (nnmail-activate 'nnfolder) |
731 (let ((files (directory-files nnfolder-directory)) | 757 (let ((files (directory-files nnfolder-directory)) |
732 file) | 758 file) |
733 (while (setq file (pop files)) | 759 (while (setq file (pop files)) |
734 (when (and (not (backup-file-name-p file)) | 760 (when (and (not (backup-file-name-p file)) |
735 (message-mail-file-mbox-p | 761 (nnheader-mail-file-mbox-p file)) |
736 (nnheader-concat nnfolder-directory file))) | 762 (nnheader-message 5 "Adding group %s..." file) |
737 (let ((oldgroup (assoc file nnfolder-group-alist))) | 763 (push (list file (cons 1 0)) nnfolder-group-alist) |
738 (if oldgroup | 764 (nnfolder-possibly-change-group file) |
739 (nnheader-message 5 "Refreshing group %s..." file) | 765 ;; (nnfolder-read-folder file) |
740 (nnheader-message 5 "Adding group %s..." file)) | 766 (nnfolder-close-group file)) |
741 (setq nnfolder-group-alist (remove oldgroup nnfolder-group-alist)) | 767 (message "")))) |
742 (push (list file (cons 1 0)) nnfolder-group-alist) | |
743 (nnfolder-possibly-change-folder file) | |
744 (nnfolder-possibly-change-group file) | |
745 (nnfolder-close-group file)))) | |
746 (message ""))) | |
747 | 768 |
748 (defun nnfolder-group-pathname (group) | 769 (defun nnfolder-group-pathname (group) |
749 "Make pathname for GROUP." | 770 "Make pathname for GROUP." |
750 (let ((dir (file-name-as-directory (expand-file-name nnfolder-directory)))) | 771 (let ((dir (file-name-as-directory (expand-file-name nnfolder-directory)))) |
751 ;; If this file exists, we use it directly. | 772 ;; If this file exists, we use it directly. |
752 (if (or nnmail-use-long-file-names | 773 (if (or nnmail-use-long-file-names |
753 (file-exists-p (concat dir group))) | 774 (file-exists-p (concat dir group))) |
754 (concat dir group) | 775 (concat dir group) |
755 ;; If not, we translate dots into slashes. | 776 ;; If not, we translate dots into slashes. |
756 (concat dir (nnheader-replace-chars-in-string group ?. ?/))))) | 777 (concat dir (nnheader-replace-chars-in-string group ?. ?/))))) |
757 | 778 |