aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/gnus
diff options
context:
space:
mode:
authorMiles Bader2004-10-22 10:13:52 +0000
committerMiles Bader2004-10-22 10:13:52 +0000
commit5ea24f9468ea9fb01253a98343a67fdb74d1817e (patch)
tree434ee6dc5f051d6deaf0c357b97b656d16e4ed12 /lisp/gnus
parent56c68b971d6f7665dd035df1ff302d794c0f294a (diff)
parentd5ddd795bdab373fe62ccfd099c270fd97da0964 (diff)
downloademacs-5ea24f9468ea9fb01253a98343a67fdb74d1817e.tar.gz
emacs-5ea24f9468ea9fb01253a98343a67fdb74d1817e.zip
Revision: miles@gnu.org--gnu-2004/emacs--unicode--0--patch-62
Merge from emacs--cvs-trunk--0 Patches applied: * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-616 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-620 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-621 Merge from gnus--rel--5.10 * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-622 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-625 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-626 Merge from gnus--rel--5.10 * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-627 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-628 Merge from gnus--rel--5.10 * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-629 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-630 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-631 Merge from gnus--rel--5.10 * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-632 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-633 Merge from gnus--rel--5.10 * miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-51 - miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-52 Update from CVS * miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-53 Merge from emacs--cvs-trunk--0 * miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-54 - miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-55 Update from CVS * miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-56 Update from CVS: Add lisp/legacy-gnus-agent.el * miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-57 - miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-58 Update from CVS
Diffstat (limited to 'lisp/gnus')
-rw-r--r--lisp/gnus/ChangeLog366
-rw-r--r--lisp/gnus/gnus-agent.el1100
-rw-r--r--lisp/gnus/gnus-art.el19
-rw-r--r--lisp/gnus/gnus-cache.el40
-rw-r--r--lisp/gnus/gnus-draft.el74
-rw-r--r--lisp/gnus/gnus-group.el30
-rw-r--r--lisp/gnus/gnus-int.el58
-rw-r--r--lisp/gnus/gnus-range.el67
-rw-r--r--lisp/gnus/gnus-registry.el2
-rw-r--r--lisp/gnus/gnus-start.el258
-rw-r--r--lisp/gnus/gnus-sum.el129
-rw-r--r--lisp/gnus/gnus-util.el30
-rw-r--r--lisp/gnus/imap.el12
-rw-r--r--lisp/gnus/legacy-gnus-agent.el227
-rw-r--r--lisp/gnus/mail-source.el2
-rw-r--r--lisp/gnus/message.el30
-rw-r--r--lisp/gnus/mm-view.el21
-rw-r--r--lisp/gnus/mml.el6
-rw-r--r--lisp/gnus/nnagent.el13
-rw-r--r--lisp/gnus/nnspool.el2
-rw-r--r--lisp/gnus/pop3.el40
-rw-r--r--lisp/gnus/spam-stat.el2
-rw-r--r--lisp/gnus/spam.el8
23 files changed, 1849 insertions, 687 deletions
diff --git a/lisp/gnus/ChangeLog b/lisp/gnus/ChangeLog
index 292d36ce9e1..2a4b0a80398 100644
--- a/lisp/gnus/ChangeLog
+++ b/lisp/gnus/ChangeLog
@@ -1,3 +1,365 @@
12004-10-21 Katsumi Yamaoka <yamaoka@jpl.org>
2
3 * mm-view.el (mm-display-inline-fontify): Inhibit font-lock when
4 running the major-mode function.
5
62004-10-21 Kevin Greiner <kevin.greiner@compsol.cc>
7
8 * gnus-start.el (gnus-convert-old-newsrc): Two of the converters
9 have been backported to 'Gnus v5.11' from 'No Gnus v0.2'. Added a
10 boolean check to not apply converters that apply to future
11 versions of gnus.
12
132004-10-19 Katsumi Yamaoka <yamaoka@jpl.org>
14
15 * gnus-sum.el (gnus-update-summary-mark-positions): Search for
16 dummy marks in the right way.
17
182004-10-18 Kevin Greiner <kevin.greiner@compsol.cc>
19
20 * nnagent.el (nnagent-request-type): Bind gnus-agent to nil to
21 avoid infinite recursion via gnus-get-function.
22
232004-10-18 Kevin Greiner <kevin.greiner@compsol.cc>
24
25 * gnus-agent.el (gnus-agent-synchronize-group-flags): When
26 necessary, pass full group name to gnus-request-set-marks.
27 (gnus-agent-synchronize-group-flags): Added support for sync'ing
28 tick marks.
29 (gnus-agent-synchronize-flags-server): Be silent when writing file.
30
312004-10-18 Kevin Greiner <kevin.greiner@compsol.cc>
32
33 * gnus-agent.el (gnus-agent-synchronize-group-flags): Replaced
34 gnus-request-update-info with explicit code to sync the in-memory
35 info read flags with the marks being sync'd to the backend.
36
372004-10-18 Kevin Greiner <kevin.greiner@compsol.cc>
38
39 * gnus-agent.el (gnus-agent-possibly-synchronize-flags): Ignore
40 servers that are offline. Avoids having gnus-agent-toggle-plugged
41 first ask if you want to open a server and then, even when you
42 responded with no, asking if you want to synchronize the server's
43 flags.
44 (gnus-agent-synchronize-flags-server): Rewrote read loop to handle
45 multi-line expressions.
46 (gnus-agent-synchronize-group-flags): New internal function.
47 Updates marks in memory (in the info structure) AND in the
48 backend.
49 (gnus-agent-check-overview-buffer): Fixed range of
50 deletion to remove entire duplicate line. Fixes merged article
51 number bug.
52
53 * gnus-util.el (gnus-remassoc): Fixed typo in documentation.
54
55 * nnagent.el (nnagent-request-set-mark): Use
56 gnus-agent-synchronize-group-flags, not backend's request-set-mark
57 method, to ensure that synchronization updates marks in the
58 backend and in the info (in memory) structure.
59
602004-10-18 Kevin Greiner <kevin.greiner@compsol.cc>
61
62 * gnus-agent.el (gnus-agent-synchronize-flags-server): Do nothing
63 unless plugged. Disable the agent so that an open failure causes
64 an error.
65
662004-10-18 Kevin Greiner <kevin.greiner@compsol.cc> for Reiner Steib <Reiner.Steib@gmx.de>
67 * gnus-agent.el (gnus-agent-fetched-hook): Add :version.
68 (gnus-agent-go-online): Change :version.
69 (gnus-agent-expire-unagentized-dirs)
70 (gnus-agent-auto-agentize-methods): Add :version.
71
722004-10-18 Kevin Greiner <kevin.greiner@compsol.cc>
73
74 * legacy-gnus-agent.el (gnus-agent-convert-to-compressed-agentview-prompt):
75 New function. Used internally to only display 'gnus converting
76 files' message when actually necessary.
77
78 * gnus-sum.el (): Removed (require 'gnus-agent) as required
79 methods now autoloaded.
80
81 * gnus-int.el (gnus-request-move-article): Use
82 gnus-agent-unfetch-articles in place of gnus-agent-expire to
83 improve performance.
84
852004-10-18 Kevin Greiner <kevin.greiner@compsol.cc>
86
87 * gnus-agent.el (gnus-agent-cat-groups): rewrote avoiding defsetf
88 to avoid run-time CL dependencies.
89 (gnus-agent-unfetch-articles): New function.
90 (gnus-agent-fetch-headers): Use gnus-agent-braid-nov to validate
91 article numbers even when local .overview file is missing.
92 (gnus-agent-read-article-number): New function. Only accepts
93 27-bit article numbers.
94 (gnus-agent-copy-nov-line, gnus-agent-uncached-articles): Use
95 gnus-agent-read-article-number.
96 (gnus-agent-braid-nov): Rewrote to validate article numbers coming
97 from backend while recognizing that article numbers in .overview
98 must be valid.
99
100 * gnus-start.el (gnus-convert-old-newsrc): Changed message text as
101 some users confused by references to .newsrc when they only have a
102 .newsrc.eld file.
103 (gnus-convert-mark-converter-prompt,
104 gnus-convert-converter-needs-prompt): Fixed use of property list.
105
1062004-10-18 Kevin Greiner <kevin.greiner@compsol.cc> for Katsumi Yamaoka <yamaoka@jpl.org>
107
108 * gnus-agent.el (gnus-agent-restore-gcc): Use ^ and regexp-quote.
109
1102004-10-18 Kevin Greiner <kevin.greiner@compsol.cc> for Lars Magne Ingebrigtsen <larsi@gnus.org>
111
112 * gnus-start.el (gnus-get-unread-articles-in-group): Don't do
113 stuff for non-living groups.
114
1152004-10-18 Kevin Greiner <kevin.greiner@compsol.cc> for Lars Magne Ingebrigtsen <larsi@gnus.org>
116
117 * gnus-agent.el (gnus-agent-synchronize-flags): Default to nil.
118 (gnus-agent-regenerate-group): Using nil messages aren't valid.
119
1202004-10-18 Kevin Greiner <kevin.greiner@compsol.cc> for Lars Magne Ingebrigtsen <larsi@gnus.org>
121
122 * gnus-agent.el (gnus-agent-read-agentview): Inline
123 gnus-uncompress-range.
124
1252004-10-18 Kevin Greiner <kgreiner@xpediantsolutions.com>
126
127 * legacy-gnus-agent.el
128 (gnus-agent-convert-to-compressed-agentview): Fixed typos with
129 help from Florian Weimer <fw@deneb.enyo.de>
130
131 * gnus-agent.el (gnus-agentize):
132 gnus-agent-send-mail-real-function no longer set to current value
133 of message-send-mail-function but rather a lambda that calls
134 message-send-mail-function. The change makes the agent real-time
135 responsive to user changes to message-send-mail-function.
136
1372004-10-18 Kevin Greiner <kevin.greiner@compsol.cc> for Reiner Steib <Reiner.Steib@gmx.de>
138
139 * gnus-start.el (gnus-get-unread-articles): Fix last commit.
140
1412004-10-18 Kevin Greiner <kgreiner@xpediantsolutions.com>
142
143 * gnus-cache.el (gnus-cache-rename-group): New function.
144 (gnus-cache-delete-group): New function.
145
146 * gnus-agent.el (gnus-agent-rename-group): New function.
147 (gnus-agent-delete-group): New function.
148 (gnus-agent-save-group-info): Use gnus-command-method when
149 `method' parameter is nil. Don't write nil entries into the
150 active file.
151 (gnus-agent-get-group-info): New function.
152 (gnus-agent-get-local): Added optional parameters to avoid calling
153 gnus-group-real-name and gnus-find-method-for-group.
154 (gnus-agent-set-local): Delete stored entry if either min, or max,
155 are nil.
156 (gnus-agent-fetch-session): Reworded error/quit messages. On
157 quit, use gnus-agent-regenerate-group to record existance of any
158 articles fetched to disk before the quit occurred.
159
160 * gnus-int.el (gnus-request-delete-group): Use
161 gnus-cache-delete-group and gnus-agent-delete-group to keep the
162 local disk in sync with the server.
163 (gnus-request-rename-group): Use
164 gnus-cache-rename-group and gnus-agent-rename-group to keep the
165 local disk in sync with the server.
166
167 * gnus-start.el (gnus-get-unread-articles): Cosmetic
168 simplification to logic.
169
170 * gnus-group.el (): (gnus-group-delete-group): No longer update
171 gnus-cache-active-altered as gnus-request-delete-group now keeps
172 the cache in sync.
173 (gnus-group-list-active): Let the agent store a server's active
174 list if currently plugged.
175
176 * gnus-util.el (gnus-rename-file): New function.
177
1782004-10-18 Kevin Greiner <kevin.greiner@compsol.cc> for Katsumi Yamaoka <yamaoka@jpl.org>
179
180 * gnus-agent.el (gnus-agent-regenerate-group): Activate the group
181 when the group's active is not available.
182
1832004-10-18 Kevin Greiner <kevin.greiner@compsol.cc> for Katsumi Yamaoka <yamaoka@jpl.org>
184
185 * gnus-agent.el (gnus-agent-read-agentview): Add a missing arg to
186 error.
187
1882004-10-18 Kevin Greiner <kevin.greiner@compsol.cc>
189
190 * gnus-start.el (gnus-convert-old-newsrc): Only write the
191 conversion message to newsrc-dribble when an actual conversion is
192 performed.
193
1942004-10-18 Kevin Greiner <kevin.greiner@compsol.cc>
195
196 * gnus-agent.el (gnus-agent-read-local): Bind
197 nnheader-file-coding-system to gnus-agent-file-coding-system to
198 avoid the implicit assumption that they will always be equal.
199 (gnus-agent-save-local): Bind buffer-file-coding-system, not
200 coding-system-for-write, as the with-temp-file macro first prints
201 to a buffer then saves the buffer.
202
2032004-10-18 Kevin Greiner <kgreiner@xpediantsolutions.com>
204
205 * legacy-gnus-agent.el (): New. Provides converters that are only
206 loaded when gnus-convert-old-newsrc needs to call them.
207
208 * gnus-agent.el (gnus-agent-read-agentview): Removed support for
209 old file versions.
210 (gnus-group-prepare-hook): Removed function that converted list
211 form of gnus-agent-expire-days to group properties.
212
213 * gnus-start.el (gnus-convert-old-newsrc): Registered new
214 converters to handle old agent file formats. Added logic for a
215 "backup before upgrading warning".
216 (gnus-convert-mark-converter-prompt): Developers can mark
217 functions as needing (default), or not needing,
218 gnus-convert-old-newsrc's "backup before upgrading warning".
219 (gnus-convert-converter-needs-prompt): Tests whether the user
220 should be protected from potentially irreversable changes by the
221 function.
222
2232004-10-18 Kevin Greiner <kgreiner@xpediantsolutions.com>
224
225 * gnus-int.el (gnus-request-accept-article): Inform the agent that
226 articles are being added to a group.
227 (gnus-request-replace-article): Inform the agent that articles
228 need to be uncached as the cached contents are no longer valid.
229
230 * gnus-agent.el (gnus-agent-file-header-cache): Removed.
231 (gnus-agent-possibly-alter-active): Avoid null in numeric
232 comparison.
233 (gnus-agent-set-local): Refuse to save null in local object table.
234 (gnus-agent-regenerate-group): The REREAD parameter can now be a
235 list of articles that will be marked as unread.
236
2372004-10-18 Kevin Greiner <kevin.greiner@compsol.cc>
238
239 * gnus-range.el (gnus-sorted-range-intersection): Now accepts
240 single-interval range of the form (min . max). Previously the
241 range had to look like ((min . max)). Likewise, return
242 (min . max) rather than ((min . max)).
243 (gnus-range-map): Use gnus-range-normalize to accept
244 single-interval range.
245
246 * gnus-sum.el (gnus-summary-highlight-line): Articles stored in
247 the cache, but not the agent, now appear with their usual face.
248
2492004-10-18 Kevin Greiner <kevin.greiner@compsol.cc>
250
251 * gnus-sum.el (gnus-adjust-marks): Now correctly handles a list of
252 marks consisting of a single range {for example, (3 . 5)} rather
253 than a list of a single range { ((3 . 5)) }.
254
2552004-10-18 Kevin Greiner <kevin.greiner@compsol.cc>
256
257 * gnus-sum.el (gnus-adjust-marks): Avoid splicing null INTO the
258 uncompressed list.
259
2602004-10-18 Kevin Greiner <kevin.greiner@compsol.cc>
261
262 * gnus-draft.el (gnus-group-send-queue): Pass the group name
263 "nndraft:queue" along to gnus-draft-send. Use
264 gnus-agent-prompt-send-queue.
265 (gnus-draft-send): Rebind gnus-agent-queue-mail to nil when group
266 is "nndraft:queue". Suggested by Gaute Strokkenes
267 <gs234@srcf.ucam.org>
268
269 * gnus-group.el (gnus-group-catchup): Use new
270 gnus-sequence-of-unread-articles, not
271 gnus-list-of-unread-articles, to avoid exhausting memory with huge
272 numbers of articles. Use gnus-range-map to avoid having to
273 uncompress the unread list.
274 (gnus-group-archive-directory,
275 gnus-group-recent-archive-directory): Fixed invalid ange-ftp
276 reference.
277
278 * gnus-range.el (gnus-range-map): Iterate over list or sequence.
279 (gnus-sorted-range-intersection): Intersection of two ranges
280 without requiring that they first be uncompressed.
281
282 * gnus-start.el (gnus-activate-group): Unless blocked by the
283 caller, possibly expand the active range to include both cached
284 and agentized articles.
285 (gnus-convert-old-newsrc): Rewrote in anticipation of having
286 multiple version-dependent converters.
287 (gnus-groups-to-gnus-format): Replaced gnus-agent-save-groups with
288 gnus-agent-save-active.
289 (gnus-save-newsrc-file): Save dirty agent range limits.
290
291 * gnus-sum.el (gnus-select-newgroup): Replaced inline code with
292 gnus-agent-possibly-alter-active.
293 (gnus-adjust-marked-articles): Faster handling of simple lists
294
2952004-10-18 David Edmondson <dme@dme.org>
296
297 * mm-view.el (mm-w3m-cid-retrieve-1): Don't use recursive call
298 excessively.
299
3002004-10-18 Reiner Steib <Reiner.Steib@gmx.de>
301
302 * mml.el (mml-preview): Use `pop-to-buffer'.
303
304 * message.el (message-goto-mail-followup-to): Insert after "To".
305 (message-carefully-insert-headers): Add comment.
306
307 * gnus-sum.el (gnus-summary-make-menu-bar): Add help texts.
308
309 * gnus-art.el (gnus-button-alist): Improve
310 `gnus-button-handle-library' entry.
311
312 * gnus-art.el (gnus-button-alist): Fixed regexp for manual links.
313
314 * gnus-group.el (gnus-group-get-new-news-this-group): Added
315 doc-string.
316
317 * gnus-start.el (gnus-activate-group): Added doc-string.
318
319 * gnus-art.el (gnus-button-handle-man, gnus-button-alist): Try to
320 handle manual section.
321
322 * imap.el (imap-store-password): New variable.
323 (imap-interactive-login): Use it.
324 Suggested by Mark Plaksin <happy@mcplaksin.org>.
325
326 * gnus-art.el (gnus-button-alist, gnus-header-button-alist): Allow
327 / in mailto URLs.
328
329 * spam.el (spam-directory): Derive from `gnus-directory'.
330
331 * gnus-sum.el (gnus-pick-line-number): Add autoload.
332
3332004-10-17 Richard M. Stallman <rms@gnu.org>
334
335 * gnus-registry.el (gnus-registry-unload-hook):
336 Set as a variable with add-hook.
337
338 * nnspool.el (nnspool-spool-directory): Use news-directory instead
339 of news-path.
340
341 * spam-stat.el (spam-stat-unload-hook): Set as a variable w/ add-hook.
342
343 * spam.el: Delete duplicate `provide'.
344 (spam-unload-hook): Set as a variable with add-hook.
345
3462004-10-15 Reiner Steib <Reiner.Steib@gmx.de>
347
348 * pop3.el (pop3-leave-mail-on-server): Describe possible problems
349 in the doc string.
350
351 * message.el (message-ignored-news-headers)
352 (message-ignored-supersedes-headers)
353 (message-ignored-resent-headers)
354 (message-forward-ignored-headers): Improve custom type.
355
3562004-10-15 Simon Josefsson <jas@extundo.com>
357
358 * pop3.el (top-level): Don't require nnheader.
359 (pop3-read-timeout): Add.
360 (pop3-accept-process-output): Add.
361 (pop3-read-response, pop3-retr): Use it.
362
12004-10-13 Katsumi Yamaoka <yamaoka@jpl.org> 3632004-10-13 Katsumi Yamaoka <yamaoka@jpl.org>
2 364
3 * message.el (message-tokenize-header): Fix 2004-09-06 change 365 * message.el (message-tokenize-header): Fix 2004-09-06 change
@@ -9,6 +371,10 @@
9 (tls-certificate-information): New function, based on 371 (tls-certificate-information): New function, based on
10 ssl-certificate-information. 372 ssl-certificate-information.
11 373
3742004-10-11 Reiner Steib <Reiner.Steib@gmx.de>
375
376 * message.el (message-bury): Use `window-dedicated-p'.
377
122004-10-10 Reiner Steib <Reiner.Steib@gmx.de> 3782004-10-10 Reiner Steib <Reiner.Steib@gmx.de>
13 379
14 * gnus-sum.el: Mention that multibyte characters don't work as marks. 380 * gnus-sum.el: Mention that multibyte characters don't work as marks.
diff --git a/lisp/gnus/gnus-agent.el b/lisp/gnus/gnus-agent.el
index 4596c783d32..c62460946ab 100644
--- a/lisp/gnus/gnus-agent.el
+++ b/lisp/gnus/gnus-agent.el
@@ -114,7 +114,7 @@ If nil, only read articles will be expired."
114 :group 'gnus-agent 114 :group 'gnus-agent
115 :type 'function) 115 :type 'function)
116 116
117(defcustom gnus-agent-synchronize-flags 'ask 117(defcustom gnus-agent-synchronize-flags nil
118 "Indicate if flags are synchronized when you plug in. 118 "Indicate if flags are synchronized when you plug in.
119If this is `ask' the hook will query the user." 119If this is `ask' the hook will query the user."
120 :version "21.1" 120 :version "21.1"
@@ -362,9 +362,23 @@ manipulated as follows:
362(gnus-agent-cat-defaccessor 362(gnus-agent-cat-defaccessor
363 gnus-agent-cat-enable-undownloaded-faces agent-enable-undownloaded-faces) 363 gnus-agent-cat-enable-undownloaded-faces agent-enable-undownloaded-faces)
364 364
365
366;; This form is equivalent to defsetf except that it calls make-symbol
367;; whereas defsetf calls gensym (Using gensym creates a run-time
368;; dependency on the CL library).
369
365(eval-and-compile 370(eval-and-compile
366 (defsetf gnus-agent-cat-groups (category) (groups) 371 (define-setf-method gnus-agent-cat-groups (category)
367 (list 'gnus-agent-set-cat-groups category groups))) 372 (let* ((--category--temp-- (make-symbol "--category--"))
373 (--groups--temp-- (make-symbol "--groups--")))
374 (list (list --category--temp--)
375 (list category)
376 (list --groups--temp--)
377 (let* ((category --category--temp--)
378 (groups --groups--temp--))
379 (list (quote gnus-agent-set-cat-groups) category groups))
380 (list (quote gnus-agent-cat-groups) --category--temp--))))
381 )
368 382
369(defun gnus-agent-set-cat-groups (category groups) 383(defun gnus-agent-set-cat-groups (category groups)
370 (unless (eq groups 'ignore) 384 (unless (eq groups 'ignore)
@@ -624,7 +638,7 @@ minor mode in all Gnus buffers."
624 (unless gnus-agent-send-mail-function 638 (unless gnus-agent-send-mail-function
625 (setq gnus-agent-send-mail-function 639 (setq gnus-agent-send-mail-function
626 (or message-send-mail-real-function 640 (or message-send-mail-real-function
627 message-send-mail-function) 641 (function (lambda () (funcall message-send-mail-function))))
628 message-send-mail-real-function 'gnus-agent-send-mail)) 642 message-send-mail-real-function 'gnus-agent-send-mail))
629 643
630 ;; If the servers file doesn't exist, auto-agentize some servers and 644 ;; If the servers file doesn't exist, auto-agentize some servers and
@@ -790,25 +804,39 @@ be a select method."
790 (interactive) 804 (interactive)
791 (save-excursion 805 (save-excursion
792 (dolist (gnus-command-method (gnus-agent-covered-methods)) 806 (dolist (gnus-command-method (gnus-agent-covered-methods))
793 (when (file-exists-p (gnus-agent-lib-file "flags")) 807 (when (and (file-exists-p (gnus-agent-lib-file "flags"))
808 (not (eq (gnus-server-status gnus-command-method) 'offline)))
794 (gnus-agent-possibly-synchronize-flags-server gnus-command-method))))) 809 (gnus-agent-possibly-synchronize-flags-server gnus-command-method)))))
795 810
796(defun gnus-agent-synchronize-flags-server (method) 811(defun gnus-agent-synchronize-flags-server (method)
797 "Synchronize flags set when unplugged for server." 812 "Synchronize flags set when unplugged for server."
798 (let ((gnus-command-method method)) 813 (let ((gnus-command-method method)
814 (gnus-agent nil))
799 (when (file-exists-p (gnus-agent-lib-file "flags")) 815 (when (file-exists-p (gnus-agent-lib-file "flags"))
800 (set-buffer (get-buffer-create " *Gnus Agent flag synchronize*")) 816 (set-buffer (get-buffer-create " *Gnus Agent flag synchronize*"))
801 (erase-buffer) 817 (erase-buffer)
802 (nnheader-insert-file-contents (gnus-agent-lib-file "flags")) 818 (nnheader-insert-file-contents (gnus-agent-lib-file "flags"))
803 (if (null (gnus-check-server gnus-command-method)) 819 (cond ((null gnus-plugged)
804 (gnus-message 1 "Couldn't open server %s" (nth 1 gnus-command-method)) 820 (gnus-message
805 (while (not (eobp)) 821 1 "You must be plugged to synchronize flags with server %s"
806 (if (null (eval (read (current-buffer)))) 822 (nth 1 gnus-command-method)))
807 (gnus-delete-line) 823 ((null (gnus-check-server gnus-command-method))
808 (write-file (gnus-agent-lib-file "flags")) 824 (gnus-message
809 (error "Couldn't set flags from file %s" 825 1 "Couldn't open server %s" (nth 1 gnus-command-method)))
810 (gnus-agent-lib-file "flags")))) 826 (t
811 (delete-file (gnus-agent-lib-file "flags"))) 827 (condition-case err
828 (while t
829 (let ((bgn (point)))
830 (eval (read (current-buffer)))
831 (delete-region bgn (point))))
832 (end-of-file
833 (delete-file (gnus-agent-lib-file "flags")))
834 (error
835 (let ((file (gnus-agent-lib-file "flags")))
836 (write-region (point-min) (point-max)
837 (gnus-agent-lib-file "flags") nil 'silent)
838 (error "Couldn't set flags from file %s due to %s"
839 file (error-message-string err)))))))
812 (kill-buffer nil)))) 840 (kill-buffer nil))))
813 841
814(defun gnus-agent-possibly-synchronize-flags-server (method) 842(defun gnus-agent-possibly-synchronize-flags-server (method)
@@ -820,6 +848,56 @@ be a select method."
820 (cadr method))))) 848 (cadr method)))))
821 (gnus-agent-synchronize-flags-server method))) 849 (gnus-agent-synchronize-flags-server method)))
822 850
851;;;###autoload
852(defun gnus-agent-rename-group (old-group new-group)
853 "Rename fully-qualified OLD-GROUP as NEW-GROUP. Always updates the agent, even when
854disabled, as the old agent files would corrupt gnus when the agent was
855next enabled. Depends upon the caller to determine whether group renaming is supported."
856 (let* ((old-command-method (gnus-find-method-for-group old-group))
857 (old-path (directory-file-name
858 (let (gnus-command-method old-command-method)
859 (gnus-agent-group-pathname old-group))))
860 (new-command-method (gnus-find-method-for-group new-group))
861 (new-path (directory-file-name
862 (let (gnus-command-method new-command-method)
863 (gnus-agent-group-pathname new-group)))))
864 (gnus-rename-file old-path new-path t)
865
866 (let* ((old-real-group (gnus-group-real-name old-group))
867 (new-real-group (gnus-group-real-name new-group))
868 (old-active (gnus-agent-get-group-info old-command-method old-real-group)))
869 (gnus-agent-save-group-info old-command-method old-real-group nil)
870 (gnus-agent-save-group-info new-command-method new-real-group old-active)
871
872 (let ((old-local (gnus-agent-get-local old-group
873 old-real-group old-command-method)))
874 (gnus-agent-set-local old-group
875 nil nil
876 old-real-group old-command-method)
877 (gnus-agent-set-local new-group
878 (car old-local) (cdr old-local)
879 new-real-group new-command-method)))))
880
881;;;###autoload
882(defun gnus-agent-delete-group (group)
883 "Delete fully-qualified GROUP. Always updates the agent, even when
884disabled, as the old agent files would corrupt gnus when the agent was
885next enabled. Depends upon the caller to determine whether group deletion is supported."
886 (let* ((command-method (gnus-find-method-for-group group))
887 (path (directory-file-name
888 (let (gnus-command-method command-method)
889 (gnus-agent-group-pathname group)))))
890 (gnus-delete-file path)
891
892 (let* ((real-group (gnus-group-real-name group)))
893 (gnus-agent-save-group-info command-method real-group nil)
894
895 (let ((local (gnus-agent-get-local group
896 real-group command-method)))
897 (gnus-agent-set-local group
898 nil nil
899 real-group command-method)))))
900
823;;; 901;;;
824;;; Server mode commands 902;;; Server mode commands
825;;; 903;;;
@@ -969,6 +1047,7 @@ article's mark is toggled."
969 gnus-downloadable-mark) 1047 gnus-downloadable-mark)
970 'unread)))) 1048 'unread))))
971 1049
1050;;;###autoload
972(defun gnus-agent-get-undownloaded-list () 1051(defun gnus-agent-get-undownloaded-list ()
973 "Construct list of articles that have not been downloaded." 1052 "Construct list of articles that have not been downloaded."
974 (let ((gnus-command-method (gnus-find-method-for-group gnus-newsgroup-name))) 1053 (let ((gnus-command-method (gnus-find-method-for-group gnus-newsgroup-name)))
@@ -1113,6 +1192,49 @@ This can be added to `gnus-select-article-hook' or
1113;;; Internal functions 1192;;; Internal functions
1114;;; 1193;;;
1115 1194
1195(defun gnus-agent-synchronize-group-flags (group actions server)
1196"Update a plugged group by performing the indicated actions."
1197 (let* ((gnus-command-method (gnus-server-to-method server))
1198 (info
1199 ;; This initializer is required as gnus-request-set-mark
1200 ;; calls gnus-group-real-name to strip off the host name
1201 ;; before calling the backend. Now that the backend is
1202 ;; trying to call gnus-request-set-mark, I have to
1203 ;; reconstruct the original group name.
1204 (or (gnus-get-info group)
1205 (gnus-get-info
1206 (setq group (gnus-group-full-name
1207 group gnus-command-method))))))
1208 (gnus-request-set-mark group actions)
1209
1210 (when info
1211 (dolist (action actions)
1212 (let ((range (nth 0 action))
1213 (what (nth 1 action))
1214 (marks (nth 2 action)))
1215 (dolist (mark marks)
1216 (cond ((eq mark 'read)
1217 (gnus-info-set-read
1218 info
1219 (funcall (if (eq what 'add)
1220 'gnus-range-add
1221 'gnus-remove-from-range)
1222 (gnus-info-read info)
1223 range))
1224 (gnus-get-unread-articles-in-group
1225 info
1226 (gnus-active (gnus-info-group info))))
1227 ((memq mark '(tick))
1228 (let ((info-marks (assoc mark (gnus-info-marks info))))
1229 (unless info-marks
1230 (gnus-info-set-marks info (cons (setq info-marks (list mark)) (gnus-info-marks info))))
1231 (setcdr info-marks (funcall (if (eq what 'add)
1232 'gnus-range-add
1233 'gnus-remove-from-range)
1234 (cdr info-marks)
1235 range)))))))))
1236 nil))
1237
1116(defun gnus-agent-save-active (method) 1238(defun gnus-agent-save-active (method)
1117 (when (gnus-agent-method-p method) 1239 (when (gnus-agent-method-p method)
1118 (let* ((gnus-command-method method) 1240 (let* ((gnus-command-method method)
@@ -1131,6 +1253,7 @@ This can be added to `gnus-select-article-hook' or
1131 ;; will add it while reading the file. 1253 ;; will add it while reading the file.
1132 (gnus-write-active-file file new nil))) 1254 (gnus-write-active-file file new nil)))
1133 1255
1256;;;###autoload
1134(defun gnus-agent-possibly-alter-active (group active &optional info) 1257(defun gnus-agent-possibly-alter-active (group active &optional info)
1135 "Possibly expand a group's active range to include articles 1258 "Possibly expand a group's active range to include articles
1136downloaded into the agent." 1259downloaded into the agent."
@@ -1183,7 +1306,7 @@ downloaded into the agent."
1183(defun gnus-agent-save-group-info (method group active) 1306(defun gnus-agent-save-group-info (method group active)
1184 "Update a single group's active range in the agent's copy of the server's active file." 1307 "Update a single group's active range in the agent's copy of the server's active file."
1185 (when (gnus-agent-method-p method) 1308 (when (gnus-agent-method-p method)
1186 (let* ((gnus-command-method method) 1309 (let* ((gnus-command-method (or method gnus-command-method))
1187 (coding-system-for-write nnheader-file-coding-system) 1310 (coding-system-for-write nnheader-file-coding-system)
1188 (file-name-coding-system nnmail-pathname-coding-system) 1311 (file-name-coding-system nnmail-pathname-coding-system)
1189 (file (gnus-agent-lib-file "active")) 1312 (file (gnus-agent-lib-file "active"))
@@ -1199,15 +1322,39 @@ downloaded into the agent."
1199 (when (re-search-forward 1322 (when (re-search-forward
1200 (concat "^" (regexp-quote group) " ") nil t) 1323 (concat "^" (regexp-quote group) " ") nil t)
1201 (save-excursion 1324 (save-excursion
1202 (setq oactive-max (read (current-buffer)) ;; max 1325 (setq oactive-max (read (current-buffer)) ;; max
1203 oactive-min (read (current-buffer)))) ;; min 1326 oactive-min (read (current-buffer)))) ;; min
1204 (gnus-delete-line))) 1327 (gnus-delete-line)))
1205 (insert (format "%S %d %d y\n" (intern group) 1328 (when active
1206 (max (or oactive-max (cdr active)) (cdr active)) 1329 (insert (format "%S %d %d y\n" (intern group)
1207 (min (or oactive-min (car active)) (car active)))) 1330 (max (or oactive-max (cdr active)) (cdr active))
1208 (goto-char (point-max)) 1331 (min (or oactive-min (car active)) (car active))))
1209 (while (search-backward "\\." nil t) 1332 (goto-char (point-max))
1210 (delete-char 1)))))) 1333 (while (search-backward "\\." nil t)
1334 (delete-char 1)))))))
1335
1336(defun gnus-agent-get-group-info (method group)
1337 "Get a single group's active range in the agent's copy of the server's active file."
1338 (when (gnus-agent-method-p method)
1339 (let* ((gnus-command-method (or method gnus-command-method))
1340 (coding-system-for-write nnheader-file-coding-system)
1341 (file-name-coding-system nnmail-pathname-coding-system)
1342 (file (gnus-agent-lib-file "active"))
1343 oactive-min oactive-max)
1344 (gnus-make-directory (file-name-directory file))
1345 (with-temp-buffer
1346 ;; Emacs got problem to match non-ASCII group in multibyte buffer.
1347 (mm-disable-multibyte)
1348 (when (file-exists-p file)
1349 (nnheader-insert-file-contents file)
1350
1351 (goto-char (point-min))
1352 (when (re-search-forward
1353 (concat "^" (regexp-quote group) " ") nil t)
1354 (save-excursion
1355 (setq oactive-max (read (current-buffer)) ;; max
1356 oactive-min (read (current-buffer))) ;; min
1357 (cons oactive-min oactive-max))))))))
1211 1358
1212(defun gnus-agent-group-path (group) 1359(defun gnus-agent-group-path (group)
1213 "Translate GROUP into a file name." 1360 "Translate GROUP into a file name."
@@ -1413,6 +1560,31 @@ downloaded into the agent."
1413 (gnus-message 7 "")) 1560 (gnus-message 7 ""))
1414 (cdr fetched-articles)))))) 1561 (cdr fetched-articles))))))
1415 1562
1563(defun gnus-agent-unfetch-articles (group articles)
1564 "Delete ARTICLES that were fetched from GROUP into the agent."
1565 (when articles
1566 (gnus-agent-load-alist group)
1567 (let* ((alist (cons nil gnus-agent-article-alist))
1568 (articles (sort articles #'<))
1569 (next-possibility alist)
1570 (delete-this (pop articles)))
1571 (while (and (cdr next-possibility) delete-this)
1572 (let ((have-this (caar (cdr next-possibility))))
1573 (cond ((< delete-this have-this)
1574 (setq delete-this (pop articles)))
1575 ((= delete-this have-this)
1576 (let ((timestamp (cdar (cdr next-possibility))))
1577 (when timestamp
1578 (let* ((file-name (concat (gnus-agent-group-pathname group)
1579 (number-to-string have-this))))
1580 (delete-file file-name))))
1581
1582 (setcdr next-possibility (cddr next-possibility)))
1583 (t
1584 (setq next-possibility (cdr next-possibility))))))
1585 (setq gnus-agent-article-alist (cdr alist))
1586 (gnus-agent-save-alist group))))
1587
1416(defun gnus-agent-crosspost (crosses article &optional date) 1588(defun gnus-agent-crosspost (crosses article &optional date)
1417 (setq date (or date t)) 1589 (setq date (or date t))
1418 1590
@@ -1487,7 +1659,7 @@ and that there are no duplicates."
1487 (setq backed-up (gnus-agent-backup-overview-buffer))) 1659 (setq backed-up (gnus-agent-backup-overview-buffer)))
1488 (gnus-message 1 1660 (gnus-message 1
1489 "Duplicate overview line for %d" cur) 1661 "Duplicate overview line for %d" cur)
1490 (delete-region (point) (progn (forward-line 1) (point)))) 1662 (delete-region p (progn (forward-line 1) (point))))
1491 ((< cur prev-num) 1663 ((< cur prev-num)
1492 (or backed-up 1664 (or backed-up
1493 (setq backed-up (gnus-agent-backup-overview-buffer))) 1665 (setq backed-up (gnus-agent-backup-overview-buffer)))
@@ -1519,6 +1691,7 @@ and that there are no duplicates."
1519 (insert "\n")) 1691 (insert "\n"))
1520 (setq gnus-agent-group-alist (cdr gnus-agent-group-alist))))) 1692 (setq gnus-agent-group-alist (cdr gnus-agent-group-alist)))))
1521 1693
1694;;;###autoload
1522(defun gnus-agent-find-parameter (group symbol) 1695(defun gnus-agent-find-parameter (group symbol)
1523 "Search for GROUPs SYMBOL in the group's parameters, the group's 1696 "Search for GROUPs SYMBOL in the group's parameters, the group's
1524topic parameters, the group's category, or the customizable 1697topic parameters, the group's category, or the customizable
@@ -1623,8 +1796,10 @@ article numbers will be returned."
1623 ;; of FILE. 1796 ;; of FILE.
1624 (copy-to-buffer 1797 (copy-to-buffer
1625 gnus-agent-overview-buffer (point-min) (point-max)) 1798 gnus-agent-overview-buffer (point-min) (point-max))
1626 (when (file-exists-p file) 1799 ;; NOTE: Call g-a-brand-nov even when the file does not
1627 (gnus-agent-braid-nov group articles file)) 1800 ;; exist. As a minimum, it will validate the article
1801 ;; numbers already in the buffer.
1802 (gnus-agent-braid-nov group articles file)
1628 (let ((coding-system-for-write 1803 (let ((coding-system-for-write
1629 gnus-agent-file-coding-system)) 1804 gnus-agent-file-coding-system))
1630 (gnus-agent-check-overview-buffer) 1805 (gnus-agent-check-overview-buffer)
@@ -1636,11 +1811,32 @@ article numbers will be returned."
1636 (nnheader-insert-file-contents file))))) 1811 (nnheader-insert-file-contents file)))))
1637 articles)) 1812 articles))
1638 1813
1814(defsubst gnus-agent-read-article-number ()
1815 "Reads the article number at point. Returns nil when a valid article number can not be read."
1816
1817 ;; It is unfortunite but the read function quietly overflows
1818 ;; integer. As a result, I have to use string operations to test
1819 ;; for overflow BEFORE calling read.
1820 (when (looking-at "[0-9]+\t")
1821 (let ((len (- (match-end 0) (match-beginning 0))))
1822 (cond ((< len 9)
1823 (read (current-buffer)))
1824 ((= len 9)
1825 ;; Many 9 digit base-10 numbers can be represented in a 27-bit int
1826 ;; Back convert from int to string to ensure that this is one of them.
1827 (let* ((str1 (buffer-substring (match-beginning 0) (1- (match-end 0))))
1828 (num (read (current-buffer)))
1829 (str2 (int-to-string num)))
1830 (when (equal str1 str2)
1831 num)))))))
1832
1639(defsubst gnus-agent-copy-nov-line (article) 1833(defsubst gnus-agent-copy-nov-line (article)
1834 "Copy the indicated ARTICLE from the overview buffer to the nntp server buffer."
1640 (let (art b e) 1835 (let (art b e)
1641 (set-buffer gnus-agent-overview-buffer) 1836 (set-buffer gnus-agent-overview-buffer)
1642 (while (and (not (eobp)) 1837 (while (and (not (eobp))
1643 (< (setq art (read (current-buffer))) article)) 1838 (or (not (setq art (gnus-agent-read-article-number)))
1839 (< art article)))
1644 (forward-line 1)) 1840 (forward-line 1))
1645 (beginning-of-line) 1841 (beginning-of-line)
1646 (if (or (eobp) 1842 (if (or (eobp)
@@ -1653,64 +1849,77 @@ article numbers will be returned."
1653 1849
1654(defun gnus-agent-braid-nov (group articles file) 1850(defun gnus-agent-braid-nov (group articles file)
1655 "Merge agent overview data with given file. 1851 "Merge agent overview data with given file.
1656Takes headers for ARTICLES from `gnus-agent-overview-buffer' and the given 1852Takes unvalidated headers for ARTICLES from
1657FILE and places the combined headers into `nntp-server-buffer'." 1853`gnus-agent-overview-buffer' and validated headers from the given
1854FILE and places the combined valid headers into
1855`nntp-server-buffer'. This function can be used, when file
1856doesn't exist, to valid the overview buffer."
1658 (let (start last) 1857 (let (start last)
1659 (set-buffer gnus-agent-overview-buffer) 1858 (set-buffer gnus-agent-overview-buffer)
1660 (goto-char (point-min)) 1859 (goto-char (point-min))
1661 (set-buffer nntp-server-buffer) 1860 (set-buffer nntp-server-buffer)
1662 (erase-buffer) 1861 (erase-buffer)
1663 (nnheader-insert-file-contents file) 1862 (when (file-exists-p file)
1863 (nnheader-insert-file-contents file))
1664 (goto-char (point-max)) 1864 (goto-char (point-max))
1665 (forward-line -1) 1865 (forward-line -1)
1666 (unless (looking-at "[0-9]+\t") 1866
1667 ;; Remove corrupted lines
1668 (gnus-message
1669 1 "Overview %s is corrupted. Removing corrupted lines..." file)
1670 (goto-char (point-min))
1671 (while (not (eobp))
1672 (if (looking-at "[0-9]+\t")
1673 (forward-line 1)
1674 (delete-region (point) (progn (forward-line 1) (point)))))
1675 (forward-line -1))
1676 (unless (or (= (point-min) (point-max)) 1867 (unless (or (= (point-min) (point-max))
1677 (< (setq last (read (current-buffer))) (car articles))) 1868 (< (setq last (read (current-buffer))) (car articles)))
1678 ;; We do it the hard way. 1869 ;; Old and new overlap -- We do it the hard way.
1679 (when (nnheader-find-nov-line (car articles)) 1870 (when (nnheader-find-nov-line (car articles))
1680 ;; Replacing existing NOV entry 1871 ;; Replacing existing NOV entry
1681 (delete-region (point) (progn (forward-line 1) (point)))) 1872 (delete-region (point) (progn (forward-line 1) (point))))
1682 (gnus-agent-copy-nov-line (pop articles)) 1873 (gnus-agent-copy-nov-line (pop articles))
1683 1874
1684 (ignore-errors 1875 (ignore-errors
1685 (while articles 1876 (while articles
1686 (while (let ((art (read (current-buffer)))) 1877 (while (let ((art (read (current-buffer))))
1687 (cond ((< art (car articles)) 1878 (cond ((< art (car articles))
1688 (forward-line 1) 1879 (forward-line 1)
1689 t) 1880 t)
1690 ((= art (car articles)) 1881 ((= art (car articles))
1691 (beginning-of-line) 1882 (beginning-of-line)
1692 (delete-region 1883 (delete-region
1693 (point) (progn (forward-line 1) (point))) 1884 (point) (progn (forward-line 1) (point)))
1694 nil) 1885 nil)
1695 (t 1886 (t
1696 (beginning-of-line) 1887 (beginning-of-line)
1697 nil)))) 1888 nil))))
1698 1889
1699 (gnus-agent-copy-nov-line (pop articles))))) 1890 (gnus-agent-copy-nov-line (pop articles)))))
1700 1891
1701 ;; Copy the rest lines
1702 (set-buffer nntp-server-buffer)
1703 (goto-char (point-max)) 1892 (goto-char (point-max))
1893
1894 ;; Append the remaining lines
1704 (when articles 1895 (when articles
1705 (when last 1896 (when last
1706 (set-buffer gnus-agent-overview-buffer) 1897 (set-buffer gnus-agent-overview-buffer)
1707 (ignore-errors
1708 (while (<= (read (current-buffer)) last)
1709 (forward-line 1)))
1710 (beginning-of-line)
1711 (setq start (point)) 1898 (setq start (point))
1712 (set-buffer nntp-server-buffer)) 1899 (set-buffer nntp-server-buffer))
1713 (insert-buffer-substring gnus-agent-overview-buffer start)))) 1900
1901 (let ((p (point)))
1902 (insert-buffer-substring gnus-agent-overview-buffer start)
1903 (goto-char p))
1904
1905 (setq last (or last -134217728))
1906 (let (sort art)
1907 (while (not (eobp))
1908 (setq art (gnus-agent-read-article-number))
1909 (cond ((not art)
1910 ;; Bad art num - delete this line
1911 (beginning-of-line)
1912 (delete-region (point) (progn (forward-line 1) (point))))
1913 ((< art last)
1914 ;; Art num out of order - enable sort
1915 (setq sort t)
1916 (forward-line 1))
1917 (t
1918 ;; Good art num
1919 (setq last art)
1920 (forward-line 1))))
1921 (when sort
1922 (sort-numeric-fields 1 (point-min) (point-max)))))))
1714 1923
1715;; Keeps the compiler from warning about the free variable in 1924;; Keeps the compiler from warning about the free variable in
1716;; gnus-agent-read-agentview. 1925;; gnus-agent-read-agentview.
@@ -1735,7 +1944,8 @@ FILE and places the combined headers into `nntp-server-buffer'."
1735(defun gnus-agent-read-agentview (file) 1944(defun gnus-agent-read-agentview (file)
1736 "Load FILE and do a `read' there." 1945 "Load FILE and do a `read' there."
1737 (with-temp-buffer 1946 (with-temp-buffer
1738 (ignore-errors 1947 (condition-case nil
1948 (progn
1739 (nnheader-insert-file-contents file) 1949 (nnheader-insert-file-contents file)
1740 (goto-char (point-min)) 1950 (goto-char (point-min))
1741 (let ((alist (read (current-buffer))) 1951 (let ((alist (read (current-buffer)))
@@ -1744,6 +1954,8 @@ FILE and places the combined headers into `nntp-server-buffer'."
1744 changed-version) 1954 changed-version)
1745 1955
1746 (cond 1956 (cond
1957 ((< version 2)
1958 (error "gnus-agent-read-agentview no longer supports version %d. Stop gnus, manually evaluate gnus-agent-convert-to-compressed-agentview, then restart gnus." version))
1747 ((= version 0) 1959 ((= version 0)
1748 (let ((inhibit-quit t) 1960 (let ((inhibit-quit t)
1749 entry) 1961 entry)
@@ -1767,8 +1979,9 @@ FILE and places the combined headers into `nntp-server-buffer'."
1767 (mapcar 1979 (mapcar
1768 (lambda (comp-list) 1980 (lambda (comp-list)
1769 (let ((state (car comp-list)) 1981 (let ((state (car comp-list))
1770 (sequence (gnus-uncompress-sequence 1982 (sequence (inline
1771 (cdr comp-list)))) 1983 (gnus-uncompress-range
1984 (cdr comp-list)))))
1772 (mapcar (lambda (article-id) 1985 (mapcar (lambda (article-id)
1773 (setq uncomp (cons (cons article-id state) uncomp))) 1986 (setq uncomp (cons (cons article-id state) uncomp)))
1774 sequence))) 1987 sequence)))
@@ -1777,7 +1990,8 @@ FILE and places the combined headers into `nntp-server-buffer'."
1777 (when changed-version 1990 (when changed-version
1778 (let ((gnus-agent-article-alist alist)) 1991 (let ((gnus-agent-article-alist alist))
1779 (gnus-agent-save-alist gnus-agent-read-agentview))) 1992 (gnus-agent-save-alist gnus-agent-read-agentview)))
1780 alist)))) 1993 alist))
1994 (file-error nil))))
1781 1995
1782(defun gnus-agent-save-alist (group &optional articles state) 1996(defun gnus-agent-save-alist (group &optional articles state)
1783 "Save the article-state alist for GROUP." 1997 "Save the article-state alist for GROUP."
@@ -1860,7 +2074,8 @@ modified) original contents, they are first saved to their own file."
1860 (line 1)) 2074 (line 1))
1861 (with-temp-buffer 2075 (with-temp-buffer
1862 (condition-case nil 2076 (condition-case nil
1863 (nnheader-insert-file-contents file) 2077 (let ((nnheader-file-coding-system gnus-agent-file-coding-system))
2078 (nnheader-insert-file-contents file))
1864 (file-error)) 2079 (file-error))
1865 2080
1866 (goto-char (point-min)) 2081 (goto-char (point-min))
@@ -1903,31 +2118,31 @@ modified) original contents, they are first saved to their own file."
1903 ;; NOTE: gnus-command-method is used within gnus-agent-lib-file. 2118 ;; NOTE: gnus-command-method is used within gnus-agent-lib-file.
1904 (dest (gnus-agent-lib-file "local"))) 2119 (dest (gnus-agent-lib-file "local")))
1905 (gnus-make-directory (gnus-agent-lib-file "")) 2120 (gnus-make-directory (gnus-agent-lib-file ""))
1906 (with-temp-file dest 2121
1907 (let ((gnus-command-method (symbol-value (intern "+method" my-obarray))) 2122 (let ((buffer-file-coding-system gnus-agent-file-coding-system))
1908 (file-name-coding-system nnmail-pathname-coding-system) 2123 (with-temp-file dest
1909 (coding-system-for-write 2124 (let ((gnus-command-method (symbol-value (intern "+method" my-obarray)))
1910 gnus-agent-file-coding-system) 2125 (file-name-coding-system nnmail-pathname-coding-system)
1911 print-level print-length item article 2126 print-level print-length item article
1912 (standard-output (current-buffer))) 2127 (standard-output (current-buffer)))
1913 (mapatoms (lambda (symbol) 2128 (mapatoms (lambda (symbol)
1914 (cond ((not (boundp symbol)) 2129 (cond ((not (boundp symbol))
1915 nil) 2130 nil)
1916 ((member (symbol-name symbol) '("+dirty" "+method")) 2131 ((member (symbol-name symbol) '("+dirty" "+method"))
1917 nil) 2132 nil)
1918 (t 2133 (t
1919 (prin1 symbol) 2134 (prin1 symbol)
1920 (let ((range (symbol-value symbol))) 2135 (let ((range (symbol-value symbol)))
1921 (princ " ") 2136 (princ " ")
1922 (princ (car range)) 2137 (princ (car range))
1923 (princ " ") 2138 (princ " ")
1924 (princ (cdr range)) 2139 (princ (cdr range))
1925 (princ "\n"))))) 2140 (princ "\n")))))
1926 my-obarray))))))) 2141 my-obarray))))))))
1927 2142
1928(defun gnus-agent-get-local (group) 2143(defun gnus-agent-get-local (group &optional gmane method)
1929 (let* ((gmane (gnus-group-real-name group)) 2144 (let* ((gmane (or gmane (gnus-group-real-name group)))
1930 (gnus-command-method (gnus-find-method-for-group group)) 2145 (gnus-command-method (or method (gnus-find-method-for-group group)))
1931 (local (gnus-agent-load-local)) 2146 (local (gnus-agent-load-local))
1932 (symb (intern gmane local)) 2147 (symb (intern gmane local))
1933 (minmax (and (boundp symb) (symbol-value symb)))) 2148 (minmax (and (boundp symb) (symbol-value symb))))
@@ -1962,7 +2177,9 @@ modified) original contents, they are first saved to their own file."
1962 nil) 2177 nil)
1963 ((and min max) 2178 ((and min max)
1964 (set symb (cons min max)) 2179 (set symb (cons min max))
1965 t)) 2180 t)
2181 (t
2182 (unintern symb local)))
1966 (set (intern "+dirty" local) t)))) 2183 (set (intern "+dirty" local) t))))
1967 2184
1968(defun gnus-agent-article-name (article group) 2185(defun gnus-agent-article-name (article group)
@@ -2012,13 +2229,14 @@ modified) original contents, they are first saved to their own file."
2012 group gnus-command-method) 2229 group gnus-command-method)
2013 (error 2230 (error
2014 (unless (funcall gnus-agent-confirmation-function 2231 (unless (funcall gnus-agent-confirmation-function
2015 (format "Error %s. Continue? " 2232 (format "Error %s while fetching session. Should gnus continue? "
2016 (error-message-string err))) 2233 (error-message-string err)))
2017 (error "Cannot fetch articles into the Gnus agent"))) 2234 (error "Cannot fetch articles into the Gnus agent")))
2018 (quit 2235 (quit
2236 (gnus-agent-regenerate-group group)
2019 (unless (funcall gnus-agent-confirmation-function 2237 (unless (funcall gnus-agent-confirmation-function
2020 (format 2238 (format
2021 "Quit fetching session %s. Continue? " 2239 "%s while fetching session. Should gnus continue? "
2022 (error-message-string err))) 2240 (error-message-string err)))
2023 (signal 'quit 2241 (signal 'quit
2024 "Cannot fetch articles into the Gnus agent"))))))))) 2242 "Cannot fetch articles into the Gnus agent")))))))))
@@ -2736,328 +2954,334 @@ FORCE is equivalent to setting the expiration predicates to true."
2736 (let ((dir (gnus-agent-group-pathname group))) 2954 (let ((dir (gnus-agent-group-pathname group)))
2737 (when (boundp 'gnus-agent-expire-current-dirs) 2955 (when (boundp 'gnus-agent-expire-current-dirs)
2738 (set 'gnus-agent-expire-current-dirs 2956 (set 'gnus-agent-expire-current-dirs
2739 (cons dir 2957 (cons dir
2740 (symbol-value 'gnus-agent-expire-current-dirs)))) 2958 (symbol-value 'gnus-agent-expire-current-dirs))))
2741 2959
2742 (if (and (not force) 2960 (if (and (not force)
2743 (eq 'DISABLE (gnus-agent-find-parameter group 2961 (eq 'DISABLE (gnus-agent-find-parameter group
2744 'agent-enable-expiration))) 2962 'agent-enable-expiration)))
2745 (gnus-message 5 "Expiry skipping over %s" group) 2963 (gnus-message 5 "Expiry skipping over %s" group)
2746 (gnus-message 5 "Expiring articles in %s" group) 2964 (gnus-message 5 "Expiring articles in %s" group)
2747 (gnus-agent-load-alist group) 2965 (gnus-agent-load-alist group)
2748 (let* ((stats (if (boundp 'gnus-agent-expire-stats) 2966 (let* ((bytes-freed 0)
2749 ;; Use the list provided by my caller 2967 (files-deleted 0)
2750 (symbol-value 'gnus-agent-expire-stats) 2968 (nov-entries-deleted 0)
2751 ;; otherwise use my own temporary list 2969 (info (gnus-get-info group))
2752 (list 0 0 0.0))) 2970 (alist gnus-agent-article-alist)
2753 (info (gnus-get-info group)) 2971 (day (- (time-to-days (current-time))
2754 (alist gnus-agent-article-alist) 2972 (gnus-agent-find-parameter group 'agent-days-until-old)))
2755 (day (- (time-to-days (current-time)) 2973 (specials (if (and alist
2756 (gnus-agent-find-parameter group 'agent-days-until-old))) 2974 (not force))
2757 (specials (if (and alist 2975 ;; This could be a bit of a problem. I need to
2758 (not force)) 2976 ;; keep the last article to avoid refetching
2759 ;; This could be a bit of a problem. I need to 2977 ;; headers when using nntp in the backend. At
2760 ;; keep the last article to avoid refetching 2978 ;; the same time, if someone uses a backend
2761 ;; headers when using nntp in the backend. At 2979 ;; that supports article moving then I may have
2762 ;; the same time, if someone uses a backend 2980 ;; to remove the last article to complete the
2763 ;; that supports article moving then I may have 2981 ;; move. Right now, I'm going to assume that
2764 ;; to remove the last article to complete the 2982 ;; FORCE overrides specials.
2765 ;; move. Right now, I'm going to assume that 2983 (list (caar (last alist)))))
2766 ;; FORCE overrides specials. 2984 (unreads ;; Articles that are excluded from the
2767 (list (caar (last alist))))) 2985 ;; expiration process
2768 (unreads ;; Articles that are excluded from the 2986 (cond (gnus-agent-expire-all
2769 ;; expiration process 2987 ;; All articles are marked read by global decree
2770 (cond (gnus-agent-expire-all 2988 nil)
2771 ;; All articles are marked read by global decree 2989 ((eq articles t)
2772 nil) 2990 ;; All articles are marked read by function
2773 ((eq articles t) 2991 ;; parameter
2774 ;; All articles are marked read by function 2992 nil)
2775 ;; parameter 2993 ((not articles)
2776 nil) 2994 ;; Unread articles are marked protected from
2777 ((not articles) 2995 ;; expiration Don't call
2778 ;; Unread articles are marked protected from 2996 ;; gnus-list-of-unread-articles as it returns
2779 ;; expiration Don't call 2997 ;; articles that have not been fetched into the
2780 ;; gnus-list-of-unread-articles as it returns 2998 ;; agent.
2781 ;; articles that have not been fetched into the 2999 (ignore-errors
2782 ;; agent. 3000 (gnus-agent-unread-articles group)))
2783 (ignore-errors 3001 (t
2784 (gnus-agent-unread-articles group))) 3002 ;; All articles EXCEPT those named by the caller
2785 (t 3003 ;; are protected from expiration
2786 ;; All articles EXCEPT those named by the caller 3004 (gnus-sorted-difference
2787 ;; are protected from expiration 3005 (gnus-uncompress-range
2788 (gnus-sorted-difference 3006 (cons (caar alist)
2789 (gnus-uncompress-range 3007 (caar (last alist))))
2790 (cons (caar alist) 3008 (sort articles '<)))))
2791 (caar (last alist)))) 3009 (marked ;; More articles that are excluded from the
2792 (sort articles '<))))) 3010 ;; expiration process
2793 (marked ;; More articles that are excluded from the 3011 (cond (gnus-agent-expire-all
2794 ;; expiration process 3012 ;; All articles are unmarked by global decree
2795 (cond (gnus-agent-expire-all 3013 nil)
2796 ;; All articles are unmarked by global decree 3014 ((eq articles t)
2797 nil) 3015 ;; All articles are unmarked by function
2798 ((eq articles t) 3016 ;; parameter
2799 ;; All articles are unmarked by function 3017 nil)
2800 ;; parameter 3018 (articles
2801 nil) 3019 ;; All articles may as well be unmarked as the
2802 (articles 3020 ;; unreads list already names the articles we are
2803 ;; All articles may as well be unmarked as the 3021 ;; going to keep
2804 ;; unreads list already names the articles we are 3022 nil)
2805 ;; going to keep 3023 (t
2806 nil) 3024 ;; Ticked and/or dormant articles are excluded
2807 (t 3025 ;; from expiration
2808 ;; Ticked and/or dormant articles are excluded 3026 (nconc
2809 ;; from expiration 3027 (gnus-uncompress-range
2810 (nconc 3028 (cdr (assq 'tick (gnus-info-marks info))))
2811 (gnus-uncompress-range 3029 (gnus-uncompress-range
2812 (cdr (assq 'tick (gnus-info-marks info)))) 3030 (cdr (assq 'dormant
2813 (gnus-uncompress-range 3031 (gnus-info-marks info))))))))
2814 (cdr (assq 'dormant 3032 (nov-file (concat dir ".overview"))
2815 (gnus-info-marks info)))))))) 3033 (cnt 0)
2816 (nov-file (concat dir ".overview")) 3034 (completed -1)
2817 (cnt 0) 3035 dlist
2818 (completed -1) 3036 type)
2819 dlist 3037
2820 type) 3038 ;; The normal article alist contains elements that look like
2821 3039 ;; (article# . fetch_date) I need to combine other
2822 ;; The normal article alist contains elements that look like 3040 ;; information with this list. For example, a flag indicating
2823 ;; (article# . fetch_date) I need to combine other 3041 ;; that a particular article MUST BE KEPT. To do this, I'm
2824 ;; information with this list. For example, a flag indicating 3042 ;; going to transform the elements to look like (article#
2825 ;; that a particular article MUST BE KEPT. To do this, I'm 3043 ;; fetch_date keep_flag NOV_entry_marker) Later, I'll reverse
2826 ;; going to transform the elements to look like (article# 3044 ;; the process to generate the expired article alist.
2827 ;; fetch_date keep_flag NOV_entry_marker) Later, I'll reverse 3045
2828 ;; the process to generate the expired article alist. 3046 ;; Convert the alist elements to (article# fetch_date nil
2829 3047 ;; nil).
2830 ;; Convert the alist elements to (article# fetch_date nil 3048 (setq dlist (mapcar (lambda (e)
2831 ;; nil). 3049 (list (car e) (cdr e) nil nil)) alist))
2832 (setq dlist (mapcar (lambda (e) 3050
2833 (list (car e) (cdr e) nil nil)) alist)) 3051 ;; Convert the keep lists to elements that look like (article#
2834 3052 ;; nil keep_flag nil) then append it to the expanded dlist
2835 ;; Convert the keep lists to elements that look like (article# 3053 ;; These statements are sorted by ascending precidence of the
2836 ;; nil keep_flag nil) then append it to the expanded dlist 3054 ;; keep_flag.
2837 ;; These statements are sorted by ascending precidence of the 3055 (setq dlist (nconc dlist
2838 ;; keep_flag. 3056 (mapcar (lambda (e)
2839 (setq dlist (nconc dlist 3057 (list e nil 'unread nil))
2840 (mapcar (lambda (e) 3058 unreads)))
2841 (list e nil 'unread nil)) 3059 (setq dlist (nconc dlist
2842 unreads))) 3060 (mapcar (lambda (e)
2843 (setq dlist (nconc dlist 3061 (list e nil 'marked nil))
2844 (mapcar (lambda (e) 3062 marked)))
2845 (list e nil 'marked nil)) 3063 (setq dlist (nconc dlist
2846 marked))) 3064 (mapcar (lambda (e)
2847 (setq dlist (nconc dlist 3065 (list e nil 'special nil))
2848 (mapcar (lambda (e) 3066 specials)))
2849 (list e nil 'special nil)) 3067
2850 specials))) 3068 (set-buffer overview)
2851 3069 (erase-buffer)
2852 (set-buffer overview) 3070 (buffer-disable-undo)
2853 (erase-buffer) 3071 (when (file-exists-p nov-file)
2854 (buffer-disable-undo) 3072 (gnus-message 7 "gnus-agent-expire: Loading overview...")
2855 (when (file-exists-p nov-file) 3073 (nnheader-insert-file-contents nov-file)
2856 (gnus-message 7 "gnus-agent-expire: Loading overview...") 3074 (goto-char (point-min))
2857 (nnheader-insert-file-contents nov-file) 3075
2858 (goto-char (point-min)) 3076 (let (p)
2859 3077 (while (< (setq p (point)) (point-max))
2860 (let (p) 3078 (condition-case nil
2861 (while (< (setq p (point)) (point-max)) 3079 ;; If I successfully read an integer (the plus zero
2862 (condition-case nil 3080 ;; ensures a numeric type), prepend a marker entry
2863 ;; If I successfully read an integer (the plus zero 3081 ;; to the list
2864 ;; ensures a numeric type), prepend a marker entry 3082 (push (list (+ 0 (read (current-buffer))) nil nil
2865 ;; to the list 3083 (set-marker (make-marker) p))
2866 (push (list (+ 0 (read (current-buffer))) nil nil 3084 dlist)
2867 (set-marker (make-marker) p)) 3085 (error
2868 dlist) 3086 (gnus-message 1 "gnus-agent-expire: read error \
2869 (error
2870 (gnus-message 1 "gnus-agent-expire: read error \
2871occurred when reading expression at %s in %s. Skipping to next \ 3087occurred when reading expression at %s in %s. Skipping to next \
2872line." (point) nov-file))) 3088line." (point) nov-file)))
2873 ;; Whether I succeeded, or failed, it doesn't matter. 3089 ;; Whether I succeeded, or failed, it doesn't matter.
2874 ;; Move to the next line then try again. 3090 ;; Move to the next line then try again.
2875 (forward-line 1))) 3091 (forward-line 1)))
2876 3092
2877 (gnus-message 3093 (gnus-message
2878 7 "gnus-agent-expire: Loading overview... Done")) 3094 7 "gnus-agent-expire: Loading overview... Done"))
2879 (set-buffer-modified-p nil) 3095 (set-buffer-modified-p nil)
2880 3096
2881 ;; At this point, all of the information is in dlist. The 3097 ;; At this point, all of the information is in dlist. The
2882 ;; only problem is that much of it is spread across multiple 3098 ;; only problem is that much of it is spread across multiple
2883 ;; entries. Sort then MERGE!! 3099 ;; entries. Sort then MERGE!!
2884 (gnus-message 7 "gnus-agent-expire: Sorting entries... ") 3100 (gnus-message 7 "gnus-agent-expire: Sorting entries... ")
2885 ;; If two entries have the same article-number then sort by 3101 ;; If two entries have the same article-number then sort by
2886 ;; ascending keep_flag. 3102 ;; ascending keep_flag.
2887 (let ((special 0) 3103 (let ((special 0)
2888 (marked 1) 3104 (marked 1)
2889 (unread 2)) 3105 (unread 2))
2890 (setq dlist 3106 (setq dlist
2891 (sort dlist 3107 (sort dlist
2892 (lambda (a b) 3108 (lambda (a b)
2893 (cond ((< (nth 0 a) (nth 0 b)) 3109 (cond ((< (nth 0 a) (nth 0 b))
2894 t) 3110 t)
2895 ((> (nth 0 a) (nth 0 b)) 3111 ((> (nth 0 a) (nth 0 b))
2896 nil) 3112 nil)
2897 (t 3113 (t
2898 (let ((a (or (symbol-value (nth 2 a)) 3114 (let ((a (or (symbol-value (nth 2 a))
2899 3)) 3115 3))
2900 (b (or (symbol-value (nth 2 b)) 3116 (b (or (symbol-value (nth 2 b))
2901 3))) 3117 3)))
2902 (<= a b)))))))) 3118 (<= a b))))))))
2903 (gnus-message 7 "gnus-agent-expire: Sorting entries... Done") 3119 (gnus-message 7 "gnus-agent-expire: Sorting entries... Done")
2904 (gnus-message 7 "gnus-agent-expire: Merging entries... ") 3120 (gnus-message 7 "gnus-agent-expire: Merging entries... ")
2905 (let ((dlist dlist)) 3121 (let ((dlist dlist))
2906 (while (cdr dlist) ; I'm not at the end-of-list 3122 (while (cdr dlist) ; I'm not at the end-of-list
2907 (if (eq (caar dlist) (caadr dlist)) 3123 (if (eq (caar dlist) (caadr dlist))
2908 (let ((first (cdr (car dlist))) 3124 (let ((first (cdr (car dlist)))
2909 (secnd (cdr (cadr dlist)))) 3125 (secnd (cdr (cadr dlist))))
2910 (setcar first (or (car first) 3126 (setcar first (or (car first)
2911 (car secnd))) ; fetch_date 3127 (car secnd))) ; fetch_date
2912 (setq first (cdr first) 3128 (setq first (cdr first)
2913 secnd (cdr secnd)) 3129 secnd (cdr secnd))
2914 (setcar first (or (car first) 3130 (setcar first (or (car first)
2915 (car secnd))) ; Keep_flag 3131 (car secnd))) ; Keep_flag
2916 (setq first (cdr first) 3132 (setq first (cdr first)
2917 secnd (cdr secnd)) 3133 secnd (cdr secnd))
2918 (setcar first (or (car first) 3134 (setcar first (or (car first)
2919 (car secnd))) ; NOV_entry_marker 3135 (car secnd))) ; NOV_entry_marker
2920 3136
2921 (setcdr dlist (cddr dlist))) 3137 (setcdr dlist (cddr dlist)))
2922 (setq dlist (cdr dlist))))) 3138 (setq dlist (cdr dlist)))))
2923 (gnus-message 7 "gnus-agent-expire: Merging entries... Done") 3139 (gnus-message 7 "gnus-agent-expire: Merging entries... Done")
2924 3140
2925 (let* ((len (float (length dlist))) 3141 (let* ((len (float (length dlist)))
2926 (alist (list nil)) 3142 (alist (list nil))
2927 (tail-alist alist)) 3143 (tail-alist alist))
2928 (while dlist 3144 (while dlist
2929 (let ((new-completed (truncate (* 100.0 3145 (let ((new-completed (truncate (* 100.0
2930 (/ (setq cnt (1+ cnt)) 3146 (/ (setq cnt (1+ cnt))
2931 len)))) 3147 len))))
2932 message-log-max) 3148 message-log-max)
2933 (when (> new-completed completed) 3149 (when (> new-completed completed)
2934 (setq completed new-completed) 3150 (setq completed new-completed)
2935 (gnus-message 7 "%3d%% completed..." completed))) 3151 (gnus-message 7 "%3d%% completed..." completed)))
2936 (let* ((entry (car dlist)) 3152 (let* ((entry (car dlist))
2937 (article-number (nth 0 entry)) 3153 (article-number (nth 0 entry))
2938 (fetch-date (nth 1 entry)) 3154 (fetch-date (nth 1 entry))
2939 (keep (nth 2 entry)) 3155 (keep (nth 2 entry))
2940 (marker (nth 3 entry))) 3156 (marker (nth 3 entry)))
2941 3157
2942 (cond 3158 (cond
2943 ;; Kept articles are unread, marked, or special. 3159 ;; Kept articles are unread, marked, or special.
2944 (keep 3160 (keep
2945 (gnus-agent-message 10 3161 (gnus-agent-message 10
2946 "gnus-agent-expire: %s:%d: Kept %s article%s." 3162 "gnus-agent-expire: %s:%d: Kept %s article%s."
2947 group article-number keep (if fetch-date " and file" "")) 3163 group article-number keep (if fetch-date " and file" ""))
2948 (when fetch-date 3164 (when fetch-date
2949 (unless (file-exists-p 3165 (unless (file-exists-p
2950 (concat dir (number-to-string 3166 (concat dir (number-to-string
2951 article-number))) 3167 article-number)))
2952 (setf (nth 1 entry) nil) 3168 (setf (nth 1 entry) nil)
2953 (gnus-agent-message 3 "gnus-agent-expire cleared \ 3169 (gnus-agent-message 3 "gnus-agent-expire cleared \
2954download flag on %s:%d as the cached article file is missing." 3170download flag on %s:%d as the cached article file is missing."
2955 group (caar dlist))) 3171 group (caar dlist)))
2956 (unless marker 3172 (unless marker
2957 (gnus-message 1 "gnus-agent-expire detected a \ 3173 (gnus-message 1 "gnus-agent-expire detected a \
2958missing NOV entry. Run gnus-agent-regenerate-group to restore it."))) 3174missing NOV entry. Run gnus-agent-regenerate-group to restore it.")))
2959 (gnus-agent-append-to-list 3175 (gnus-agent-append-to-list
2960 tail-alist 3176 tail-alist
2961 (cons article-number fetch-date))) 3177 (cons article-number fetch-date)))
2962 3178
2963 ;; The following articles are READ, UNMARKED, and 3179 ;; The following articles are READ, UNMARKED, and
2964 ;; ORDINARY. See if they can be EXPIRED!!! 3180 ;; ORDINARY. See if they can be EXPIRED!!!
2965 ((setq type 3181 ((setq type
2966 (cond 3182 (cond
2967 ((not (integerp fetch-date)) 3183 ((not (integerp fetch-date))
2968 'read) ;; never fetched article (may expire 3184 'read) ;; never fetched article (may expire
2969 ;; right now) 3185 ;; right now)
2970 ((not (file-exists-p 3186 ((not (file-exists-p
2971 (concat dir (number-to-string 3187 (concat dir (number-to-string
2972 article-number)))) 3188 article-number))))
2973 (setf (nth 1 entry) nil) 3189 (setf (nth 1 entry) nil)
2974 'externally-expired) ;; Can't find the cached 3190 'externally-expired) ;; Can't find the cached
2975 ;; article. Handle case 3191 ;; article. Handle case
2976 ;; as though this article 3192 ;; as though this article
2977 ;; was never fetched. 3193 ;; was never fetched.
2978 3194
2979 ;; We now have the arrival day, so we see 3195 ;; We now have the arrival day, so we see
2980 ;; whether it's old enough to be expired. 3196 ;; whether it's old enough to be expired.
2981 ((< fetch-date day) 3197 ((< fetch-date day)
2982 'expired) 3198 'expired)
2983 (force 3199 (force
2984 'forced))) 3200 'forced)))
2985 3201
2986 ;; I found some reason to expire this entry. 3202 ;; I found some reason to expire this entry.
2987 3203
2988 (let ((actions nil)) 3204 (let ((actions nil))
2989 (when (memq type '(forced expired)) 3205 (when (memq type '(forced expired))
2990 (ignore-errors ; Just being paranoid. 3206 (ignore-errors ; Just being paranoid.
2991 (let ((file-name (concat dir (number-to-string 3207 (let* ((file-name (nnheader-concat dir (number-to-string
2992 article-number)))) 3208 article-number)))
2993 (incf (nth 2 stats) (nth 7 (file-attributes file-name))) 3209 (size (float (nth 7 (file-attributes file-name)))))
2994 (incf (nth 1 stats)) 3210 (incf bytes-freed size)
2995 (delete-file file-name)) 3211 (incf files-deleted)
2996 (push "expired cached article" actions)) 3212 (delete-file file-name))
2997 (setf (nth 1 entry) nil) 3213 (push "expired cached article" actions))
2998 ) 3214 (setf (nth 1 entry) nil)
2999 3215 )
3000 (when marker 3216
3001 (push "NOV entry removed" actions) 3217 (when marker
3002 (goto-char marker) 3218 (push "NOV entry removed" actions)
3003 3219 (goto-char marker)
3004 (incf (nth 0 stats)) 3220
3005 3221 (incf nov-entries-deleted)
3006 (let ((from (gnus-point-at-bol)) 3222
3007 (to (progn (forward-line 1) (point)))) 3223 (let ((from (gnus-point-at-bol))
3008 (incf (nth 2 stats) (- to from)) 3224 (to (progn (forward-line 1) (point))))
3009 (delete-region from to))) 3225 (incf bytes-freed (- to from))
3010 3226 (delete-region from to)))
3011 ;; If considering all articles is set, I can only 3227
3012 ;; expire article IDs that are no longer in the 3228 ;; If considering all articles is set, I can only
3013 ;; active range (That is, articles that preceed the 3229 ;; expire article IDs that are no longer in the
3014 ;; first article in the new alist). 3230 ;; active range (That is, articles that preceed the
3015 (if (and gnus-agent-consider-all-articles 3231 ;; first article in the new alist).
3016 (>= article-number (car active))) 3232 (if (and gnus-agent-consider-all-articles
3017 ;; I have to keep this ID in the alist 3233 (>= article-number (car active)))
3018 (gnus-agent-append-to-list 3234 ;; I have to keep this ID in the alist
3019 tail-alist (cons article-number fetch-date)) 3235 (gnus-agent-append-to-list
3020 (push (format "Removed %s article number from \ 3236 tail-alist (cons article-number fetch-date))
3237 (push (format "Removed %s article number from \
3021article alist" type) actions)) 3238article alist" type) actions))
3022 3239
3023 (when actions 3240 (when actions
3024 (gnus-agent-message 8 "gnus-agent-expire: %s:%d: %s" 3241 (gnus-agent-message 8 "gnus-agent-expire: %s:%d: %s"
3025 group article-number 3242 group article-number
3026 (mapconcat 'identity actions ", "))))) 3243 (mapconcat 'identity actions ", ")))))
3027 (t 3244 (t
3028 (gnus-agent-message 3245 (gnus-agent-message
3029 10 "gnus-agent-expire: %s:%d: Article kept as \ 3246 10 "gnus-agent-expire: %s:%d: Article kept as \
3030expiration tests failed." group article-number) 3247expiration tests failed." group article-number)
3031 (gnus-agent-append-to-list 3248 (gnus-agent-append-to-list
3032 tail-alist (cons article-number fetch-date))) 3249 tail-alist (cons article-number fetch-date)))
3033 ) 3250 )
3034 3251
3035 ;; Clean up markers as I want to recycle this buffer 3252 ;; Clean up markers as I want to recycle this buffer
3036 ;; over several groups. 3253 ;; over several groups.
3037 (when marker 3254 (when marker
3038 (set-marker marker nil)) 3255 (set-marker marker nil))
3039 3256
3040 (setq dlist (cdr dlist)))) 3257 (setq dlist (cdr dlist))))
3041 3258
3042 (setq alist (cdr alist)) 3259 (setq alist (cdr alist))
3043 3260
3044 (let ((inhibit-quit t)) 3261 (let ((inhibit-quit t))
3045 (unless (equal alist gnus-agent-article-alist) 3262 (unless (equal alist gnus-agent-article-alist)
3046 (setq gnus-agent-article-alist alist) 3263 (setq gnus-agent-article-alist alist)
3047 (gnus-agent-save-alist group)) 3264 (gnus-agent-save-alist group))
3048 3265
3049 (when (buffer-modified-p) 3266 (when (buffer-modified-p)
3050 (let ((coding-system-for-write 3267 (let ((coding-system-for-write
3051 gnus-agent-file-coding-system)) 3268 gnus-agent-file-coding-system))
3052 (gnus-make-directory dir) 3269 (gnus-make-directory dir)
3053 (write-region (point-min) (point-max) nov-file nil 3270 (write-region (point-min) (point-max) nov-file nil
3054 'silent) 3271 'silent)
3055 ;; clear the modified flag as that I'm not confused by 3272 ;; clear the modified flag as that I'm not confused by
3056 ;; its status on the next pass through this routine. 3273 ;; its status on the next pass through this routine.
3057 (set-buffer-modified-p nil))) 3274 (set-buffer-modified-p nil)))
3058 3275
3059 (when (eq articles t) 3276 (when (eq articles t)
3060 (gnus-summary-update-info)))))))) 3277 (gnus-summary-update-info))))
3278
3279 (when (boundp 'gnus-agent-expire-stats)
3280 (let ((stats (symbol-value 'gnus-agent-expire-stats)))
3281 (incf (nth 2 stats) bytes-freed)
3282 (incf (nth 1 stats) files-deleted)
3283 (incf (nth 0 stats) nov-entries-deleted)))
3284 ))))
3061 3285
3062(defun gnus-agent-expire (&optional articles group force) 3286(defun gnus-agent-expire (&optional articles group force)
3063 "Expire all old articles. 3287 "Expire all old articles.
@@ -3248,7 +3472,7 @@ articles in every agentized group."))
3248 3472
3249(defun gnus-agent-uncached-articles (articles group &optional cached-header) 3473(defun gnus-agent-uncached-articles (articles group &optional cached-header)
3250 "Restrict ARTICLES to numbers already fetched. 3474 "Restrict ARTICLES to numbers already fetched.
3251Returns a sublist of ARTICLES that excludes thos article ids in GROUP 3475Returns a sublist of ARTICLES that excludes those article ids in GROUP
3252that have already been fetched. 3476that have already been fetched.
3253If CACHED-HEADER is nil, articles are only excluded if the article itself 3477If CACHED-HEADER is nil, articles are only excluded if the article itself
3254has been fetched." 3478has been fetched."
@@ -3338,12 +3562,11 @@ has been fetched."
3338 3562
3339 ;; Get the list of articles that were fetched 3563 ;; Get the list of articles that were fetched
3340 (goto-char (point-min)) 3564 (goto-char (point-min))
3341 (let ((pm (point-max))) 3565 (let ((pm (point-max))
3566 art)
3342 (while (< (point) pm) 3567 (while (< (point) pm)
3343 (when (looking-at "[0-9]+\t") 3568 (when (setq art (gnus-agent-read-article-number))
3344 (gnus-agent-append-to-list 3569 (gnus-agent-append-to-list tail-fetched-articles art))
3345 tail-fetched-articles
3346 (read (current-buffer))))
3347 (forward-line 1))) 3570 (forward-line 1)))
3348 3571
3349 ;; Clip this list to the headers that will 3572 ;; Clip this list to the headers that will
@@ -3380,12 +3603,12 @@ has been fetched."
3380 (set-buffer nntp-server-buffer) 3603 (set-buffer nntp-server-buffer)
3381 (copy-to-buffer gnus-agent-overview-buffer (point-min) (point-max)) 3604 (copy-to-buffer gnus-agent-overview-buffer (point-min) (point-max))
3382 3605
3383 ;; Merge the temp buffer with the known headers (found on 3606 ;; Merge the temp buffer with the known headers (found on
3384 ;; disk in FILE) into the nntp-server-buffer 3607 ;; disk in FILE) into the nntp-server-buffer
3385 (when (and uncached-articles (file-exists-p file)) 3608 (when uncached-articles
3386 (gnus-agent-braid-nov group uncached-articles file)) 3609 (gnus-agent-braid-nov group uncached-articles file))
3387 3610
3388 ;; Save the new set of known headers to FILE 3611 ;; Save the new set of known headers to FILE
3389 (set-buffer nntp-server-buffer) 3612 (set-buffer nntp-server-buffer)
3390 (let ((coding-system-for-write 3613 (let ((coding-system-for-write
3391 gnus-agent-file-coding-system)) 3614 gnus-agent-file-coding-system))
@@ -3465,7 +3688,6 @@ If REREAD is not nil, downloaded articles are marked as unread."
3465 (gnus-message 3 "Ignoring unexpected input") 3688 (gnus-message 3 "Ignoring unexpected input")
3466 (sit-for 1) 3689 (sit-for 1)
3467 t))))) 3690 t)))))
3468
3469 (when group 3691 (when group
3470 (gnus-message 5 "Regenerating in %s" group) 3692 (gnus-message 5 "Regenerating in %s" group)
3471 (let* ((gnus-command-method (or gnus-command-method 3693 (let* ((gnus-command-method (or gnus-command-method
@@ -3506,7 +3728,7 @@ If REREAD is not nil, downloaded articles are marked as unread."
3506 (gnus-delete-line) 3728 (gnus-delete-line)
3507 (setq nov-arts (cdr nov-arts)) 3729 (setq nov-arts (cdr nov-arts))
3508 (gnus-message 4 "gnus-agent-regenerate-group: NOV\ 3730 (gnus-message 4 "gnus-agent-regenerate-group: NOV\
3509entry of article %s deleted." l1)) 3731 entry of article %s deleted." l1))
3510 ((not l2) 3732 ((not l2)
3511 nil) 3733 nil)
3512 ((< l1 l2) 3734 ((< l1 l2)
@@ -3651,10 +3873,9 @@ entry of article %s deleted." l1))
3651 gnus-agent-article-alist)))) 3873 gnus-agent-article-alist))))
3652 3874
3653 (when (gnus-buffer-live-p gnus-group-buffer) 3875 (when (gnus-buffer-live-p gnus-group-buffer)
3654 (gnus-group-update-group group t) 3876 (gnus-group-update-group group t)))
3655 (sit-for 0)))
3656 3877
3657 (gnus-message 5 nil) 3878 (gnus-message 5 "")
3658 regenerated))) 3879 regenerated)))
3659 3880
3660;;;###autoload 3881;;;###autoload
@@ -3700,49 +3921,6 @@ If CLEAN, obsolete (ignore)."
3700(defun gnus-agent-group-covered-p (group) 3921(defun gnus-agent-group-covered-p (group)
3701 (gnus-agent-method-p (gnus-group-method group))) 3922 (gnus-agent-method-p (gnus-group-method group)))
3702 3923
3703(add-hook 'gnus-group-prepare-hook
3704 (lambda ()
3705 'gnus-agent-do-once
3706
3707 (when (listp gnus-agent-expire-days)
3708 (beep)
3709 (beep)
3710 (gnus-message 1 "WARNING: gnus-agent-expire-days no longer\
3711 supports being set to a list.")(sleep-for 3)
3712 (gnus-message 1 "Change your configuration to set it to an\
3713 integer.")(sleep-for 3)
3714 (gnus-message 1 "I am now setting group parameters on each\
3715 group to match the configuration that the list offered.")
3716
3717 (save-excursion
3718 (let ((groups (gnus-group-listed-groups)))
3719 (while groups
3720 (let* ((group (pop groups))
3721 (days gnus-agent-expire-days)
3722 (day (catch 'found
3723 (while days
3724 (when (eq 0 (string-match
3725 (caar days)
3726 group))
3727 (throw 'found (cadar days)))
3728 (setq days (cdr days)))
3729 nil)))
3730 (when day
3731 (gnus-group-set-parameter group 'agent-days-until-old
3732 day))))))
3733
3734 (let ((h gnus-group-prepare-hook))
3735 (while h
3736 (let ((func (pop h)))
3737 (when (and (listp func)
3738 (eq (cadr (caddr func)) 'gnus-agent-do-once))
3739 (remove-hook 'gnus-group-prepare-hook func)
3740 (setq h nil)))))
3741
3742 (gnus-message 1 "I have finished setting group parameters on\
3743 each group. You may now customize your groups and/or topics to control the\
3744 agent."))))
3745
3746(provide 'gnus-agent) 3924(provide 'gnus-agent)
3747 3925
3748;;; arch-tag: b0ba4afc-5229-4cee-ad25-9956daa4e91e 3926;;; arch-tag: b0ba4afc-5229-4cee-ad25-9956daa4e91e
diff --git a/lisp/gnus/gnus-art.el b/lisp/gnus/gnus-art.el
index d4dbe1319e0..7a365d81a2c 100644
--- a/lisp/gnus/gnus-art.el
+++ b/lisp/gnus/gnus-art.el
@@ -6122,7 +6122,7 @@ positives are possible."
6122 ("\\(<URL: *\\)mailto: *\\([^> \n\t]+\\)>" 6122 ("\\(<URL: *\\)mailto: *\\([^> \n\t]+\\)>"
6123 0 (>= gnus-button-message-level 0) gnus-url-mailto 2) 6123 0 (>= gnus-button-message-level 0) gnus-url-mailto 2)
6124 ;; RFC 2368 (The mailto URL scheme) 6124 ;; RFC 2368 (The mailto URL scheme)
6125 ("mailto:\\([-a-z.@_+0-9%=?&]+\\)" 6125 ("\\bmailto:\\([-a-z.@_+0-9%=?&/]+\\)"
6126 0 (>= gnus-button-message-level 0) gnus-url-mailto 1) 6126 0 (>= gnus-button-message-level 0) gnus-url-mailto 1)
6127 ("\\bmailto:\\([^ \n\t]+\\)" 6127 ("\\bmailto:\\([^ \n\t]+\\)"
6128 0 (>= gnus-button-message-level 0) gnus-url-mailto 1) 6128 0 (>= gnus-button-message-level 0) gnus-url-mailto 1)
@@ -6170,8 +6170,9 @@ positives are possible."
6170 ("M-x[ \t\n]+apropos-documentation[ \t\n]+RET[ \t\n]+\\([^ \t\n]+\\)[ \t\n]+RET" 6170 ("M-x[ \t\n]+apropos-documentation[ \t\n]+RET[ \t\n]+\\([^ \t\n]+\\)[ \t\n]+RET"
6171 0 (>= gnus-button-emacs-level 1) gnus-button-handle-apropos-documentation 1) 6171 0 (>= gnus-button-emacs-level 1) gnus-button-handle-apropos-documentation 1)
6172 ;; The following entries may lead to many false positives so don't enable 6172 ;; The following entries may lead to many false positives so don't enable
6173 ;; them by default (use a high button level): 6173 ;; them by default (use a high button level).
6174 ("/\\([a-z][-a-z0-9]+\\.el\\)\\>" 6174 ("/\\([a-z][-a-z0-9]+\\.el\\)\\>[^.?]"
6175 ;; Exclude [.?] for URLs in gmane.emacs.cvs
6175 1 (>= gnus-button-emacs-level 8) gnus-button-handle-library 1) 6176 1 (>= gnus-button-emacs-level 8) gnus-button-handle-library 1)
6176 ("`\\([a-z][-a-z0-9]+\\.el\\)'" 6177 ("`\\([a-z][-a-z0-9]+\\.el\\)'"
6177 1 (>= gnus-button-emacs-level 8) gnus-button-handle-library 1) 6178 1 (>= gnus-button-emacs-level 8) gnus-button-handle-library 1)
@@ -6204,16 +6205,16 @@ positives are possible."
6204 (gnus-button-url-regexp 6205 (gnus-button-url-regexp
6205 0 (>= gnus-button-browse-level 0) browse-url 0) 6206 0 (>= gnus-button-browse-level 0) browse-url 0)
6206 ;; man pages 6207 ;; man pages
6207 ("\\b\\([a-z][a-z]+\\)([1-9])\\W" 6208 ("\\b\\([a-z][a-z]+([1-9])\\)\\W"
6208 0 (and (>= gnus-button-man-level 1) (< gnus-button-man-level 3)) 6209 0 (and (>= gnus-button-man-level 1) (< gnus-button-man-level 3))
6209 gnus-button-handle-man 1) 6210 gnus-button-handle-man 1)
6210 ;; more man pages: resolv.conf(5), iso_8859-1(7), xterm(1x) 6211 ;; more man pages: resolv.conf(5), iso_8859-1(7), xterm(1x)
6211 ("\\b\\([a-z][-_.a-z0-9]+\\)([1-9])\\W" 6212 ("\\b\\([a-z][-_.a-z0-9]+([1-9])\\)\\W"
6212 0 (and (>= gnus-button-man-level 3) (< gnus-button-man-level 5)) 6213 0 (and (>= gnus-button-man-level 3) (< gnus-button-man-level 5))
6213 gnus-button-handle-man 1) 6214 gnus-button-handle-man 1)
6214 ;; even more: Apache::PerlRun(3pm), PDL::IO::FastRaw(3pm), 6215 ;; even more: Apache::PerlRun(3pm), PDL::IO::FastRaw(3pm),
6215 ;; SoWWWAnchor(3iv), XSelectInput(3X11), X(1), X(7) 6216 ;; SoWWWAnchor(3iv), XSelectInput(3X11), X(1), X(7)
6216 ("\\b\\([a-z][-+_.:a-z0-9]+\\)([1-9][X1a-z]*)\\W\\|\\b\\(X\\)([1-9])\\W" 6217 ("\\b\\(\\(?:[a-z][-+_.:a-z0-9]+([1-9][X1a-z]*)\\)\\|\\b\\(?:X([1-9])\\)\\)\\W"
6217 0 (>= gnus-button-man-level 5) gnus-button-handle-man 1) 6218 0 (>= gnus-button-man-level 5) gnus-button-handle-man 1)
6218 ;; MID or mail: To avoid too many false positives we don't try to catch 6219 ;; MID or mail: To avoid too many false positives we don't try to catch
6219 ;; all kind of allowed MIDs or mail addresses. Domain part must contain 6220 ;; all kind of allowed MIDs or mail addresses. Domain part must contain
@@ -6257,7 +6258,7 @@ variable it the real callback function."
6257 0 (>= gnus-button-browse-level 0) browse-url 0) 6258 0 (>= gnus-button-browse-level 0) browse-url 0)
6258 ("^[^:]+:" gnus-button-url-regexp 6259 ("^[^:]+:" gnus-button-url-regexp
6259 0 (>= gnus-button-browse-level 0) browse-url 0) 6260 0 (>= gnus-button-browse-level 0) browse-url 0)
6260 ("^[^:]+:" "\\bmailto:\\([-a-z.@_+0-9%=?&]+\\)" 6261 ("^[^:]+:" "\\bmailto:\\([-a-z.@_+0-9%=?&/]+\\)"
6261 0 (>= gnus-button-message-level 0) gnus-url-mailto 1) 6262 0 (>= gnus-button-message-level 0) gnus-url-mailto 1)
6262 ("^[^:]+:" "\\(<\\(url: \\)?\\(nntp\\|news\\):\\([^>\n ]*\\)>\\)" 6263 ("^[^:]+:" "\\(<\\(url: \\)?\\(nntp\\|news\\):\\([^>\n ]*\\)>\\)"
6263 1 (>= gnus-button-message-level 0) gnus-button-message-id 4)) 6264 1 (>= gnus-button-message-level 0) gnus-button-message-id 4))
@@ -6602,6 +6603,10 @@ specified by `gnus-button-alist'."
6602 6603
6603(defun gnus-button-handle-man (url) 6604(defun gnus-button-handle-man (url)
6604 "Fetch a man page." 6605 "Fetch a man page."
6606 (gnus-message 9 "`%s' `%s'" gnus-button-man-handler url)
6607 (when (eq gnus-button-man-handler 'woman)
6608 (setq url (gnus-replace-in-string url "([1-9][X1a-z]*).*\\'" "")))
6609 (gnus-message 9 "`%s' `%s'" gnus-button-man-handler url)
6605 (funcall gnus-button-man-handler url)) 6610 (funcall gnus-button-man-handler url))
6606 6611
6607(defun gnus-button-handle-info-url (url) 6612(defun gnus-button-handle-info-url (url)
diff --git a/lisp/gnus/gnus-cache.el b/lisp/gnus/gnus-cache.el
index 99e77b18f68..f0a5aa318fd 100644
--- a/lisp/gnus/gnus-cache.el
+++ b/lisp/gnus/gnus-cache.el
@@ -726,6 +726,46 @@ If GROUP is non-nil, also cater to `gnus-cacheable-groups' and
726 (or (not gnus-uncacheable-groups) 726 (or (not gnus-uncacheable-groups)
727 (not (string-match gnus-uncacheable-groups group))))))) 727 (not (string-match gnus-uncacheable-groups group)))))))
728 728
729;;;###autoload
730(defun gnus-cache-rename-group (old-group new-group)
731 "Rename OLD-GROUP as NEW-GROUP. Always updates the cache, even when
732disabled, as the old cache files would corrupt gnus when the cache was
733next enabled. Depends upon the caller to determine whether group renaming is supported."
734 (let ((old-dir (gnus-cache-file-name old-group ""))
735 (new-dir (gnus-cache-file-name new-group "")))
736 (gnus-rename-file old-dir new-dir t))
737
738 (let ((no-save gnus-cache-active-hashtb))
739 (unless gnus-cache-active-hashtb
740 (gnus-cache-read-active))
741 (let* ((old-group-hash-value (gnus-gethash old-group gnus-cache-active-hashtb))
742 (new-group-hash-value (gnus-gethash new-group gnus-cache-active-hashtb))
743 (delta (or old-group-hash-value new-group-hash-value)))
744 (gnus-sethash new-group old-group-hash-value gnus-cache-active-hashtb)
745 (gnus-sethash old-group nil gnus-cache-active-hashtb)
746
747 (if no-save
748 (setq gnus-cache-active-altered delta)
749 (gnus-cache-write-active delta)))))
750
751;;;###autoload
752(defun gnus-cache-delete-group (group)
753 "Delete GROUP. Always updates the cache, even when
754disabled, as the old cache files would corrupt gnus when the cache was
755next enabled. Depends upon the caller to determine whether group deletion is supported."
756 (let ((dir (gnus-cache-file-name group "")))
757 (gnus-delete-file dir))
758
759 (let ((no-save gnus-cache-active-hashtb))
760 (unless gnus-cache-active-hashtb
761 (gnus-cache-read-active))
762 (let* ((group-hash-value (gnus-gethash group gnus-cache-active-hashtb)))
763 (gnus-sethash group nil gnus-cache-active-hashtb)
764
765 (if no-save
766 (setq gnus-cache-active-altered group-hash-value)
767 (gnus-cache-write-active group-hash-value)))))
768
729(provide 'gnus-cache) 769(provide 'gnus-cache)
730 770
731;;; arch-tag: 05a79442-8c58-4e65-bd0a-3cbb1b89a33a 771;;; arch-tag: 05a79442-8c58-4e65-bd0a-3cbb1b89a33a
diff --git a/lisp/gnus/gnus-draft.el b/lisp/gnus/gnus-draft.el
index 62deeb4b894..15bb3bc3544 100644
--- a/lisp/gnus/gnus-draft.el
+++ b/lisp/gnus/gnus-draft.el
@@ -132,17 +132,21 @@
132 132
133(defun gnus-draft-send (article &optional group interactive) 133(defun gnus-draft-send (article &optional group interactive)
134 "Send message ARTICLE." 134 "Send message ARTICLE."
135 (let ((message-syntax-checks (if interactive message-syntax-checks 135 (let* ((is-queue (or (not group)
136 'dont-check-for-anything-just-trust-me)) 136 (equal group "nndraft:queue")))
137 (message-hidden-headers nil) 137 (message-syntax-checks (if interactive message-syntax-checks
138 (message-inhibit-body-encoding (or (not group) 138 'dont-check-for-anything-just-trust-me))
139 (equal group "nndraft:queue") 139 (message-hidden-headers nil)
140 message-inhibit-body-encoding)) 140 (message-inhibit-body-encoding (or is-queue
141 (message-send-hook (and group (not (equal group "nndraft:queue")) 141 message-inhibit-body-encoding))
142 message-send-hook)) 142 (message-send-hook (and (not is-queue)
143 (message-setup-hook (and group (not (equal group "nndraft:queue")) 143 message-send-hook))
144 message-setup-hook)) 144 (message-setup-hook (and (not is-queue)
145 type method move-to) 145 message-setup-hook))
146 (gnus-agent-queue-mail (and (not is-queue)
147 gnus-agent-queue-mail))
148 (rfc2047-encode-encoded-words nil)
149 type method move-to)
146 (gnus-draft-setup article (or group "nndraft:queue")) 150 (gnus-draft-setup article (or group "nndraft:queue"))
147 ;; We read the meta-information that says how and where 151 ;; We read the meta-information that says how and where
148 ;; this message is to be sent. 152 ;; this message is to be sent.
@@ -196,22 +200,25 @@
196(defun gnus-group-send-queue () 200(defun gnus-group-send-queue ()
197 "Send all sendable articles from the queue group." 201 "Send all sendable articles from the queue group."
198 (interactive) 202 (interactive)
199 (gnus-activate-group "nndraft:queue") 203 (when (or gnus-plugged
200 (save-excursion 204 (not gnus-agent-prompt-send-queue)
201 (let* ((articles (nndraft-articles)) 205 (gnus-y-or-n-p "Gnus is unplugged; really send queue? "))
202 (unsendable (gnus-uncompress-range 206 (gnus-activate-group "nndraft:queue")
203 (cdr (assq 'unsend 207 (save-excursion
204 (gnus-info-marks 208 (let* ((articles (nndraft-articles))
205 (gnus-get-info "nndraft:queue")))))) 209 (unsendable (gnus-uncompress-range
206 (gnus-posting-styles nil) 210 (cdr (assq 'unsend
207 (total (length articles)) 211 (gnus-info-marks
208 article) 212 (gnus-get-info "nndraft:queue"))))))
209 (while (setq article (pop articles)) 213 (gnus-posting-styles nil)
210 (unless (memq article unsendable) 214 (total (length articles))
211 (let ((message-sending-message 215 article)
212 (format "Sending message %d of %d..." 216 (while (setq article (pop articles))
213 (- total (length articles)) total))) 217 (unless (memq article unsendable)
214 (gnus-draft-send article))))))) 218 (let ((message-sending-message
219 (format "Sending message %d of %d..."
220 (- total (length articles)) total)))
221 (gnus-draft-send article))))))))
215 222
216;;;###autoload 223;;;###autoload
217(defun gnus-draft-reminder () 224(defun gnus-draft-reminder ()
@@ -265,12 +272,13 @@
265 `(lambda (arg) 272 `(lambda (arg)
266 (gnus-post-method arg ,(car ga)))) 273 (gnus-post-method arg ,(car ga))))
267 (unless (equal (cadr ga) "") 274 (unless (equal (cadr ga) "")
268 (message-add-action 275 (dolist (article (cdr ga))
269 `(progn 276 (message-add-action
270 (gnus-add-mark ,(car ga) 'replied ,(cadr ga)) 277 `(progn
271 (gnus-request-set-mark ,(car ga) (list (list (list ,(cadr ga)) 278 (gnus-add-mark ,(car ga) 'replied ,article)
272 'add '(reply))))) 279 (gnus-request-set-mark ,(car ga) (list (list (list ,article)
273 'send)))))) 280 'add '(reply)))))
281 'send)))))))
274 282
275(defun gnus-draft-article-sendable-p (article) 283(defun gnus-draft-article-sendable-p (article)
276 "Say whether ARTICLE is sendable." 284 "Say whether ARTICLE is sendable."
diff --git a/lisp/gnus/gnus-group.el b/lisp/gnus/gnus-group.el
index 435acb1d6c2..f3b2f91cd5e 100644
--- a/lisp/gnus/gnus-group.el
+++ b/lisp/gnus/gnus-group.el
@@ -44,13 +44,13 @@
44(eval-when-compile (require 'mm-url)) 44(eval-when-compile (require 'mm-url))
45 45
46(defcustom gnus-group-archive-directory 46(defcustom gnus-group-archive-directory
47 "*ftp@ftp.hpc.uh.edu:/pub/emacs/ding-list/" 47 "/ftp@ftp.hpc.uh.edu:/pub/emacs/ding-list/"
48 "*The address of the (ding) archives." 48 "*The address of the (ding) archives."
49 :group 'gnus-group-foreign 49 :group 'gnus-group-foreign
50 :type 'directory) 50 :type 'directory)
51 51
52(defcustom gnus-group-recent-archive-directory 52(defcustom gnus-group-recent-archive-directory
53 "*ftp@ftp.hpc.uh.edu:/pub/emacs/ding-list-recent/" 53 "/ftp@ftp.hpc.uh.edu:/pub/emacs/ding-list-recent/"
54 "*The address of the most recent (ding) articles." 54 "*The address of the most recent (ding) articles."
55 :group 'gnus-group-foreign 55 :group 'gnus-group-foreign
56 :type 'directory) 56 :type 'directory)
@@ -2283,8 +2283,6 @@ ADDRESS."
2283 (lambda (group) 2283 (lambda (group)
2284 (gnus-group-delete-group group nil t)))))) 2284 (gnus-group-delete-group group nil t))))))
2285 2285
2286(defvar gnus-cache-active-altered)
2287
2288(defun gnus-group-delete-group (group &optional force no-prompt) 2286(defun gnus-group-delete-group (group &optional force no-prompt)
2289 "Delete the current group. Only meaningful with editable groups. 2287 "Delete the current group. Only meaningful with editable groups.
2290If FORCE (the prefix) is non-nil, all the articles in the group will 2288If FORCE (the prefix) is non-nil, all the articles in the group will
@@ -2314,10 +2312,6 @@ be removed from the server, even when it's empty."
2314 (gnus-group-goto-group group) 2312 (gnus-group-goto-group group)
2315 (gnus-group-kill-group 1 t) 2313 (gnus-group-kill-group 1 t)
2316 (gnus-sethash group nil gnus-active-hashtb) 2314 (gnus-sethash group nil gnus-active-hashtb)
2317 (if (boundp 'gnus-cache-active-hashtb)
2318 (when gnus-cache-active-hashtb
2319 (gnus-sethash group nil gnus-cache-active-hashtb)
2320 (setq gnus-cache-active-altered t)))
2321 t)) 2315 t))
2322 (gnus-group-position-point))) 2316 (gnus-group-position-point)))
2323 2317
@@ -3133,7 +3127,7 @@ or nil if no action could be taken."
3133 (let* ((entry (gnus-gethash group gnus-newsrc-hashtb)) 3127 (let* ((entry (gnus-gethash group gnus-newsrc-hashtb))
3134 (num (car entry)) 3128 (num (car entry))
3135 (marks (nth 3 (nth 2 entry))) 3129 (marks (nth 3 (nth 2 entry)))
3136 (unread (gnus-list-of-unread-articles group))) 3130 (unread (gnus-sequence-of-unread-articles group)))
3137 ;; Remove entries for this group. 3131 ;; Remove entries for this group.
3138 (nnmail-purge-split-history (gnus-group-real-name group)) 3132 (nnmail-purge-split-history (gnus-group-real-name group))
3139 ;; Do the updating only if the newsgroup isn't killed. 3133 ;; Do the updating only if the newsgroup isn't killed.
@@ -3146,16 +3140,17 @@ or nil if no action could be taken."
3146 'del '(tick)) 3140 'del '(tick))
3147 (list (cdr (assq 'dormant marks)) 3141 (list (cdr (assq 'dormant marks))
3148 'del '(dormant)))) 3142 'del '(dormant))))
3149 (setq unread (gnus-uncompress-range 3143 (setq unread (gnus-range-add (gnus-range-add
3150 (gnus-range-add (gnus-range-add 3144 unread (cdr (assq 'dormant marks)))
3151 unread (cdr (assq 'dormant marks))) 3145 (cdr (assq 'tick marks))))
3152 (cdr (assq 'tick marks)))))
3153 (gnus-add-marked-articles group 'tick nil nil 'force) 3146 (gnus-add-marked-articles group 'tick nil nil 'force)
3154 (gnus-add-marked-articles group 'dormant nil nil 'force)) 3147 (gnus-add-marked-articles group 'dormant nil nil 'force))
3155 ;; Do auto-expirable marks if that's required. 3148 ;; Do auto-expirable marks if that's required.
3156 (when (gnus-group-auto-expirable-p group) 3149 (when (gnus-group-auto-expirable-p group)
3157 (gnus-add-marked-articles group 'expire unread) 3150 (gnus-range-map (lambda (article)
3158 (gnus-request-set-mark group (list (list unread 'add '(expire))))) 3151 (gnus-add-marked-articles group 'expire (list article))
3152 (gnus-request-set-mark group (list (list (list article) 'add '(expire)))))
3153 unread))
3159 (let ((gnus-newsgroup-name group)) 3154 (let ((gnus-newsgroup-name group))
3160 (gnus-run-hooks 'gnus-group-catchup-group-hook)) 3155 (gnus-run-hooks 'gnus-group-catchup-group-hook))
3161 num))) 3156 num)))
@@ -3517,7 +3512,7 @@ entail asking the server for the groups."
3517 ;; First we make sure that we have really read the active file. 3512 ;; First we make sure that we have really read the active file.
3518 (unless (gnus-read-active-file-p) 3513 (unless (gnus-read-active-file-p)
3519 (let ((gnus-read-active-file t) 3514 (let ((gnus-read-active-file t)
3520 (gnus-agent nil)) ; Trick the agent into ignoring the active file. 3515 (gnus-agent gnus-plugged)); If we're actually plugged, store the active file in the agent.
3521 (gnus-read-active-file))) 3516 (gnus-read-active-file)))
3522 ;; Find all groups and sort them. 3517 ;; Find all groups and sort them.
3523 (let ((groups 3518 (let ((groups
@@ -3599,7 +3594,8 @@ re-scanning. If ARG is non-nil and not a number, this will force
3599(defun gnus-group-get-new-news-this-group (&optional n dont-scan) 3594(defun gnus-group-get-new-news-this-group (&optional n dont-scan)
3600 "Check for newly arrived news in the current group (and the N-1 next groups). 3595 "Check for newly arrived news in the current group (and the N-1 next groups).
3601The difference between N and the number of newsgroup checked is returned. 3596The difference between N and the number of newsgroup checked is returned.
3602If N is negative, this group and the N-1 previous groups will be checked." 3597If N is negative, this group and the N-1 previous groups will be checked.
3598If DONT-SCAN is non-nil, scan non-activated groups as well."
3603 (interactive "P") 3599 (interactive "P")
3604 (let* ((groups (gnus-group-process-prefix n)) 3600 (let* ((groups (gnus-group-process-prefix n))
3605 (ret (if (numberp n) (- n (length groups)) 0)) 3601 (ret (if (numberp n) (- n (length groups)) 0))
diff --git a/lisp/gnus/gnus-int.el b/lisp/gnus/gnus-int.el
index 2363c2705cb..7382fa7a090 100644
--- a/lisp/gnus/gnus-int.el
+++ b/lisp/gnus/gnus-int.el
@@ -33,6 +33,7 @@
33(require 'gnus-range) 33(require 'gnus-range)
34 34
35(autoload 'gnus-agent-expire "gnus-agent") 35(autoload 'gnus-agent-expire "gnus-agent")
36(autoload 'gnus-agent-regenerate-group "gnus-agent")
36(autoload 'gnus-agent-read-servers-validate-native "gnus-agent") 37(autoload 'gnus-agent-read-servers-validate-native "gnus-agent")
37 38
38(defcustom gnus-open-server-hook nil 39(defcustom gnus-open-server-hook nil
@@ -176,7 +177,7 @@ If it is down, start it up (again)."
176 (setq method (gnus-server-to-method method))) 177 (setq method (gnus-server-to-method method)))
177 ;; Check cache of constructed names. 178 ;; Check cache of constructed names.
178 (let* ((method-sym (if gnus-agent 179 (let* ((method-sym (if gnus-agent
179 (gnus-agent-get-function method) 180 (inline (gnus-agent-get-function method))
180 (car method))) 181 (car method)))
181 (method-fns (get method-sym 'gnus-method-functions)) 182 (method-fns (get method-sym 'gnus-method-functions))
182 (func (let ((method-fnlist-elt (assq function method-fns))) 183 (func (let ((method-fnlist-elt (assq function method-fns)))
@@ -570,7 +571,7 @@ If GROUP is nil, all groups on GNUS-COMMAND-METHOD are scanned."
570 (nth 1 gnus-command-method) accept-function last))) 571 (nth 1 gnus-command-method) accept-function last)))
571 (when (and result gnus-agent 572 (when (and result gnus-agent
572 (gnus-agent-method-p gnus-command-method)) 573 (gnus-agent-method-p gnus-command-method))
573 (gnus-agent-expire (list article) group 'force)) 574 (gnus-agent-unfetch-articles group (list article)))
574 result)) 575 result))
575 576
576(defun gnus-request-accept-article (group &optional gnus-command-method last 577(defun gnus-request-accept-article (group &optional gnus-command-method last
@@ -580,7 +581,8 @@ If GROUP is nil, all groups on GNUS-COMMAND-METHOD are scanned."
580 (setq gnus-command-method (gnus-server-to-method gnus-command-method))) 581 (setq gnus-command-method (gnus-server-to-method gnus-command-method)))
581 (when (and (not gnus-command-method) 582 (when (and (not gnus-command-method)
582 (stringp group)) 583 (stringp group))
583 (setq gnus-command-method (gnus-group-name-to-method group))) 584 (setq gnus-command-method (or (gnus-find-method-for-group group)
585 (gnus-group-name-to-method group))))
584 (goto-char (point-max)) 586 (goto-char (point-max))
585 (unless (bolp) 587 (unless (bolp)
586 (insert "\n")) 588 (insert "\n"))
@@ -592,12 +594,17 @@ If GROUP is nil, all groups on GNUS-COMMAND-METHOD are scanned."
592 (let ((mail-parse-charset message-default-charset)) 594 (let ((mail-parse-charset message-default-charset))
593 (mail-encode-encoded-word-buffer))) 595 (mail-encode-encoded-word-buffer)))
594 (message-encode-message-body))) 596 (message-encode-message-body)))
595 (let ((gnus-command-method (or gnus-command-method 597(let ((gnus-command-method (or gnus-command-method
596 (gnus-find-method-for-group group)))) 598 (gnus-find-method-for-group group)))
597 (funcall (gnus-get-function gnus-command-method 'request-accept-article) 599 (result
598 (if (stringp group) (gnus-group-real-name group) group) 600 (funcall
599 (cadr gnus-command-method) 601 (gnus-get-function gnus-command-method 'request-accept-article)
600 last))) 602 (if (stringp group) (gnus-group-real-name group) group)
603 (cadr gnus-command-method)
604 last)))
605 (when (and gnus-agent (gnus-agent-method-p gnus-command-method))
606 (gnus-agent-regenerate-group group (list (cdr result))))
607 result))
601 608
602(defun gnus-request-replace-article (article group buffer &optional no-encode) 609(defun gnus-request-replace-article (article group buffer &optional no-encode)
603 (unless no-encode 610 (unless no-encode
@@ -608,9 +615,12 @@ If GROUP is nil, all groups on GNUS-COMMAND-METHOD are scanned."
608 (let ((mail-parse-charset message-default-charset)) 615 (let ((mail-parse-charset message-default-charset))
609 (mail-encode-encoded-word-buffer))) 616 (mail-encode-encoded-word-buffer)))
610 (message-encode-message-body))) 617 (message-encode-message-body)))
611 (let ((func (car (gnus-group-name-to-method group)))) 618 (let* ((func (car (gnus-group-name-to-method group)))
612 (funcall (intern (format "%s-request-replace-article" func)) 619 (result (funcall (intern (format "%s-request-replace-article" func))
613 article (gnus-group-real-name group) buffer))) 620 article (gnus-group-real-name group) buffer)))
621 (when (and gnus-agent (gnus-agent-method-p gnus-command-method))
622 (gnus-agent-regenerate-group group (list article)))
623 result))
614 624
615(defun gnus-request-associate-buffer (group) 625(defun gnus-request-associate-buffer (group)
616 (let ((gnus-command-method (gnus-find-method-for-group group))) 626 (let ((gnus-command-method (gnus-find-method-for-group group)))
@@ -633,15 +643,25 @@ If GROUP is nil, all groups on GNUS-COMMAND-METHOD are scanned."
633 (gnus-group-real-name group) (nth 1 gnus-command-method) args))) 643 (gnus-group-real-name group) (nth 1 gnus-command-method) args)))
634 644
635(defun gnus-request-delete-group (group &optional force) 645(defun gnus-request-delete-group (group &optional force)
636 (let ((gnus-command-method (gnus-find-method-for-group group))) 646 (let* ((gnus-command-method (gnus-find-method-for-group group))
637 (funcall (gnus-get-function gnus-command-method 'request-delete-group) 647 (result
638 (gnus-group-real-name group) force (nth 1 gnus-command-method)))) 648 (funcall (gnus-get-function gnus-command-method 'request-delete-group)
649 (gnus-group-real-name group) force (nth 1 gnus-command-method))))
650 (when result
651 (gnus-cache-delete-group group)
652 (gnus-agent-delete-group group))
653 result))
639 654
640(defun gnus-request-rename-group (group new-name) 655(defun gnus-request-rename-group (group new-name)
641 (let ((gnus-command-method (gnus-find-method-for-group group))) 656 (let* ((gnus-command-method (gnus-find-method-for-group group))
642 (funcall (gnus-get-function gnus-command-method 'request-rename-group) 657 (result
643 (gnus-group-real-name group) 658 (funcall (gnus-get-function gnus-command-method 'request-rename-group)
644 (gnus-group-real-name new-name) (nth 1 gnus-command-method)))) 659 (gnus-group-real-name group)
660 (gnus-group-real-name new-name) (nth 1 gnus-command-method))))
661 (when result
662 (gnus-cache-rename-group group new-name)
663 (gnus-agent-rename-group group new-name))
664 result))
645 665
646(defun gnus-close-backends () 666(defun gnus-close-backends ()
647 ;; Send a close request to all backends that support such a request. 667 ;; Send a close request to all backends that support such a request.
diff --git a/lisp/gnus/gnus-range.el b/lisp/gnus/gnus-range.el
index 56a1b569418..d2442c63a42 100644
--- a/lisp/gnus/gnus-range.el
+++ b/lisp/gnus/gnus-range.el
@@ -1,6 +1,6 @@
1;;; gnus-range.el --- range and sequence functions for Gnus 1;;; gnus-range.el --- range and sequence functions for Gnus
2 2
3;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002 3;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2004
4;; Free Software Foundation, Inc. 4;; Free Software Foundation, Inc.
5 5
6;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org> 6;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
@@ -184,6 +184,58 @@ LIST1 and LIST2 have to be sorted over <."
184 (nreverse out))) 184 (nreverse out)))
185 185
186;;;###autoload 186;;;###autoload
187(defun gnus-sorted-range-intersection (range1 range2)
188 "Return intersection of RANGE1 and RANGE2.
189RANGE1 and RANGE2 have to be sorted over <."
190 (let* (out
191 (min1 (car range1))
192 (max1 (if (numberp min1)
193 (if (numberp (cdr range1))
194 (prog1 (cdr range1)
195 (setq range1 nil)) min1)
196 (prog1 (cdr min1)
197 (setq min1 (car min1)))))
198 (min2 (car range2))
199 (max2 (if (numberp min2)
200 (if (numberp (cdr range2))
201 (prog1 (cdr range2)
202 (setq range2 nil)) min2)
203 (prog1 (cdr min2)
204 (setq min2 (car min2))))))
205 (setq range1 (cdr range1)
206 range2 (cdr range2))
207 (while (and min1 min2)
208 (cond ((< max1 min2) ; range1 preceeds range2
209 (setq range1 (cdr range1)
210 min1 nil))
211 ((< max2 min1) ; range2 preceeds range1
212 (setq range2 (cdr range2)
213 min2 nil))
214 (t ; some sort of overlap is occurring
215 (let ((min (max min1 min2))
216 (max (min max1 max2)))
217 (setq out (if (= min max)
218 (cons min out)
219 (cons (cons min max) out))))
220 (if (< max1 max2) ; range1 ends before range2
221 (setq min1 nil) ; incr range1
222 (setq min2 nil)))) ; incr range2
223 (unless min1
224 (setq min1 (car range1)
225 max1 (if (numberp min1) min1 (prog1 (cdr min1) (setq min1 (car min1))))
226 range1 (cdr range1)))
227 (unless min2
228 (setq min2 (car range2)
229 max2 (if (numberp min2) min2 (prog1 (cdr min2) (setq min2 (car min2))))
230 range2 (cdr range2))))
231 (cond ((cdr out)
232 (nreverse out))
233 ((numberp (car out))
234 out)
235 (t
236 (car out)))))
237
238;;;###autoload
187(defalias 'gnus-set-sorted-intersection 'gnus-sorted-nintersection) 239(defalias 'gnus-set-sorted-intersection 'gnus-sorted-nintersection)
188 240
189;;;###autoload 241;;;###autoload
@@ -589,6 +641,19 @@ LIST is a sorted list."
589 (setcdr prev (cons num list))) 641 (setcdr prev (cons num list)))
590 (cdr top))) 642 (cdr top)))
591 643
644(defun gnus-range-map (func range)
645 "Apply FUNC to each value contained by RANGE."
646 (setq range (gnus-range-normalize range))
647 (while range
648 (let ((span (pop range)))
649 (if (numberp span)
650 (funcall func span)
651 (let ((first (car span))
652 (last (cdr span)))
653 (while (<= first last)
654 (funcall func first)
655 (setq first (1+ first))))))))
656
592(provide 'gnus-range) 657(provide 'gnus-range)
593 658
594;;; arch-tag: 4780bdd8-5a15-4aff-be28-18727895b6ad 659;;; arch-tag: 4780bdd8-5a15-4aff-be28-18727895b6ad
diff --git a/lisp/gnus/gnus-registry.el b/lisp/gnus/gnus-registry.el
index 33238ef4552..841f0057566 100644
--- a/lisp/gnus/gnus-registry.el
+++ b/lisp/gnus/gnus-registry.el
@@ -693,6 +693,8 @@ Returns the first place where the trail finds a group name."
693 693
694 (remove-hook 'gnus-summary-prepare-hook 'gnus-registry-register-message-ids)) 694 (remove-hook 'gnus-summary-prepare-hook 'gnus-registry-register-message-ids))
695 695
696(add-hook 'gnus-registry-unload-hook 'gnus-registry-unload-hook)
697
696(when gnus-registry-install 698(when gnus-registry-install
697 (gnus-registry-install-hooks) 699 (gnus-registry-install-hooks)
698 (gnus-registry-read)) 700 (gnus-registry-read))
diff --git a/lisp/gnus/gnus-start.el b/lisp/gnus/gnus-start.el
index 18641b3a37f..dda03b864b1 100644
--- a/lisp/gnus/gnus-start.el
+++ b/lisp/gnus/gnus-start.el
@@ -1,5 +1,5 @@
1;;; gnus-start.el --- startup functions for Gnus 1;;; gnus-start.el --- startup functions for Gnus
2;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 2;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
3;; Free Software Foundation, Inc. 3;; Free Software Foundation, Inc.
4 4
5;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org> 5;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
@@ -34,8 +34,15 @@
34(require 'gnus-util) 34(require 'gnus-util)
35(autoload 'message-make-date "message") 35(autoload 'message-make-date "message")
36(autoload 'gnus-agent-read-servers-validate "gnus-agent") 36(autoload 'gnus-agent-read-servers-validate "gnus-agent")
37(autoload 'gnus-agent-save-local "gnus-agent")
37(autoload 'gnus-agent-possibly-alter-active "gnus-agent") 38(autoload 'gnus-agent-possibly-alter-active "gnus-agent")
38(eval-when-compile (require 'cl)) 39
40(eval-when-compile
41 (require 'cl)
42
43 (defvar gnus-agent-covered-methods nil)
44 (defvar gnus-agent-file-loading-local nil)
45 (defvar gnus-agent-file-loading-cache nil))
39 46
40(defcustom gnus-startup-file (nnheader-concat gnus-home-directory ".newsrc") 47(defcustom gnus-startup-file (nnheader-concat gnus-home-directory ".newsrc")
41 "Your `.newsrc' file. 48 "Your `.newsrc' file.
@@ -665,6 +672,8 @@ the first newsgroup."
665 (setq gnus-list-of-killed-groups nil 672 (setq gnus-list-of-killed-groups nil
666 gnus-have-read-active-file nil 673 gnus-have-read-active-file nil
667 gnus-agent-covered-methods nil 674 gnus-agent-covered-methods nil
675 gnus-agent-file-loading-local nil
676 gnus-agent-file-loading-cache nil
668 gnus-server-method-cache nil 677 gnus-server-method-cache nil
669 gnus-newsrc-alist nil 678 gnus-newsrc-alist nil
670 gnus-newsrc-hashtb nil 679 gnus-newsrc-hashtb nil
@@ -1481,8 +1490,8 @@ newsgroup."
1481 (setcdr active (cdr cache-active)))))))) 1490 (setcdr active (cdr cache-active))))))))
1482 1491
1483(defun gnus-activate-group (group &optional scan dont-check method) 1492(defun gnus-activate-group (group &optional scan dont-check method)
1484 ;; Check whether a group has been activated or not. 1493 "Check whether a group has been activated or not.
1485 ;; If SCAN, request a scan of that group as well. 1494If SCAN, request a scan of that group as well."
1486 (let ((method (or method (inline (gnus-find-method-for-group group)))) 1495 (let ((method (or method (inline (gnus-find-method-for-group group))))
1487 active) 1496 active)
1488 (and (inline (gnus-check-server method)) 1497 (and (inline (gnus-check-server method))
@@ -1513,12 +1522,21 @@ newsgroup."
1513 (gnus-active group)) 1522 (gnus-active group))
1514 (gnus-active group) 1523 (gnus-active group)
1515 1524
1525 ;; If a cache is present, we may have to alter the active info.
1526 (when gnus-use-cache
1527 (inline (gnus-cache-possibly-alter-active
1528 group active)))
1529
1530 ;; If the agent is enabled, we may have to alter the active info.
1531 (when gnus-agent
1532 (gnus-agent-possibly-alter-active group active))
1533
1516 (gnus-set-active group active) 1534 (gnus-set-active group active)
1517 ;; Return the new active info. 1535 ;; Return the new active info.
1518 active))))) 1536 active)))))
1519 1537
1520(defun gnus-get-unread-articles-in-group (info active &optional update) 1538(defun gnus-get-unread-articles-in-group (info active &optional update)
1521 (when active 1539 (when (and info active)
1522 ;; Allow the backend to update the info in the group. 1540 ;; Allow the backend to update the info in the group.
1523 (when (and update 1541 (when (and update
1524 (gnus-request-update-info 1542 (gnus-request-update-info
@@ -1528,6 +1546,10 @@ newsgroup."
1528 1546
1529 (let* ((range (gnus-info-read info)) 1547 (let* ((range (gnus-info-read info))
1530 (num 0)) 1548 (num 0))
1549
1550 ;; These checks are present in gnus-activate-group but skipped
1551 ;; due to setting dont-check in the preceeding call.
1552
1531 ;; If a cache is present, we may have to alter the active info. 1553 ;; If a cache is present, we may have to alter the active info.
1532 (when (and gnus-use-cache info) 1554 (when (and gnus-use-cache info)
1533 (inline (gnus-cache-possibly-alter-active 1555 (inline (gnus-cache-possibly-alter-active
@@ -1535,8 +1557,7 @@ newsgroup."
1535 1557
1536 ;; If the agent is enabled, we may have to alter the active info. 1558 ;; If the agent is enabled, we may have to alter the active info.
1537 (when (and gnus-agent info) 1559 (when (and gnus-agent info)
1538 (gnus-agent-possibly-alter-active 1560 (gnus-agent-possibly-alter-active (gnus-info-group info) active info))
1539 (gnus-info-group info) active))
1540 1561
1541 ;; Modify the list of read articles according to what articles 1562 ;; Modify the list of read articles according to what articles
1542 ;; are available; then tally the unread articles and add the 1563 ;; are available; then tally the unread articles and add the
@@ -1632,7 +1653,7 @@ newsgroup."
1632 1653
1633 (while newsrc 1654 (while newsrc
1634 (setq active (gnus-active (setq group (gnus-info-group 1655 (setq active (gnus-active (setq group (gnus-info-group
1635 (setq info (pop newsrc)))))) 1656 (setq info (pop newsrc))))))
1636 1657
1637 ;; Check newsgroups. If the user doesn't want to check them, or 1658 ;; Check newsgroups. If the user doesn't want to check them, or
1638 ;; they can't be checked (for instance, if the news server can't 1659 ;; they can't be checked (for instance, if the news server can't
@@ -1655,61 +1676,60 @@ newsgroup."
1655 (when (and method 1676 (when (and method
1656 (not (setq method-type (cdr (assoc method type-cache))))) 1677 (not (setq method-type (cdr (assoc method type-cache)))))
1657 (setq method-type 1678 (setq method-type
1658 (cond 1679 (cond
1659 ((gnus-secondary-method-p method) 1680 ((gnus-secondary-method-p method)
1660 'secondary) 1681 'secondary)
1661 ((inline (gnus-server-equal gnus-select-method method)) 1682 ((inline (gnus-server-equal gnus-select-method method))
1662 'primary) 1683 'primary)
1663 (t 1684 (t
1664 'foreign))) 1685 'foreign)))
1665 (push (cons method method-type) type-cache)) 1686 (push (cons method method-type) type-cache))
1666 (if (and method 1687
1667 (eq method-type 'foreign)) 1688 (cond ((and method (eq method-type 'foreign))
1668 ;; These groups are foreign. Check the level. 1689 ;; These groups are foreign. Check the level.
1669 (when (and (<= (gnus-info-level info) foreign-level) 1690 (when (and (<= (gnus-info-level info) foreign-level)
1670 (setq active (gnus-activate-group group 'scan))) 1691 (setq active (gnus-activate-group group 'scan)))
1671 ;; Let the Gnus agent save the active file. 1692 ;; Let the Gnus agent save the active file.
1672 (when (and gnus-agent active (gnus-online method)) 1693 (when (and gnus-agent active (gnus-online method))
1673 (gnus-agent-save-group-info 1694 (gnus-agent-save-group-info
1674 method (gnus-group-real-name group) active)) 1695 method (gnus-group-real-name group) active))
1675 (unless (inline (gnus-virtual-group-p group)) 1696 (unless (inline (gnus-virtual-group-p group))
1676 (inline (gnus-close-group group))) 1697 (inline (gnus-close-group group)))
1677 (when (fboundp (intern (concat (symbol-name (car method)) 1698 (when (fboundp (intern (concat (symbol-name (car method))
1678 "-request-update-info"))) 1699 "-request-update-info")))
1679 (inline (gnus-request-update-info info method)))) 1700 (inline (gnus-request-update-info info method)))))
1680 ;; These groups are native or secondary. 1701 ;; These groups are native or secondary.
1681 (cond 1702 ((> (gnus-info-level info) level)
1682 ;; We don't want these groups. 1703 ;; We don't want these groups.
1683 ((> (gnus-info-level info) level) 1704 (setq active 'ignore))
1684 (setq active 'ignore)) 1705 ;; Activate groups.
1685 ;; Activate groups. 1706 ((not gnus-read-active-file)
1686 ((not gnus-read-active-file) 1707 (if (gnus-check-backend-function 'retrieve-groups group)
1687 (if (gnus-check-backend-function 'retrieve-groups group) 1708 ;; if server support gnus-retrieve-groups we push
1688 ;; if server support gnus-retrieve-groups we push 1709 ;; the group onto retrievegroups for later checking
1689 ;; the group onto retrievegroups for later checking 1710 (if (assoc method retrieve-groups)
1690 (if (assoc method retrieve-groups) 1711 (setcdr (assoc method retrieve-groups)
1691 (setcdr (assoc method retrieve-groups) 1712 (cons group (cdr (assoc method retrieve-groups))))
1692 (cons group (cdr (assoc method retrieve-groups)))) 1713 (push (list method group) retrieve-groups))
1693 (push (list method group) retrieve-groups)) 1714 ;; hack: `nnmail-get-new-mail' changes the mail-source depending
1694 ;; hack: `nnmail-get-new-mail' changes the mail-source depending 1715 ;; on the group, so we must perform a scan for every group
1695 ;; on the group, so we must perform a scan for every group 1716 ;; if the users has any directory mail sources.
1696 ;; if the users has any directory mail sources. 1717 ;; hack: if `nnmail-scan-directory-mail-source-once' is non-nil,
1697 ;; hack: if `nnmail-scan-directory-mail-source-once' is non-nil, 1718 ;; for it scan all spool files even when the groups are
1698 ;; for it scan all spool files even when the groups are 1719 ;; not required.
1699 ;; not required. 1720 (if (and
1700 (if (and 1721 (or nnmail-scan-directory-mail-source-once
1701 (or nnmail-scan-directory-mail-source-once 1722 (null (assq 'directory
1702 (null (assq 'directory 1723 (or mail-sources
1703 (or mail-sources 1724 (if (listp nnmail-spool-file)
1704 (if (listp nnmail-spool-file) 1725 nnmail-spool-file
1705 nnmail-spool-file 1726 (list nnmail-spool-file))))))
1706 (list nnmail-spool-file)))))) 1727 (member method scanned-methods))
1707 (member method scanned-methods)) 1728 (setq active (gnus-activate-group group))
1708 (setq active (gnus-activate-group group)) 1729 (setq active (gnus-activate-group group 'scan))
1709 (setq active (gnus-activate-group group 'scan)) 1730 (push method scanned-methods))
1710 (push method scanned-methods)) 1731 (when active
1711 (when active 1732 (gnus-close-group group)))))
1712 (gnus-close-group group))))))
1713 1733
1714 ;; Get the number of unread articles in the group. 1734 ;; Get the number of unread articles in the group.
1715 (cond 1735 (cond
@@ -1736,8 +1756,8 @@ newsgroup."
1736 (when (gnus-check-backend-function 'request-scan (car method)) 1756 (when (gnus-check-backend-function 'request-scan (car method))
1737 (gnus-request-scan nil method)) 1757 (gnus-request-scan nil method))
1738 (gnus-read-active-file-2 1758 (gnus-read-active-file-2
1739 (mapcar (lambda (group) (gnus-group-real-name group)) groups) 1759 (mapcar (lambda (group) (gnus-group-real-name group)) groups)
1740 method) 1760 method)
1741 (dolist (group groups) 1761 (dolist (group groups)
1742 (cond 1762 (cond
1743 ((setq active (gnus-active (gnus-info-group 1763 ((setq active (gnus-active (gnus-info-group
@@ -1982,10 +2002,10 @@ newsgroup."
1982 (while (setq info (pop newsrc)) 2002 (while (setq info (pop newsrc))
1983 (when (inline 2003 (when (inline
1984 (gnus-server-equal 2004 (gnus-server-equal
1985 (inline 2005 (inline
1986 (gnus-find-method-for-group 2006 (gnus-find-method-for-group
1987 (gnus-info-group info) info)) 2007 (gnus-info-group info) info))
1988 gmethod)) 2008 gmethod))
1989 (push (gnus-group-real-name (gnus-info-group info)) 2009 (push (gnus-group-real-name (gnus-info-group info))
1990 groups))) 2010 groups)))
1991 (gnus-read-active-file-2 groups method))) 2011 (gnus-read-active-file-2 groups method)))
@@ -2129,7 +2149,7 @@ newsgroup."
2129 (gnus-online method) 2149 (gnus-online method)
2130 (gnus-agent-method-p method)) 2150 (gnus-agent-method-p method))
2131 (progn 2151 (progn
2132 (gnus-agent-save-groups method) 2152 (gnus-agent-save-active method)
2133 (gnus-active-to-gnus-format method hashtb nil real-active)) 2153 (gnus-active-to-gnus-format method hashtb nil real-active))
2134 2154
2135 (goto-char (point-min)) 2155 (goto-char (point-min))
@@ -2205,17 +2225,94 @@ If FORCE is non-nil, the .newsrc file is read."
2205 (gnus-convert-old-newsrc)))) 2225 (gnus-convert-old-newsrc))))
2206 2226
2207(defun gnus-convert-old-newsrc () 2227(defun gnus-convert-old-newsrc ()
2208 "Convert old newsrc into the new format, if needed." 2228 "Convert old newsrc formats into the current format, if needed."
2209 (let ((fcv (and gnus-newsrc-file-version 2229 (let ((fcv (and gnus-newsrc-file-version
2210 (gnus-continuum-version gnus-newsrc-file-version)))) 2230 (gnus-continuum-version gnus-newsrc-file-version))))
2211 (cond 2231 (when fcv
2212 ;; No .newsrc.eld file was loaded. 2232 ;; A newsrc file was loaded.
2213 ((null fcv) nil) 2233 (let (prompt-displayed
2214 ;; Gnus 5 .newsrc.eld was loaded. 2234 (converters
2215 ((< fcv (gnus-continuum-version "September Gnus v0.1")) 2235 (sort
2216 (gnus-convert-old-ticks))))) 2236 (mapcar (lambda (date-func)
2217 2237 (cons (gnus-continuum-version (car date-func))
2218(defun gnus-convert-old-ticks () 2238 date-func))
2239 ;; This is a list of converters that must be run
2240 ;; to bring the newsrc file up to the current
2241 ;; version. If you create an incompatibility
2242 ;; with older versions, you should create an
2243 ;; entry here. The entry should consist of the
2244 ;; current gnus version (hardcoded so that it
2245 ;; doesn't change with each release) and the
2246 ;; function that must be applied to convert the
2247 ;; previous version into the current version.
2248 '(("September Gnus v0.1" nil
2249 gnus-convert-old-ticks)
2250 ("Oort Gnus v0.08" "legacy-gnus-agent"
2251 gnus-agent-convert-to-compressed-agentview)
2252 ("Gnus v5.11" "legacy-gnus-agent"
2253 gnus-agent-unlist-expire-days)
2254 ("Gnus v5.11" "legacy-gnus-agent"
2255 gnus-agent-unhook-expire-days)))
2256 #'car-less-than-car)))
2257 ;; Skip converters older than the file version
2258 (while (and converters (>= fcv (caar converters)))
2259 (pop converters))
2260
2261 ;; Perform converters to bring older version up to date.
2262 (when (and converters (< fcv (caar converters)))
2263 (while (and converters (< fcv (caar converters))
2264 (<= (caar converters) gnus-version))
2265 (let* ((converter-spec (pop converters))
2266 (convert-to (nth 1 converter-spec))
2267 (load-from (nth 2 converter-spec))
2268 (func (nth 3 converter-spec)))
2269 (when (and load-from
2270 (not (fboundp func)))
2271 (load load-from t))
2272
2273 (or prompt-displayed
2274 (not (gnus-convert-converter-needs-prompt func))
2275 (while (let (c
2276 (cursor-in-echo-area t)
2277 (echo-keystrokes 0))
2278 (message "Convert gnus from version '%s' to '%s'? (n/y/?)"
2279 gnus-newsrc-file-version gnus-version)
2280 (setq c (read-char-exclusive))
2281
2282 (cond ((or (eq c ?n) (eq c ?N))
2283 (error "Can not start gnus without converting"))
2284 ((or (eq c ?y) (eq c ?Y))
2285 (setq prompt-displayed t)
2286 nil)
2287 ((eq c ?\?)
2288 (message "This conversion is irreversible. \
2289 To be safe, you should backup your files before proceeding.")
2290 (sit-for 5)
2291 t)
2292 (t
2293 (gnus-message 3 "Ignoring unexpected input")
2294 (sit-for 3)
2295 t)))))
2296
2297 (funcall func convert-to)))
2298 (gnus-dribble-enter
2299 (format ";Converted gnus from version '%s' to '%s'."
2300 gnus-newsrc-file-version gnus-version)))))))
2301
2302(defun gnus-convert-mark-converter-prompt (converter no-prompt)
2303 "Indicate whether CONVERTER requires gnus-convert-old-newsrc to
2304 display the conversion prompt. NO-PROMPT may be nil (prompt),
2305 t (no prompt), or any form that can be called as a function.
2306 The form should return either t or nil."
2307 (put converter 'gnus-convert-no-prompt no-prompt))
2308
2309(defun gnus-convert-converter-needs-prompt (converter)
2310 (let ((no-prompt (get converter 'gnus-convert-no-prompt)))
2311 (not (if (memq no-prompt '(t nil))
2312 no-prompt
2313 (funcall no-prompt)))))
2314
2315(defun gnus-convert-old-ticks (converting-to)
2219 (let ((newsrc (cdr gnus-newsrc-alist)) 2316 (let ((newsrc (cdr gnus-newsrc-alist))
2220 marks info dormant ticked) 2317 marks info dormant ticked)
2221 (while (setq info (pop newsrc)) 2318 (while (setq info (pop newsrc))
@@ -2594,6 +2691,10 @@ If FORCE is non-nil, the .newsrc file is read."
2594 ;; from the variable gnus-newsrc-alist. 2691 ;; from the variable gnus-newsrc-alist.
2595 (when (and (or gnus-newsrc-alist gnus-killed-list) 2692 (when (and (or gnus-newsrc-alist gnus-killed-list)
2596 gnus-current-startup-file) 2693 gnus-current-startup-file)
2694 ;; Save agent range limits for the currently active method.
2695 (when gnus-agent
2696 (gnus-agent-save-local force))
2697
2597 (save-excursion 2698 (save-excursion
2598 (if (and (or gnus-use-dribble-file gnus-slave) 2699 (if (and (or gnus-use-dribble-file gnus-slave)
2599 (not force) 2700 (not force)
@@ -2611,6 +2712,7 @@ If FORCE is non-nil, the .newsrc file is read."
2611 (gnus-message 8 "Saving %s..." gnus-current-startup-file) 2712 (gnus-message 8 "Saving %s..." gnus-current-startup-file)
2612 (gnus-gnus-to-newsrc-format) 2713 (gnus-gnus-to-newsrc-format)
2613 (gnus-message 8 "Saving %s...done" gnus-current-startup-file)) 2714 (gnus-message 8 "Saving %s...done" gnus-current-startup-file))
2715
2614 ;; Save .newsrc.eld. 2716 ;; Save .newsrc.eld.
2615 (set-buffer (gnus-get-buffer-create " *Gnus-newsrc*")) 2717 (set-buffer (gnus-get-buffer-create " *Gnus-newsrc*"))
2616 (make-local-variable 'version-control) 2718 (make-local-variable 'version-control)
diff --git a/lisp/gnus/gnus-sum.el b/lisp/gnus/gnus-sum.el
index 42c699ef552..68f40b3a7bb 100644
--- a/lisp/gnus/gnus-sum.el
+++ b/lisp/gnus/gnus-sum.el
@@ -44,6 +44,7 @@
44(autoload 'gnus-cache-write-active "gnus-cache") 44(autoload 'gnus-cache-write-active "gnus-cache")
45(autoload 'gnus-mailing-list-insinuate "gnus-ml" nil t) 45(autoload 'gnus-mailing-list-insinuate "gnus-ml" nil t)
46(autoload 'turn-on-gnus-mailing-list-mode "gnus-ml" nil t) 46(autoload 'turn-on-gnus-mailing-list-mode "gnus-ml" nil t)
47(autoload 'gnus-pick-line-number "gnus-salt" nil t)
47(autoload 'mm-uu-dissect "mm-uu") 48(autoload 'mm-uu-dissect "mm-uu")
48(autoload 'gnus-article-outlook-deuglify-article "deuglify" 49(autoload 'gnus-article-outlook-deuglify-article "deuglify"
49 "Deuglify broken Outlook (Express) articles and redisplay." 50 "Deuglify broken Outlook (Express) articles and redisplay."
@@ -2238,8 +2239,12 @@ gnus-summary-show-article-from-menu-as-charset-%s" cs))))
2238 ["Pipe through a filter..." gnus-summary-pipe-output t] 2239 ["Pipe through a filter..." gnus-summary-pipe-output t]
2239 ["Add to SOUP packet" gnus-soup-add-article t] 2240 ["Add to SOUP packet" gnus-soup-add-article t]
2240 ["Print with Muttprint..." gnus-summary-muttprint t] 2241 ["Print with Muttprint..." gnus-summary-muttprint t]
2241 ["Print" gnus-summary-print-article t]) 2242 ["Print" gnus-summary-print-article
2242 ("Backend" 2243 ,@(if (featurep 'xemacs) '(t)
2244 '(:help "Generate and print a PostScript image"))])
2245 ("Copy, move,... (Backend)"
2246 ,@(if (featurep 'xemacs) '(t)
2247 '(:help "Copying, moving, expiring articles..."))
2243 ["Respool article..." gnus-summary-respool-article t] 2248 ["Respool article..." gnus-summary-respool-article t]
2244 ["Move article..." gnus-summary-move-article 2249 ["Move article..." gnus-summary-move-article
2245 (gnus-check-backend-function 2250 (gnus-check-backend-function
@@ -2330,7 +2335,7 @@ gnus-summary-show-article-from-menu-as-charset-%s" cs))))
2330 `("Post" 2335 `("Post"
2331 ["Send a message (mail or news)" gnus-summary-post-news 2336 ["Send a message (mail or news)" gnus-summary-post-news
2332 ,@(if (featurep 'xemacs) '(t) 2337 ,@(if (featurep 'xemacs) '(t)
2333 '(:help "Post an article"))] 2338 '(:help "Compose a new message (mail or news)"))]
2334 ["Followup" gnus-summary-followup 2339 ["Followup" gnus-summary-followup
2335 ,@(if (featurep 'xemacs) '(t) 2340 ,@(if (featurep 'xemacs) '(t)
2336 '(:help "Post followup to this article"))] 2341 '(:help "Post followup to this article"))]
@@ -3229,28 +3234,34 @@ buffer that was in action when the last article was fetched."
3229 (save-excursion 3234 (save-excursion
3230 (gnus-set-work-buffer) 3235 (gnus-set-work-buffer)
3231 (let ((gnus-summary-line-format-spec spec) 3236 (let ((gnus-summary-line-format-spec spec)
3232 (gnus-newsgroup-downloadable '(0))) 3237 (gnus-newsgroup-downloadable '(0))
3238 marks)
3239 (insert ?\200 "\200" ?\201 "\201" ?\202 "\202" ?\203 "\203")
3240 (while (not (bobp))
3241 (push (buffer-substring (1- (point)) (point)) marks)
3242 (backward-char))
3243 (erase-buffer)
3233 (gnus-summary-insert-line 3244 (gnus-summary-insert-line
3234 [0 "" "" "05 Apr 2001 23:33:09 +0400" "" "" 0 0 "" nil] 3245 [0 "" "" "05 Apr 2001 23:33:09 +0400" "" "" 0 0 "" nil]
3235 0 nil t 128 t nil "" nil 1) 3246 0 nil t 128 t nil "" nil 1)
3236 (goto-char (point-min)) 3247 (goto-char (point-min))
3237 (setq pos (list (cons 'unread 3248 (setq pos (list (cons 'unread
3238 (and (search-forward 3249 (and (or (search-forward (nth 0 marks) nil t)
3239 (mm-string-as-multibyte "\200") nil t) 3250 (search-forward (nth 1 marks) nil t))
3240 (- (point) (point-min) 1))))) 3251 (- (point) (point-min) 1)))))
3241 (goto-char (point-min)) 3252 (goto-char (point-min))
3242 (push (cons 'replied (and (search-forward 3253 (push (cons 'replied (and (or (search-forward (nth 2 marks) nil t)
3243 (mm-string-as-multibyte "\201") nil t) 3254 (search-forward (nth 3 marks) nil t))
3244 (- (point) (point-min) 1))) 3255 (- (point) (point-min) 1)))
3245 pos) 3256 pos)
3246 (goto-char (point-min)) 3257 (goto-char (point-min))
3247 (push (cons 'score (and (search-forward 3258 (push (cons 'score (and (or (search-forward (nth 4 marks) nil t)
3248 (mm-string-as-multibyte "\202") nil t) 3259 (search-forward (nth 5 marks) nil t))
3249 (- (point) (point-min) 1))) 3260 (- (point) (point-min) 1)))
3250 pos) 3261 pos)
3251 (goto-char (point-min)) 3262 (goto-char (point-min))
3252 (push (cons 'download (and (search-forward 3263 (push (cons 'download (and (or (search-forward (nth 6 marks) nil t)
3253 (mm-string-as-multibyte "\203") nil t) 3264 (search-forward (nth 7 marks) nil t))
3254 (- (point) (point-min) 1))) 3265 (- (point) (point-min) 1)))
3255 pos))) 3266 pos)))
3256 (setq gnus-summary-mark-positions pos)))) 3267 (setq gnus-summary-mark-positions pos))))
@@ -5065,17 +5076,8 @@ If SELECT-ARTICLES, only select those articles from GROUP."
5065 group (gnus-status-message group))) 5076 group (gnus-status-message group)))
5066 5077
5067 (when gnus-agent 5078 (when gnus-agent
5068 ;; The agent may be storing articles that are no longer in the 5079 (gnus-agent-possibly-alter-active group (gnus-active group) info)
5069 ;; server's active range. If that is the case, the active range 5080
5070 ;; needs to be expanded such that the agent's articles can be
5071 ;; included in the summary.
5072 (let* ((gnus-command-method (gnus-find-method-for-group group))
5073 (alist (gnus-agent-load-alist group))
5074 (active (gnus-active group)))
5075 (if (and (car alist)
5076 (< (caar alist) (car active)))
5077 (gnus-set-active group (cons (caar alist) (cdr active)))))
5078
5079 (setq gnus-summary-use-undownloaded-faces 5081 (setq gnus-summary-use-undownloaded-faces
5080 (gnus-agent-find-parameter 5082 (gnus-agent-find-parameter
5081 group 5083 group
@@ -5404,7 +5406,8 @@ If SELECT-ARTICLES, only select those articles from GROUP."
5404 (min (car active)) 5406 (min (car active))
5405 (max (cdr active)) 5407 (max (cdr active))
5406 (types gnus-article-mark-lists) 5408 (types gnus-article-mark-lists)
5407 marks var articles article mark mark-type) 5409 marks var articles article mark mark-type
5410 bgn end)
5408 5411
5409 (dolist (marks marked-lists) 5412 (dolist (marks marked-lists)
5410 (setq mark (car marks) 5413 (setq mark (car marks)
@@ -5414,13 +5417,30 @@ If SELECT-ARTICLES, only select those articles from GROUP."
5414 ;; We set the variable according to the type of the marks list, 5417 ;; We set the variable according to the type of the marks list,
5415 ;; and then adjust the marks to a subset of the active articles. 5418 ;; and then adjust the marks to a subset of the active articles.
5416 (cond 5419 (cond
5417 ;; Adjust "simple" lists. 5420 ;; Adjust "simple" lists - compressed yet unsorted
5418 ((eq mark-type 'list) 5421 ((eq mark-type 'list)
5419 (set var (setq articles (gnus-uncompress-range (cdr marks)))) 5422 ;; Simultaneously uncompress and clip to active range
5420 (when (memq mark '(tick dormant expire reply save)) 5423 ;; See gnus-uncompress-range for a description of possible marks
5421 (while articles 5424 (let (l lh)
5422 (when (or (< (setq article (pop articles)) min) (> article max)) 5425 (if (not (cadr marks))
5423 (set var (delq article (symbol-value var))))))) 5426 (set var nil)
5427 (setq articles (if (numberp (cddr marks))
5428 (list (cdr marks))
5429 (cdr marks))
5430 lh (cons nil nil)
5431 l lh)
5432
5433 (while (setq article (pop articles))
5434 (cond ((consp article)
5435 (setq bgn (max (car article) min)
5436 end (min (cdr article) max))
5437 (while (<= bgn end)
5438 (setq l (setcdr l (cons bgn nil))
5439 bgn (1+ bgn))))
5440 ((and (<= min article)
5441 (>= max article))
5442 (setq l (setcdr l (cons article nil))))))
5443 (set var (cdr lh)))))
5424 ;; Adjust assocs. 5444 ;; Adjust assocs.
5425 ((eq mark-type 'tuple) 5445 ((eq mark-type 'tuple)
5426 (set var (setq articles (cdr marks))) 5446 (set var (setq articles (cdr marks)))
@@ -6353,15 +6373,15 @@ displayed, no centering will be performed."
6353 (while read 6373 (while read
6354 (when first 6374 (when first
6355 (while (< first nlast) 6375 (while (< first nlast)
6356 (push first unread) 6376 (setq unread (cons first unread)
6357 (setq first (1+ first)))) 6377 first (1+ first))))
6358 (setq first (1+ (if (atom (car read)) (car read) (cdar read)))) 6378 (setq first (1+ (if (atom (car read)) (car read) (cdar read))))
6359 (setq nlast (if (atom (cadr read)) (cadr read) (caadr read))) 6379 (setq nlast (if (atom (cadr read)) (cadr read) (caadr read)))
6360 (setq read (cdr read))))) 6380 (setq read (cdr read)))))
6361 ;; And add the last unread articles. 6381 ;; And add the last unread articles.
6362 (while (<= first last) 6382 (while (<= first last)
6363 (push first unread) 6383 (setq unread (cons first unread)
6364 (setq first (1+ first))) 6384 first (1+ first)))
6365 ;; Return the list of unread articles. 6385 ;; Return the list of unread articles.
6366 (delq 0 (nreverse unread)))) 6386 (delq 0 (nreverse unread))))
6367 6387
@@ -6379,6 +6399,44 @@ displayed, no centering will be performed."
6379 (cdr (assq 'dormant marked))) 6399 (cdr (assq 'dormant marked)))
6380 (cdr (assq 'tick marked)))))) 6400 (cdr (assq 'tick marked))))))
6381 6401
6402;; This function returns a sequence of article numbers based on the
6403;; difference between the ranges of read articles in this group and
6404;; the range of active articles.
6405(defun gnus-sequence-of-unread-articles (group)
6406 (let* ((read (gnus-info-read (gnus-get-info group)))
6407 (active (or (gnus-active group) (gnus-activate-group group)))
6408 (last (cdr active))
6409 first nlast unread)
6410 ;; If none are read, then all are unread.
6411 (if (not read)
6412 (setq first (car active))
6413 ;; If the range of read articles is a single range, then the
6414 ;; first unread article is the article after the last read
6415 ;; article. Sounds logical, doesn't it?
6416 (if (and (not (listp (cdr read)))
6417 (or (< (car read) (car active))
6418 (progn (setq read (list read))
6419 nil)))
6420 (setq first (max (car active) (1+ (cdr read))))
6421 ;; `read' is a list of ranges.
6422 (when (/= (setq nlast (or (and (numberp (car read)) (car read))
6423 (caar read)))
6424 1)
6425 (setq first (car active)))
6426 (while read
6427 (when first
6428 (push (cons first nlast) unread))
6429 (setq first (1+ (if (atom (car read)) (car read) (cdar read))))
6430 (setq nlast (if (atom (cadr read)) (cadr read) (caadr read)))
6431 (setq read (cdr read)))))
6432 ;; And add the last unread articles.
6433 (cond ((< first last)
6434 (push (cons first last) unread))
6435 ((= first last)
6436 (push first unread)))
6437 ;; Return the sequence of unread articles.
6438 (delq 0 (nreverse unread))))
6439
6382;; Various summary commands 6440;; Various summary commands
6383 6441
6384(defun gnus-summary-select-article-buffer () 6442(defun gnus-summary-select-article-buffer ()
@@ -11305,7 +11363,8 @@ If REVERSE, save parts that do not match TYPE."
11305 (default-high gnus-summary-default-high-score) 11363 (default-high gnus-summary-default-high-score)
11306 (default-low gnus-summary-default-low-score) 11364 (default-low gnus-summary-default-low-score)
11307 (uncached (and gnus-summary-use-undownloaded-faces 11365 (uncached (and gnus-summary-use-undownloaded-faces
11308 (memq article gnus-newsgroup-undownloaded)))) 11366 (memq article gnus-newsgroup-undownloaded)
11367 (not (memq article gnus-newsgroup-cached)))))
11309 (let ((face (funcall (gnus-summary-highlight-line-0)))) 11368 (let ((face (funcall (gnus-summary-highlight-line-0))))
11310 (unless (eq face (get-text-property beg 'face)) 11369 (unless (eq face (get-text-property beg 'face))
11311 (gnus-put-text-property-excluding-characters-with-faces 11370 (gnus-put-text-property-excluding-characters-with-faces
diff --git a/lisp/gnus/gnus-util.el b/lisp/gnus/gnus-util.el
index 22db7ecd6d1..4b71e252f6e 100644
--- a/lisp/gnus/gnus-util.el
+++ b/lisp/gnus/gnus-util.el
@@ -38,7 +38,11 @@
38(eval-when-compile 38(eval-when-compile
39 (require 'cl) 39 (require 'cl)
40 ;; Fixme: this should be a gnus variable, not nnmail-. 40 ;; Fixme: this should be a gnus variable, not nnmail-.
41 (defvar nnmail-pathname-coding-system)) 41 (defvar nnmail-pathname-coding-system)
42
43 ;; Inappropriate references to other parts of Gnus.
44 (defvar gnus-emphasize-whitespace-regexp)
45 )
42(require 'time-date) 46(require 'time-date)
43(require 'netrc) 47(require 'netrc)
44 48
@@ -1186,7 +1190,7 @@ is run."
1186 "Delete by side effect any elements of LIST whose car is `equal' to KEY. 1190 "Delete by side effect any elements of LIST whose car is `equal' to KEY.
1187The modified LIST is returned. If the first member 1191The modified LIST is returned. If the first member
1188of LIST has a car that is `equal' to KEY, there is no way to remove it 1192of LIST has a car that is `equal' to KEY, there is no way to remove it
1189by side effect; therefore, write `(setq foo (remassoc key foo))' to be 1193by side effect; therefore, write `(setq foo (gnus-remassoc key foo))' to be
1190sure of changing the value of `foo'." 1194sure of changing the value of `foo'."
1191 (when alist 1195 (when alist
1192 (if (equal key (caar alist)) 1196 (if (equal key (caar alist))
@@ -1512,6 +1516,28 @@ predicate on the elements."
1512 ""))) 1516 "")))
1513 (t emacs-version)))) 1517 (t emacs-version))))
1514 1518
1519(defun gnus-rename-file (old-path new-path &optional trim)
1520 "Rename OLD-PATH as NEW-PATH. If TRIM, recursively delete
1521empty directories from OLD-PATH."
1522 (when (file-exists-p old-path)
1523 (let* ((old-dir (file-name-directory old-path))
1524 (old-name (file-name-nondirectory old-path))
1525 (new-dir (file-name-directory new-path))
1526 (new-name (file-name-nondirectory new-path))
1527 temp)
1528 (gnus-make-directory new-dir)
1529 (rename-file old-path new-path t)
1530 (when trim
1531 (while (progn (setq temp (directory-files old-dir))
1532 (while (member (car temp) '("." ".."))
1533 (setq temp (cdr temp)))
1534 (= (length temp) 0))
1535 (delete-directory old-dir)
1536 (setq old-dir (file-name-as-directory
1537 (file-truename
1538 (concat old-dir "..")))))))))
1539
1540
1515(provide 'gnus-util) 1541(provide 'gnus-util)
1516 1542
1517;;; arch-tag: f94991af-d32b-4c97-8c26-ca12a934de49 1543;;; arch-tag: f94991af-d32b-4c97-8c26-ca12a934de49
diff --git a/lisp/gnus/imap.el b/lisp/gnus/imap.el
index 326c998c5d9..6ef8dfa5fe2 100644
--- a/lisp/gnus/imap.el
+++ b/lisp/gnus/imap.el
@@ -270,6 +270,11 @@ Shorter values mean quicker response, but is more CPU intensive."
270 :type 'number 270 :type 'number
271 :group 'imap) 271 :group 'imap)
272 272
273(defcustom imap-store-password nil
274 "If non-nil, store session password without promting."
275 :group 'imap
276 :type 'boolean)
277
273;; Various variables. 278;; Various variables.
274 279
275(defvar imap-fetch-data-hook nil 280(defvar imap-fetch-data-hook nil
@@ -827,9 +832,10 @@ Returns t if login was successful, nil otherwise."
827 (progn 832 (progn
828 (setq ret t 833 (setq ret t
829 imap-username user) 834 imap-username user)
830 (if (and (not imap-password) 835 (when (and (not imap-password)
831 (y-or-n-p "Store password for this session? ")) 836 (or imap-store-password
832 (setq imap-password passwd))) 837 (y-or-n-p "Store password for this session? ")))
838 (setq imap-password passwd)))
833 (message "Login failed...") 839 (message "Login failed...")
834 (setq passwd nil) 840 (setq passwd nil)
835 (setq imap-password nil) 841 (setq imap-password nil)
diff --git a/lisp/gnus/legacy-gnus-agent.el b/lisp/gnus/legacy-gnus-agent.el
new file mode 100644
index 00000000000..16b0cf6c89f
--- /dev/null
+++ b/lisp/gnus/legacy-gnus-agent.el
@@ -0,0 +1,227 @@
1(require 'gnus-start)
2(require 'gnus-util)
3(require 'gnus-range)
4(require 'gnus-agent)
5
6; Oort Gnus v0.08 - This release updated agent to no longer use
7; history file and to support a compressed alist.
8
9(defvar gnus-agent-compressed-agentview-search-only nil)
10
11(defun gnus-agent-convert-to-compressed-agentview (converting-to)
12 "Iterates over all agentview files to ensure that they have been
13converted to the compressed format."
14
15 (let ((search-in (list gnus-agent-directory))
16 here
17 members
18 member
19 converted-something)
20 (while (setq here (pop search-in))
21 (setq members (directory-files here t))
22 (while (setq member (pop members))
23 (cond ((string-match "/\\.\\.?$" member)
24 nil)
25 ((file-directory-p member)
26 (push member search-in))
27 ((equal (file-name-nondirectory member) ".agentview")
28 (setq converted-something
29 (or (gnus-agent-convert-agentview member)
30 converted-something))))))
31
32 (if converted-something
33 (gnus-message 4 "Successfully converted Gnus %s offline (agent) files to %s" gnus-newsrc-file-version converting-to))))
34
35(defun gnus-agent-convert-to-compressed-agentview-prompt ()
36 (catch 'found-file-to-convert
37 (let ((gnus-agent-compressed-agentview-search-only t))
38 (gnus-agent-convert-to-compressed-agentview nil))))
39
40(gnus-convert-mark-converter-prompt 'gnus-agent-convert-to-compressed-agentview 'gnus-agent-convert-to-compressed-agentview-prompt)
41
42(defun gnus-agent-convert-agentview (file)
43 "Load FILE and do a `read' there."
44 (with-temp-buffer
45 (nnheader-insert-file-contents file)
46 (goto-char (point-min))
47 (let ((inhibit-quit t)
48 (alist (read (current-buffer)))
49 (version (condition-case nil (read (current-buffer))
50 (end-of-file 0)))
51 changed-version
52 history-file)
53
54 (cond
55 ((= version 0)
56 (let (entry
57 (gnus-command-method nil))
58 (mm-disable-multibyte) ;; everything is binary
59 (erase-buffer)
60 (insert "\n")
61 (let ((file (concat (file-name-directory file) "/history")))
62 (when (file-exists-p file)
63 (nnheader-insert-file-contents file)
64 (setq history-file file)))
65
66 (goto-char (point-min))
67 (while (not (eobp))
68 (if (and (looking-at
69 "[^\t\n]+\t\\([0-9]+\\)\t\\([^ \n]+\\) \\([0-9]+\\)")
70 (string= (gnus-agent-article-name ".agentview" (match-string 2))
71 file)
72 (setq entry (assoc (string-to-number (match-string 3)) alist)))
73 (setcdr entry (string-to-number (match-string 1))))
74 (forward-line 1))
75 (setq changed-version t)))
76 ((= version 1)
77 (setq changed-version t)))
78
79 (when changed-version
80 (when gnus-agent-compressed-agentview-search-only
81 (throw 'found-file-to-convert t))
82
83 (erase-buffer)
84 (let ((compressed nil))
85 (mapcar (lambda (pair)
86 (let* ((article-id (car pair))
87 (day-of-download (cdr pair))
88 (comp-list (assq day-of-download compressed)))
89 (if comp-list
90 (setcdr comp-list
91 (cons article-id (cdr comp-list)))
92 (setq compressed
93 (cons (list day-of-download article-id)
94 compressed)))
95 nil)) alist)
96 (mapcar (lambda (comp-list)
97 (setcdr comp-list
98 (gnus-compress-sequence
99 (nreverse (cdr comp-list)))))
100 compressed)
101 (princ compressed (current-buffer)))
102 (insert "\n2\n")
103 (write-file file)
104 (when history-file
105 (delete-file history-file))
106 t))))
107
108;; End of Oort Gnus v0.08 updates
109
110;; No Gnus v0.3 - This release provides a mechanism for upgrading gnus
111;; from previous versions. Therefore, the previous
112;; hacks to handle a gnus-agent-expire-days that
113;; specifies a list of values can be removed.
114
115(defun gnus-agent-unlist-expire-days (converting-to)
116 (when (listp gnus-agent-expire-days)
117 (let (buffer)
118 (unwind-protect
119 (save-window-excursion
120 (setq buffer (gnus-get-buffer-create " *Gnus agent upgrade*"))
121 (set-buffer buffer)
122 (erase-buffer)
123 (insert "The definition of gnus-agent-expire-days has been changed.\nYou currently have it set to the list:\n ")
124 (gnus-pp gnus-agent-expire-days)
125
126 (insert "\nIn order to use version '" converting-to "' of gnus, you will need to set\n")
127 (insert "gnus-agent-expire-days to an integer. If you still wish to set different\n")
128 (insert "expiration days to individual groups, you must instead set the\n")
129 (insert "'agent-days-until-old group and/or topic parameter.\n")
130 (insert "\n")
131 (insert "If you would like, gnus can iterate over every group comparing its name to the\n")
132 (insert "regular expressions that you currently have in gnus-agent-expire-days. When\n")
133 (insert "gnus finds a match, it will update that group's 'agent-days-until-old group\n")
134 (insert "parameter to the value associated with the regular expression.\n")
135 (insert "\n")
136 (insert "Whether gnus assigns group parameters, or not, gnus will terminate with an\n")
137 (insert "ERROR as soon as this function completes. The reason is that you must\n")
138 (insert "manually edit your configuration to either not set gnus-agent-expire-days or\n")
139 (insert "to set it to an integer before gnus can be used.\n")
140 (insert "\n")
141 (insert "Once you have successfully edited gnus-agent-expire-days, gnus will be able to\n")
142 (insert "execute past this function.\n")
143 (insert "\n")
144 (insert "Should gnus use gnus-agent-expire-days to assign\n")
145 (insert "agent-days-until-old parameters to individual groups? (Y/N)")
146
147 (switch-to-buffer buffer)
148 (beep)
149 (beep)
150
151 (let ((echo-keystrokes 0)
152 c)
153 (while (progn (setq c (read-char-exclusive))
154 (cond ((or (eq c ?y) (eq c ?Y))
155 (save-excursion
156 (let ((groups (gnus-group-listed-groups)))
157 (while groups
158 (let* ((group (pop groups))
159 (days gnus-agent-expire-days)
160 (day (catch 'found
161 (while days
162 (when (eq 0 (string-match
163 (caar days)
164 group))
165 (throw 'found (cadar days)))
166 (setq days (cdr days)))
167 nil)))
168 (when day
169 (gnus-group-set-parameter group 'agent-days-until-old
170 day))))))
171 nil
172 )
173 ((or (eq c ?n) (eq c ?N))
174 nil)
175 (t
176 t))))))
177 (kill-buffer buffer))
178 (error "Change gnus-agent-expire-days to an integer for gnus to start."))))
179
180;; The gnus-agent-unlist-expire-days has its own conversion prompt.
181;; Therefore, hide the default prompt.
182(gnus-convert-mark-converter-prompt 'gnus-agent-unlist-expire-days t)
183
184(defun gnus-agent-unhook-expire-days (converting-to)
185 "Remove every lambda from gnus-group-prepare-hook that mention the
186symbol gnus-agent-do-once in their definition. This should NOT be
187necessary as gnus-agent.el no longer adds them. However, it is
188possible that the hook was persistently saved."
189 (let ((h t)) ; iterate from bgn of hook
190 (while h
191 (let ((func (progn (when (eq h t)
192 ;; init h to list of functions
193 (setq h (cond ((listp gnus-group-prepare-hook)
194 gnus-group-prepare-hook)
195 ((boundp 'gnus-group-prepare-hook)
196 (list gnus-group-prepare-hook)))))
197 (pop h))))
198
199 (when (cond ((eq (type-of func) 'compiled-function)
200 ;; Search def. of compiled function for gnus-agent-do-once string
201 (let* (definition
202 print-level
203 print-length
204 (standard-output
205 (lambda (char)
206 (setq definition (cons char definition)))))
207 (princ func) ; populates definition with reversed list of characters
208 (let* ((i (length definition))
209 (s (make-string i 0)))
210 (while definition
211 (aset s (setq i (1- i)) (pop definition)))
212
213 (string-match "\\bgnus-agent-do-once\\b" s))))
214 ((listp func)
215 (eq (cadr (nth 2 func)) 'gnus-agent-do-once) ; handles eval'd lambda
216 ))
217
218 (remove-hook 'gnus-group-prepare-hook func)
219 ;; I don't what remove-hook is going to actually do to the
220 ;; hook list so start over from the beginning.
221 (setq h t))))))
222
223;; gnus-agent-unhook-expire-days is safe in that it does not modify
224;; the .newsrc.eld file.
225(gnus-convert-mark-converter-prompt 'gnus-agent-unhook-expire-days t)
226
227;;; arch-tag: 845c7b8a-88f7-4468-b8d7-94e8fc72cf1a
diff --git a/lisp/gnus/mail-source.el b/lisp/gnus/mail-source.el
index b35cd1d0448..740f4c9c3a3 100644
--- a/lisp/gnus/mail-source.el
+++ b/lisp/gnus/mail-source.el
@@ -257,7 +257,7 @@ If non-nil, this maildrop will be checked periodically for new mail."
257 :type 'file) 257 :type 'file)
258 258
259(defcustom mail-source-directory message-directory 259(defcustom mail-source-directory message-directory
260 "Directory where files (if any) will be stored." 260 "Directory where incoming mail source files (if any) will be stored."
261 :group 'mail-source 261 :group 'mail-source
262 :type 'directory) 262 :type 'directory)
263 263
diff --git a/lisp/gnus/message.el b/lisp/gnus/message.el
index c9d05d1a0fe..585a72af549 100644
--- a/lisp/gnus/message.el
+++ b/lisp/gnus/message.el
@@ -255,7 +255,12 @@ included. Organization and User-Agent are optional."
255 :group 'message-news 255 :group 'message-news
256 :group 'message-headers 256 :group 'message-headers
257 :link '(custom-manual "(message)Message Headers") 257 :link '(custom-manual "(message)Message Headers")
258 :type 'regexp) 258 :type '(repeat :value-to-internal (lambda (widget value)
259 (custom-split-regexp-maybe value))
260 :match (lambda (widget value)
261 (or (stringp value)
262 (widget-editable-list-match widget value)))
263 regexp))
259 264
260(defcustom message-ignored-mail-headers 265(defcustom message-ignored-mail-headers
261 "^[GF]cc:\\|^Resent-Fcc:\\|^Xref:\\|^X-Draft-From:\\|^X-Gnus-Agent-Meta-Information:" 266 "^[GF]cc:\\|^Resent-Fcc:\\|^Xref:\\|^X-Draft-From:\\|^X-Gnus-Agent-Meta-Information:"
@@ -271,7 +276,12 @@ It's best to delete old Path and Date headers before posting to avoid
271any confusion." 276any confusion."
272 :group 'message-interface 277 :group 'message-interface
273 :link '(custom-manual "(message)Superseding") 278 :link '(custom-manual "(message)Superseding")
274 :type 'regexp) 279 :type '(repeat :value-to-internal (lambda (widget value)
280 (custom-split-regexp-maybe value))
281 :match (lambda (widget value)
282 (or (stringp value)
283 (widget-editable-list-match widget value)))
284 regexp))
275 285
276(defcustom message-subject-re-regexp 286(defcustom message-subject-re-regexp
277 "^[ \t]*\\([Rr][Ee]\\(\\[[0-9]*\\]\\)*:[ \t]*\\)*[ \t]*" 287 "^[ \t]*\\([Rr][Ee]\\(\\[[0-9]*\\]\\)*:[ \t]*\\)*[ \t]*"
@@ -534,13 +544,22 @@ Done before generating the new subject of a forward."
534 "*All headers that match this regexp will be deleted when resending a message." 544 "*All headers that match this regexp will be deleted when resending a message."
535 :group 'message-interface 545 :group 'message-interface
536 :link '(custom-manual "(message)Resending") 546 :link '(custom-manual "(message)Resending")
537 :type 'regexp) 547 :type '(repeat :value-to-internal (lambda (widget value)
548 (custom-split-regexp-maybe value))
549 :match (lambda (widget value)
550 (or (stringp value)
551 (widget-editable-list-match widget value)))
552 regexp))
538 553
539(defcustom message-forward-ignored-headers "^Content-Transfer-Encoding:\\|^X-Gnus" 554(defcustom message-forward-ignored-headers "^Content-Transfer-Encoding:\\|^X-Gnus"
540 "*All headers that match this regexp will be deleted when forwarding a message." 555 "*All headers that match this regexp will be deleted when forwarding a message."
541 :version "21.1" 556 :version "21.1"
542 :group 'message-forwarding 557 :group 'message-forwarding
543 :type '(choice (const :tag "None" nil) 558 :type '(repeat :value-to-internal (lambda (widget value)
559 (custom-split-regexp-maybe value))
560 :match (lambda (widget value)
561 (or (stringp value)
562 (widget-editable-list-match widget value)))
544 regexp)) 563 regexp))
545 564
546(defcustom message-ignored-cited-headers "." 565(defcustom message-ignored-cited-headers "."
@@ -2610,7 +2629,7 @@ M-RET `message-newline-and-reformat' (break the line and reformat)."
2610(defun message-goto-mail-followup-to () 2629(defun message-goto-mail-followup-to ()
2611 "Move point to the Mail-Followup-To header." 2630 "Move point to the Mail-Followup-To header."
2612 (interactive) 2631 (interactive)
2613 (message-position-on-field "Mail-Followup-To" "From")) 2632 (message-position-on-field "Mail-Followup-To" "To"))
2614 2633
2615(defun message-goto-keywords () 2634(defun message-goto-keywords ()
2616 "Move point to the Keywords header." 2635 "Move point to the Keywords header."
@@ -2720,6 +2739,7 @@ or in the synonym headers, defined by `message-header-synonyms'."
2720 ;; FIXME: Should compare only the address and not the full name. Comparison 2739 ;; FIXME: Should compare only the address and not the full name. Comparison
2721 ;; should be done case-folded (and with `string=' rather than 2740 ;; should be done case-folded (and with `string=' rather than
2722 ;; `string-match'). 2741 ;; `string-match').
2742 ;; (mail-strip-quoted-names "Foo Bar <foo@bar>, bla@fasel (Bla Fasel)")
2723 (dolist (header headers) 2743 (dolist (header headers)
2724 (let* ((header-name (symbol-name (car header))) 2744 (let* ((header-name (symbol-name (car header)))
2725 (new-header (cdr header)) 2745 (new-header (cdr header))
diff --git a/lisp/gnus/mm-view.el b/lisp/gnus/mm-view.el
index c0ed098fa6f..2b58d103ade 100644
--- a/lisp/gnus/mm-view.el
+++ b/lisp/gnus/mm-view.el
@@ -199,13 +199,14 @@
199 (setq w3m-display-inline-images mm-inline-text-html-with-images)) 199 (setq w3m-display-inline-images mm-inline-text-html-with-images))
200 200
201(defun mm-w3m-cid-retrieve-1 (url handle) 201(defun mm-w3m-cid-retrieve-1 (url handle)
202 (if (mm-multiple-handles handle) 202 (dolist (elem handle)
203 (dolist (elem handle) 203 (when (listp elem)
204 (mm-w3m-cid-retrieve-1 url elem)) 204 (if (equal url (mm-handle-id elem))
205 (when (and (listp handle) 205 (progn
206 (equal url (mm-handle-id handle))) 206 (mm-insert-part elem)
207 (mm-insert-part handle) 207 (throw 'found-handle (mm-handle-media-type elem))))
208 (throw 'found-handle (mm-handle-media-type handle))))) 208 (if (equal "multipart" (mm-handle-media-supertype elem))
209 (mm-w3m-cid-retrieve-1 url elem)))))
209 210
210(defun mm-w3m-cid-retrieve (url &rest args) 211(defun mm-w3m-cid-retrieve (url &rest args)
211 "Insert a content pointed by URL if it has the cid: scheme." 212 "Insert a content pointed by URL if it has the cid: scheme."
@@ -465,8 +466,12 @@
465 (progn 466 (progn
466 (buffer-disable-undo) 467 (buffer-disable-undo)
467 (mm-insert-part handle) 468 (mm-insert-part handle)
468 (funcall mode)
469 (require 'font-lock) 469 (require 'font-lock)
470 ;; Inhibit font-lock this time (*-mode-hook might run
471 ;; `turn-on-font-lock') so that jit-lock may not turn off
472 ;; font-lock immediately after this.
473 (let ((font-lock-mode t))
474 (funcall mode))
470 (let ((font-lock-verbose nil)) 475 (let ((font-lock-verbose nil))
471 ;; I find font-lock a bit too verbose. 476 ;; I find font-lock a bit too verbose.
472 (font-lock-fontify-buffer)) 477 (font-lock-fontify-buffer))
diff --git a/lisp/gnus/mml.el b/lisp/gnus/mml.el
index 221e1712611..d88f6318159 100644
--- a/lisp/gnus/mml.el
+++ b/lisp/gnus/mml.el
@@ -1076,9 +1076,9 @@ If RAW, don't highlight the article."
1076 (message-fetch-field "Newsgroups"))) 1076 (message-fetch-field "Newsgroups")))
1077 message-posting-charset))) 1077 message-posting-charset)))
1078 (message-options-set-recipient) 1078 (message-options-set-recipient)
1079 (switch-to-buffer (generate-new-buffer 1079 (pop-to-buffer (generate-new-buffer
1080 (concat (if raw "*Raw MIME preview of " 1080 (concat (if raw "*Raw MIME preview of "
1081 "*MIME preview of ") (buffer-name)))) 1081 "*MIME preview of ") (buffer-name))))
1082 (when (boundp 'gnus-buffers) 1082 (when (boundp 'gnus-buffers)
1083 (push (current-buffer) gnus-buffers)) 1083 (push (current-buffer) gnus-buffers))
1084 (erase-buffer) 1084 (erase-buffer)
diff --git a/lisp/gnus/nnagent.el b/lisp/gnus/nnagent.el
index 669aa6904dd..a17e92ce001 100644
--- a/lisp/gnus/nnagent.el
+++ b/lisp/gnus/nnagent.el
@@ -103,7 +103,7 @@
103 103
104(defun nnagent-request-type (group article) 104(defun nnagent-request-type (group article)
105 (unless (stringp article) 105 (unless (stringp article)
106 (let ((gnus-plugged t)) 106 (let ((gnus-agent nil))
107 (if (not (gnus-check-backend-function 107 (if (not (gnus-check-backend-function
108 'request-type (car gnus-command-method))) 108 'request-type (car gnus-command-method)))
109 'unknown 109 'unknown
@@ -122,9 +122,14 @@
122 122
123(deffoo nnagent-request-set-mark (group action server) 123(deffoo nnagent-request-set-mark (group action server)
124 (with-temp-buffer 124 (with-temp-buffer
125 (insert (format "(%s-request-set-mark \"%s\" '%s \"%s\")\n" 125 (insert "(gnus-agent-synchronize-group-flags \""
126 (nth 0 gnus-command-method) group action 126 group
127 (or server (nth 1 gnus-command-method)))) 127 "\" '")
128 (gnus-pp action)
129 (insert " \""
130 (gnus-method-to-server gnus-command-method)
131 "\"")
132 (insert ")\n")
128 (append-to-file (point-min) (point-max) (gnus-agent-lib-file "flags"))) 133 (append-to-file (point-min) (point-max) (gnus-agent-lib-file "flags")))
129 nil) 134 nil)
130 135
diff --git a/lisp/gnus/nnspool.el b/lisp/gnus/nnspool.el
index eaf5159be8f..9a08cdfe71c 100644
--- a/lisp/gnus/nnspool.el
+++ b/lisp/gnus/nnspool.el
@@ -44,7 +44,7 @@ This is most commonly `inews' or `injnews'.")
44 "Switches for nnspool-request-post to pass to `inews' for posting news. 44 "Switches for nnspool-request-post to pass to `inews' for posting news.
45If you are using Cnews, you probably should set this variable to nil.") 45If you are using Cnews, you probably should set this variable to nil.")
46 46
47(defvoo nnspool-spool-directory (file-name-as-directory news-path) 47(defvoo nnspool-spool-directory (file-name-as-directory news-directory)
48 "Local news spool directory.") 48 "Local news spool directory.")
49 49
50(defvoo nnspool-nov-directory (concat nnspool-spool-directory "over.view/") 50(defvoo nnspool-nov-directory (concat nnspool-spool-directory "over.view/")
diff --git a/lisp/gnus/pop3.el b/lisp/gnus/pop3.el
index e288f6cace2..db8753057d6 100644
--- a/lisp/gnus/pop3.el
+++ b/lisp/gnus/pop3.el
@@ -83,7 +83,14 @@ values are 'apop."
83 :group 'pop3) 83 :group 'pop3)
84 84
85(defcustom pop3-leave-mail-on-server nil 85(defcustom pop3-leave-mail-on-server nil
86 "*Non-nil if the mail is to be left on the POP server after fetching." 86 "*Non-nil if the mail is to be left on the POP server after fetching.
87
88If the `pop3-leave-mail-on-server' is non-`nil' the mail is to be
89left on the POP server after fetching. Note that POP servers
90maintain no state information between sessions, so what the
91client believes is there and what is actually there may not match
92up. If they do not, then the whole thing can fall apart and
93leave you with a corrupt mailbox."
87 :version "21.4" ;; Oort Gnus 94 :version "21.4" ;; Oort Gnus
88 :type 'boolean 95 :type 'boolean
89 :group 'pop3) 96 :group 'pop3)
@@ -95,6 +102,32 @@ Used for APOP authentication.")
95(defvar pop3-read-point nil) 102(defvar pop3-read-point nil)
96(defvar pop3-debug nil) 103(defvar pop3-debug nil)
97 104
105;; Borrowed from nnheader-accept-process-output in nnheader.el.
106(defvar pop3-read-timeout
107 (if (string-match "windows-nt\\|os/2\\|emx\\|cygwin"
108 (symbol-name system-type))
109 ;; http://thread.gmane.org/v9655t3pjo.fsf@marauder.physik.uni-ulm.de
110 ;;
111 ;; IIRC, values lower than 1.0 didn't/don't work on Windows/DOS.
112 ;;
113 ;; There should probably be a runtime test to determine the timing
114 ;; resolution, or a primitive to report it. I don't know off-hand
115 ;; what's possible. Perhaps better, maybe the Windows/DOS primitive
116 ;; could round up non-zero timeouts to a minimum of 1.0?
117 1.0
118 0.1)
119 "How long pop3 should wait between checking for the end of output.
120Shorter values mean quicker response, but are more CPU intensive.")
121
122;; Borrowed from nnheader-accept-process-output in nnheader.el.
123(defun pop3-accept-process-output (process)
124 (accept-process-output
125 process
126 (truncate pop3-read-timeout)
127 (truncate (* (- pop3-read-timeout
128 (truncate pop3-read-timeout))
129 1000))))
130
98(defun pop3-movemail (&optional crashbox) 131(defun pop3-movemail (&optional crashbox)
99 "Transfer contents of a maildrop to the specified CRASHBOX." 132 "Transfer contents of a maildrop to the specified CRASHBOX."
100 (or crashbox (setq crashbox (expand-file-name "~/.crashbox"))) 133 (or crashbox (setq crashbox (expand-file-name "~/.crashbox")))
@@ -207,7 +240,7 @@ Return the response string if optional second argument is non-nil."
207 (goto-char pop3-read-point) 240 (goto-char pop3-read-point)
208 (while (and (memq (process-status process) '(open run)) 241 (while (and (memq (process-status process) '(open run))
209 (not (search-forward "\r\n" nil t))) 242 (not (search-forward "\r\n" nil t)))
210 (nnheader-accept-process-output process) 243 (pop3-accept-process-output process)
211 (goto-char pop3-read-point)) 244 (goto-char pop3-read-point))
212 (setq match-end (point)) 245 (setq match-end (point))
213 (goto-char pop3-read-point) 246 (goto-char pop3-read-point)
@@ -381,8 +414,7 @@ This function currently does nothing.")
381 (save-excursion 414 (save-excursion
382 (set-buffer (process-buffer process)) 415 (set-buffer (process-buffer process))
383 (while (not (re-search-forward "^\\.\r\n" nil t)) 416 (while (not (re-search-forward "^\\.\r\n" nil t))
384 ;; Fixme: Shouldn't depend on nnheader. 417 (pop3-accept-process-output process)
385 (nnheader-accept-process-output process)
386 (goto-char start)) 418 (goto-char start))
387 (setq pop3-read-point (point-marker)) 419 (setq pop3-read-point (point-marker))
388 ;; this code does not seem to work for some POP servers... 420 ;; this code does not seem to work for some POP servers...
diff --git a/lisp/gnus/spam-stat.el b/lisp/gnus/spam-stat.el
index 9e20a51b127..f197d165cdd 100644
--- a/lisp/gnus/spam-stat.el
+++ b/lisp/gnus/spam-stat.el
@@ -594,6 +594,8 @@ COUNT defaults to 5"
594 (remove-hook 'gnus-select-article-hook 594 (remove-hook 'gnus-select-article-hook
595 'spam-stat-store-gnus-article-buffer)) 595 'spam-stat-store-gnus-article-buffer))
596 596
597(add-hook 'spam-stat-unload-hook 'spam-stat-unload-hook)
598
597(provide 'spam-stat) 599(provide 'spam-stat)
598 600
599;;; arch-tag: ff1d2200-8ddb-42fb-bb7b-1b5e20448554 601;;; arch-tag: ff1d2200-8ddb-42fb-bb7b-1b5e20448554
diff --git a/lisp/gnus/spam.el b/lisp/gnus/spam.el
index 85534f3828c..1dc9058dd1f 100644
--- a/lisp/gnus/spam.el
+++ b/lisp/gnus/spam.el
@@ -78,7 +78,7 @@
78(defgroup spam nil 78(defgroup spam nil
79 "Spam configuration.") 79 "Spam configuration.")
80 80
81(defcustom spam-directory "~/News/spam/" 81(defcustom spam-directory (nnheader-concat gnus-directory "spam/")
82 "Directory for spam whitelists and blacklists." 82 "Directory for spam whitelists and blacklists."
83 :type 'directory 83 :type 'directory
84 :group 'spam) 84 :group 'spam)
@@ -1814,14 +1814,12 @@ REMOVE not nil, remove the ADDRESSES."
1814 (remove-hook 'gnus-get-new-news-hook 'spam-setup-widening) 1814 (remove-hook 'gnus-get-new-news-hook 'spam-setup-widening)
1815 (remove-hook 'gnus-summary-prepare-hook 'spam-find-spam)) 1815 (remove-hook 'gnus-summary-prepare-hook 'spam-find-spam))
1816 1816
1817(add-hook 'spam-unload-hook 'spam-unload-hook)
1818
1817(when spam-install-hooks 1819(when spam-install-hooks
1818 (spam-initialize)) 1820 (spam-initialize))
1819 1821
1820(provide 'spam) 1822(provide 'spam)
1821 1823
1822;;; spam.el ends here.
1823
1824(provide 'spam)
1825
1826;;; arch-tag: 07e6e0ca-ab0a-4412-b445-1f6c72a4f27f 1824;;; arch-tag: 07e6e0ca-ab0a-4412-b445-1f6c72a4f27f
1827;;; spam.el ends here 1825;;; spam.el ends here