comparison lisp/gnus/nnimap.el @ 110422:93e093c035a0

Merge changes made in Gnus trunk. nnimap.el (nnimap-request-group): Use the stored info for the dont-check case. nnimap.el: Use deffoo instead of defun for interface functions. gnus-int.el (gnus-request-group): Take an optional `info' parameter. nnimap.el: Allow nnimap-request-group to do a complete marks sync on `M-g'. nnimap.el: Get credentials for numerical equivalents of the port numbers. gnus-html.el (gnus-html-wash-tags): Add support for i, b and u HTML tags. nnimap.el (nnimap-update-info): Extend the info so that we can set the marks. nnimap.el (nnimap-open-connection): Fix typo -- should be 'shell, not 'stream. nnimap.el: Allow PREAUTH nnimap connections to log in without credentials. nnimap.el (nnimap-update-info): Fix off-by-one error when concatenating ranges when doing a partial update. gnus-html.el (gnus-html-schedule-image-fetching): Use `url' rather than curl to retrieve images. nnimap.el (nnimap-update-info): When doing partial marks update, get the range update right. nnimap.el (nnimap-wait-for-response): Be a bit more lax in finding the end of the command we're looking for. nnimap.el: Allow sending \n instead of \r\n on 'shell streams. gnus-html.el (gnus-html-schedule-image-fetching): Fetch all images in parallel.
author Katsumi Yamaoka <yamaoka@jpl.org>
date Sat, 18 Sep 2010 23:36:29 +0000
parents bde55f3d7125
children 6060b86fc551
comparison
equal deleted inserted replaced
110421:fac7cd0d50e0 110422:93e093c035a0
65 "If non-nil, expunge the inbox after fetching mail. 65 "If non-nil, expunge the inbox after fetching mail.
66 This is always done if the server supports UID EXPUNGE, but it's 66 This is always done if the server supports UID EXPUNGE, but it's
67 not done by default on servers that doesn't support that command.") 67 not done by default on servers that doesn't support that command.")
68 68
69 (defvoo nnimap-connection-alist nil) 69 (defvoo nnimap-connection-alist nil)
70
71 (defvoo nnimap-current-infos nil)
72
70 (defvar nnimap-process nil) 73 (defvar nnimap-process nil)
71 74
72 (defvar nnimap-status-string "") 75 (defvar nnimap-status-string "")
73 76
74 (defvar nnimap-split-download-body-default nil 77 (defvar nnimap-split-download-body-default nil
75 "Internal variable with default value for `nnimap-split-download-body'.") 78 "Internal variable with default value for `nnimap-split-download-body'.")
76 79
77 (defstruct nnimap 80 (defstruct nnimap
78 group process commands capabilities) 81 group process commands capabilities select-result newlinep)
79 82
80 (defvar nnimap-object nil) 83 (defvar nnimap-object nil)
81 84
82 (defvar nnimap-mark-alist 85 (defvar nnimap-mark-alist
83 '((read "\\Seen") 86 '((read "\\Seen")
93 (defvar nnimap-split-methods nil) 96 (defvar nnimap-split-methods nil)
94 97
95 (defun nnimap-buffer () 98 (defun nnimap-buffer ()
96 (nnimap-find-process-buffer nntp-server-buffer)) 99 (nnimap-find-process-buffer nntp-server-buffer))
97 100
98 (defun nnimap-retrieve-headers (articles &optional group server fetch-old) 101 (deffoo nnimap-retrieve-headers (articles &optional group server fetch-old)
99 (with-current-buffer nntp-server-buffer 102 (with-current-buffer nntp-server-buffer
100 (erase-buffer) 103 (erase-buffer)
101 (when (nnimap-possibly-change-group group server) 104 (when (nnimap-possibly-change-group group server)
102 (with-current-buffer (nnimap-buffer) 105 (with-current-buffer (nnimap-buffer)
103 (nnimap-send-command "SELECT %S" (utf7-encode group t)) 106 (nnimap-send-command "SELECT %S" (utf7-encode group t))
169 (format "%d:%d" (car elem) (cdr elem)) 172 (format "%d:%d" (car elem) (cdr elem))
170 (number-to-string elem)) 173 (number-to-string elem))
171 result)) 174 result))
172 (mapconcat #'identity (nreverse result) ","))))) 175 (mapconcat #'identity (nreverse result) ",")))))
173 176
174 (defun nnimap-open-server (server &optional defs) 177 (deffoo nnimap-open-server (server &optional defs)
175 (if (nnimap-server-opened server) 178 (if (nnimap-server-opened server)
176 t 179 t
177 (unless (assq 'nnimap-address defs) 180 (unless (assq 'nnimap-address defs)
178 (setq defs (append defs (list (list 'nnimap-address server))))) 181 (setq defs (append defs (list (list 'nnimap-address server)))))
179 (nnoo-change-server 'nnimap server defs) 182 (nnoo-change-server 'nnimap server defs)
201 (format-spec-make 204 (format-spec-make
202 ?s host 205 ?s host
203 ?p port))))) 206 ?p port)))))
204 process)) 207 process))
205 208
209 (defun nnimap-credentials (address ports)
210 (let (port credentials)
211 ;; Request the credentials from all ports, but only query on the
212 ;; last port if all the previous ones have failed.
213 (while (and (null credentials)
214 (setq port (pop ports)))
215 (setq credentials
216 (auth-source-user-or-password
217 '("login" "password") address port nil (null ports))))
218 credentials))
219
206 (defun nnimap-open-connection (buffer) 220 (defun nnimap-open-connection (buffer)
207 (with-current-buffer (nnimap-make-process-buffer buffer) 221 (with-current-buffer (nnimap-make-process-buffer buffer)
208 (let* ((coding-system-for-read 'binary) 222 (let* ((coding-system-for-read 'binary)
209 (coding-system-for-write 'binary) 223 (coding-system-for-write 'binary)
210 (credentials 224 (ports
211 (cond 225 (cond
212 ((eq nnimap-stream 'network) 226 ((eq nnimap-stream 'network)
213 (open-network-stream "*nnimap*" (current-buffer) nnimap-address 227 (open-network-stream
214 (or nnimap-server-port 228 "*nnimap*" (current-buffer) nnimap-address
215 (if (netrc-find-service-number "imap") 229 (or nnimap-server-port
216 "imap" 230 (if (netrc-find-service-number "imap")
217 "143"))) 231 "imap"
218 (auth-source-user-or-password 232 "143")))
219 '("login" "password") nnimap-address "imap" nil t)) 233 '("143" "imap"))
220 ((eq nnimap-stream 'stream) 234 ((eq nnimap-stream 'shell)
221 (nnimap-open-shell-stream 235 (nnimap-open-shell-stream
222 "*nnimap*" (current-buffer) nnimap-address 236 "*nnimap*" (current-buffer) nnimap-address
223 (or nnimap-server-port "imap")) 237 (or nnimap-server-port "imap"))
224 (auth-source-user-or-password 238 '("imap"))
225 '("login" "password") nnimap-address "imap" nil t))
226 ((eq nnimap-stream 'ssl) 239 ((eq nnimap-stream 'ssl)
227 (open-tls-stream "*nnimap*" (current-buffer) nnimap-address 240 (open-tls-stream
228 (or nnimap-server-port 241 "*nnimap*" (current-buffer) nnimap-address
229 (if (netrc-find-service-number "imaps") 242 (or nnimap-server-port
230 "imaps" 243 (if (netrc-find-service-number "imaps")
231 "993"))) 244 "imaps"
232 (or 245 "993")))
233 (auth-source-user-or-password 246 '("143" "993" "imap" "imaps"))))
234 '("login" "password") nnimap-address "imap") 247 connection-result login-result credentials)
235 (auth-source-user-or-password
236 '("login" "password") nnimap-address "imaps" nil t))))))
237 (setf (nnimap-process nnimap-object) 248 (setf (nnimap-process nnimap-object)
238 (get-buffer-process (current-buffer))) 249 (get-buffer-process (current-buffer)))
239 (unless credentials
240 (delete-process (nnimap-process nnimap-object)))
241 (when (and (nnimap-process nnimap-object) 250 (when (and (nnimap-process nnimap-object)
242 (memq (process-status (nnimap-process nnimap-object)) 251 (memq (process-status (nnimap-process nnimap-object))
243 '(open run))) 252 '(open run)))
244 (gnus-set-process-query-on-exit-flag (nnimap-process nnimap-object) nil) 253 (gnus-set-process-query-on-exit-flag (nnimap-process nnimap-object) nil)
245 (let ((result (nnimap-command "LOGIN %S %S" 254 (when (setq connection-result (nnimap-wait-for-connection))
246 (car credentials) (cadr credentials)))) 255 (unless (equal connection-result "PREAUTH")
247 (if (not (car result)) 256 (if (not (setq credentials
248 (progn 257 (nnimap-credentials nnimap-address ports)))
258 (setq nnimap-object nil)
259 (setq login-result (nnimap-command "LOGIN %S %S"
260 (car credentials)
261 (cadr credentials)))
262 (unless (car login-result)
249 (delete-process (nnimap-process nnimap-object)) 263 (delete-process (nnimap-process nnimap-object))
250 nil) 264 (setq nnimap-object nil))))
265 (when nnimap-object
266 (when (eq nnimap-stream 'shell)
267 (setf (nnimap-newlinep nnimap-object) t))
251 (setf (nnimap-capabilities nnimap-object) 268 (setf (nnimap-capabilities nnimap-object)
252 (mapcar 269 (mapcar
253 #'upcase 270 #'upcase
254 (or (nnimap-find-parameter "CAPABILITY" (cdr result)) 271 (or (nnimap-find-parameter "CAPABILITY" (cdr login-result))
255 (nnimap-find-parameter 272 (nnimap-find-parameter
256 "CAPABILITY" (cdr (nnimap-command "CAPABILITY")))))) 273 "CAPABILITY" (cdr (nnimap-command "CAPABILITY"))))))
257 (when (member "QRESYNC" (nnimap-capabilities nnimap-object)) 274 (when (member "QRESYNC" (nnimap-capabilities nnimap-object))
258 (nnimap-command "ENABLE QRESYNC")) 275 (nnimap-command "ENABLE QRESYNC"))
259 t)))))) 276 t))))))
268 (consp (cadr elem)) 285 (consp (cadr elem))
269 (equal (caadr elem) parameter)) 286 (equal (caadr elem) parameter))
270 (setq result (cdr (cadr elem)))))) 287 (setq result (cdr (cadr elem))))))
271 result)) 288 result))
272 289
273 (defun nnimap-close-server (&optional server) 290 (deffoo nnimap-close-server (&optional server)
274 t) 291 t)
275 292
276 (defun nnimap-request-close () 293 (deffoo nnimap-request-close ()
277 t) 294 t)
278 295
279 (defun nnimap-server-opened (&optional server) 296 (deffoo nnimap-server-opened (&optional server)
280 (and (nnoo-current-server-p 'nnimap server) 297 (and (nnoo-current-server-p 'nnimap server)
281 nntp-server-buffer 298 nntp-server-buffer
282 (gnus-buffer-live-p nntp-server-buffer) 299 (gnus-buffer-live-p nntp-server-buffer)
283 (nnimap-find-connection nntp-server-buffer))) 300 (nnimap-find-connection nntp-server-buffer)))
284 301
285 (defun nnimap-status-message (&optional server) 302 (deffoo nnimap-status-message (&optional server)
286 nnimap-status-string) 303 nnimap-status-string)
287 304
288 (defun nnimap-request-article (article &optional group server to-buffer) 305 (deffoo nnimap-request-article (article &optional group server to-buffer)
289 (with-current-buffer nntp-server-buffer 306 (with-current-buffer nntp-server-buffer
290 (let ((result (nnimap-possibly-change-group group server))) 307 (let ((result (nnimap-possibly-change-group group server)))
291 (when (stringp article) 308 (when (stringp article)
292 (setq article (nnimap-find-article-by-message-id group article))) 309 (setq article (nnimap-find-article-by-message-id group article)))
293 (when (and result 310 (when (and result
312 (goto-char (+ (point) bytes)) 329 (goto-char (+ (point) bytes))
313 (delete-region (point) (point-max)) 330 (delete-region (point) (point-max))
314 (nnheader-ms-strip-cr)) 331 (nnheader-ms-strip-cr))
315 t))))))) 332 t)))))))
316 333
317 (defun nnimap-request-group (group &optional server dont-check) 334 (deffoo nnimap-request-group (group &optional server dont-check info)
318 (with-current-buffer nntp-server-buffer 335 (with-current-buffer nntp-server-buffer
319 (let ((result (nnimap-possibly-change-group group server)) 336 (let ((result (nnimap-possibly-change-group group server))
320 articles) 337 articles active marks high low)
321 (when result 338 (when result
322 (setq articles (nnimap-get-flags "1:*")) 339 (if (and dont-check
323 (erase-buffer) 340 (setq active (nth 2 (assoc group nnimap-current-infos))))
324 (insert 341 (insert (format "211 %d %d %d %S\n"
325 (format 342 (- (cdr active) (car active))
326 "211 %d %d %d %S\n" 343 (car active)
327 (length articles) 344 (cdr active)
328 (or (caar articles) 0) 345 group))
329 (or (caar (last articles)) 0) 346 (with-current-buffer (nnimap-buffer)
330 group)) 347 (erase-buffer)
331 t)))) 348 (let ((group-sequence
349 (nnimap-send-command "SELECT %S" (utf7-encode group)))
350 (flag-sequence
351 (nnimap-send-command "UID FETCH 1:* FLAGS")))
352 (nnimap-wait-for-response flag-sequence)
353 (setq marks
354 (nnimap-flags-to-marks
355 (nnimap-parse-flags
356 (list (list group-sequence flag-sequence 1 group)))))
357 (when info
358 (nnimap-update-infos marks (list info)))
359 (goto-char (point-max))
360 (cond
361 (marks
362 (setq high (nth 3 (car marks))
363 low (nth 4 (car marks))))
364 ((re-search-backward "UIDNEXT \\([0-9]+\\)" nil t)
365 (setq high (string-to-number (match-string 1))
366 low 1)))))
367 (erase-buffer)
368 (insert
369 (format
370 "211 %d %d %d %S\n"
371 (1+ (- high low))
372 low high group))))
373 t)))
332 374
333 (defun nnimap-get-flags (spec) 375 (defun nnimap-get-flags (spec)
334 (let ((articles nil) 376 (let ((articles nil)
335 elems) 377 elems)
336 (with-current-buffer (nnimap-buffer) 378 (with-current-buffer (nnimap-buffer)
343 (push (cons (string-to-number (cadr (member "UID" elems))) 385 (push (cons (string-to-number (cadr (member "UID" elems)))
344 (cadr (member "FLAGS" elems))) 386 (cadr (member "FLAGS" elems)))
345 articles))) 387 articles)))
346 (nreverse articles))) 388 (nreverse articles)))
347 389
348 (defun nnimap-close-group (group &optional server) 390 (deffoo nnimap-close-group (group &optional server)
349 t) 391 t)
350 392
351 (deffoo nnimap-request-move-article (article group server accept-form 393 (deffoo nnimap-request-move-article (article group server accept-form
352 &optional last internal-move-group) 394 &optional last internal-move-group)
353 (when (nnimap-possibly-change-group group server) 395 (when (nnimap-possibly-change-group group server)
415 (dolist (mark marks) 457 (dolist (mark marks)
416 (when (setq flag (cadr (assq mark nnimap-mark-alist))) 458 (when (setq flag (cadr (assq mark nnimap-mark-alist)))
417 (push flag flags))) 459 (push flag flags)))
418 flags)) 460 flags))
419 461
420 (defun nnimap-request-set-mark (group actions &optional server) 462 (deffoo nnimap-request-set-mark (group actions &optional server)
421 (when (nnimap-possibly-change-group group server) 463 (when (nnimap-possibly-change-group group server)
422 (let (sequence) 464 (let (sequence)
423 (with-current-buffer (nnimap-buffer) 465 (with-current-buffer (nnimap-buffer)
424 ;; Just send all the STORE commands without waiting for 466 ;; Just send all the STORE commands without waiting for
425 ;; response. If they're successful, they're successful. 467 ;; response. If they're successful, they're successful.
447 (with-current-buffer (nnimap-buffer) 489 (with-current-buffer (nnimap-buffer)
448 (setq sequence (nnimap-send-command 490 (setq sequence (nnimap-send-command
449 "APPEND %S {%d}" (utf7-encode group t) 491 "APPEND %S {%d}" (utf7-encode group t)
450 (length message))) 492 (length message)))
451 (process-send-string (get-buffer-process (current-buffer)) message) 493 (process-send-string (get-buffer-process (current-buffer)) message)
452 (process-send-string (get-buffer-process (current-buffer)) "\r\n") 494 (process-send-string (get-buffer-process (current-buffer))
495 (if (nnimap-newlinep nnimap-object)
496 "\n"
497 "\r\n"))
453 (let ((result (nnimap-get-response sequence))) 498 (let ((result (nnimap-get-response sequence)))
454 (when result 499 (when result
455 (cons group 500 (cons group
456 (nnimap-find-article-by-message-id group message-id)))))))) 501 (nnimap-find-article-by-message-id group message-id))))))))
457 502
469 (not (and (caadr line) 514 (not (and (caadr line)
470 (string-match "noselect" (caadr line))))) 515 (string-match "noselect" (caadr line)))))
471 (push (car (last line)) groups))) 516 (push (car (last line)) groups)))
472 (nreverse groups)))) 517 (nreverse groups))))
473 518
474 (defun nnimap-request-list (&optional server) 519 (deffoo nnimap-request-list (&optional server)
475 (nnimap-possibly-change-group nil server) 520 (nnimap-possibly-change-group nil server)
476 (with-current-buffer nntp-server-buffer 521 (with-current-buffer nntp-server-buffer
477 (erase-buffer) 522 (erase-buffer)
478 (let ((groups 523 (let ((groups
479 (with-current-buffer (nnimap-buffer) 524 (with-current-buffer (nnimap-buffer)
512 ;; Return the widest possible range. 557 ;; Return the widest possible range.
513 (insert (format "%S %d 1 y\n" (utf7-decode group t) 558 (insert (format "%S %d 1 y\n" (utf7-decode group t)
514 (or highest exists))))))))) 559 (or highest exists)))))))))
515 t)))) 560 t))))
516 561
517 (defun nnimap-retrieve-group-data-early (server infos) 562 (deffoo nnimap-retrieve-group-data-early (server infos)
518 (when (nnimap-possibly-change-group nil server) 563 (when (nnimap-possibly-change-group nil server)
519 (with-current-buffer (nnimap-buffer) 564 (with-current-buffer (nnimap-buffer)
520 ;; QRESYNC handling isn't implemented. 565 ;; QRESYNC handling isn't implemented.
521 (let ((qresyncp (member "notQRESYNC" (nnimap-capabilities nnimap-object))) 566 (let ((qresyncp (member "notQRESYNC" (nnimap-capabilities nnimap-object)))
522 marks groups sequences) 567 marks groups sequences)
552 start 597 start
553 (car elem)) 598 (car elem))
554 sequences)))) 599 sequences))))
555 sequences)))) 600 sequences))))
556 601
557 (defun nnimap-finish-retrieve-group-infos (server infos sequences) 602 (deffoo nnimap-finish-retrieve-group-infos (server infos sequences)
558 (when (and sequences 603 (when (and sequences
559 (nnimap-possibly-change-group nil server)) 604 (nnimap-possibly-change-group nil server))
560 (with-current-buffer (nnimap-buffer) 605 (with-current-buffer (nnimap-buffer)
561 ;; Wait for the final data to trickle in. 606 ;; Wait for the final data to trickle in.
562 (nnimap-wait-for-response (cadar sequences)) 607 (nnimap-wait-for-response (cadar sequences))
599 (read (gnus-range-difference 644 (read (gnus-range-difference
600 (cons start-article high) unread))) 645 (cons start-article high) unread)))
601 (when (> start-article 1) 646 (when (> start-article 1)
602 (setq read 647 (setq read
603 (gnus-range-nconcat 648 (gnus-range-nconcat
604 (gnus-sorted-range-intersection 649 (if (> start-article 1)
605 (cons 1 start-article) 650 (gnus-sorted-range-intersection
606 (gnus-info-read info)) 651 (cons 1 (1- start-article))
652 (gnus-info-read info))
653 (gnus-info-read info))
607 read))) 654 read)))
608 (gnus-info-set-read info read) 655 (gnus-info-set-read info read)
609 ;; Update the marks. 656 ;; Update the marks.
610 (setq marks (gnus-info-marks info)) 657 (setq marks (gnus-info-marks info))
611 ;; Note the active level for the next run-through. 658 ;; Note the active level for the next run-through.
620 (setq marks (delq old-marks marks)) 667 (setq marks (delq old-marks marks))
621 (pop old-marks) 668 (pop old-marks)
622 (when (and old-marks 669 (when (and old-marks
623 (> start-article 1)) 670 (> start-article 1))
624 (setq old-marks (gnus-range-difference 671 (setq old-marks (gnus-range-difference
625 (cons start-article high) 672 old-marks
626 old-marks)) 673 (cons start-article high)))
627 (setq new-marks (gnus-range-nconcat old-marks new-marks))) 674 (setq new-marks (gnus-range-nconcat old-marks new-marks)))
628 (when new-marks 675 (when new-marks
629 (push (cons (car type) new-marks) marks))) 676 (push (cons (car type) new-marks) marks)))
630 (gnus-info-set-marks info marks))))))) 677 (gnus-info-set-marks info marks t)
678 (nnimap-store-info info (gnus-active group))))))))
679
680 (defun nnimap-store-info (info active)
681 (let* ((group (gnus-group-real-name (gnus-info-group info)))
682 (entry (assoc group nnimap-current-infos)))
683 (if entry
684 (setcdr entry (list info active))
685 (push (list group info active) nnimap-current-infos))))
631 686
632 (defun nnimap-flags-to-marks (groups) 687 (defun nnimap-flags-to-marks (groups)
633 (let (data group totalp uidnext articles start-article mark) 688 (let (data group totalp uidnext articles start-article mark)
634 (dolist (elem groups) 689 (dolist (elem groups)
635 (setq group (car elem) 690 (setq group (car elem)
679 groups)) 734 groups))
680 735
681 (defun nnimap-find-process-buffer (buffer) 736 (defun nnimap-find-process-buffer (buffer)
682 (cadr (assoc buffer nnimap-connection-alist))) 737 (cadr (assoc buffer nnimap-connection-alist)))
683 738
684 (defun nnimap-request-post (&optional server) 739 (deffoo nnimap-request-post (&optional server)
685 (setq nnimap-status-string "Read-only server") 740 (setq nnimap-status-string "Read-only server")
686 nil) 741 nil)
687 742
688 (defun nnimap-possibly-change-group (group server) 743 (defun nnimap-possibly-change-group (group server)
689 (let ((open-result t)) 744 (let ((open-result t))
699 (with-current-buffer (nnimap-buffer) 754 (with-current-buffer (nnimap-buffer)
700 (if (equal group (nnimap-group nnimap-object)) 755 (if (equal group (nnimap-group nnimap-object))
701 t 756 t
702 (let ((result (nnimap-command "SELECT %S" (utf7-encode group t)))) 757 (let ((result (nnimap-command "SELECT %S" (utf7-encode group t))))
703 (when (car result) 758 (when (car result)
704 (setf (nnimap-group nnimap-object) group) 759 (setf (nnimap-group nnimap-object) group
760 (nnimap-select-result nnimap-object) result)
705 result)))))))) 761 result))))))))
706 762
707 (defun nnimap-find-connection (buffer) 763 (defun nnimap-find-connection (buffer)
708 "Find the connection delivering to BUFFER." 764 "Find the connection delivering to BUFFER."
709 (let ((entry (assoc buffer nnimap-connection-alist))) 765 (let ((entry (assoc buffer nnimap-connection-alist)))
720 776
721 (defun nnimap-send-command (&rest args) 777 (defun nnimap-send-command (&rest args)
722 (process-send-string 778 (process-send-string
723 (get-buffer-process (current-buffer)) 779 (get-buffer-process (current-buffer))
724 (nnimap-log-command 780 (nnimap-log-command
725 (format "%d %s\r\n" 781 (format "%d %s%s\n"
726 (incf nnimap-sequence) 782 (incf nnimap-sequence)
727 (apply #'format args)))) 783 (apply #'format args)
784 (if (nnimap-newlinep nnimap-object)
785 ""
786 "\r"))))
728 nnimap-sequence) 787 nnimap-sequence)
729 788
730 (defun nnimap-log-command (command) 789 (defun nnimap-log-command (command)
731 (with-current-buffer (get-buffer-create "*imap log*") 790 (with-current-buffer (get-buffer-create "*imap log*")
732 (goto-char (point-max)) 791 (goto-char (point-max))
745 804
746 (defun nnimap-get-response (sequence) 805 (defun nnimap-get-response (sequence)
747 (nnimap-wait-for-response sequence) 806 (nnimap-wait-for-response sequence)
748 (nnimap-parse-response)) 807 (nnimap-parse-response))
749 808
809 (defun nnimap-wait-for-connection ()
810 (let ((process (get-buffer-process (current-buffer))))
811 (goto-char (point-min))
812 (while (and (memq (process-status process)
813 '(open run))
814 (not (re-search-forward "^\\* " nil t)))
815 (nnheader-accept-process-output process)
816 (goto-char (point-min)))
817 (and (looking-at "[A-Z0-9]+")
818 (match-string 0))))
819
750 (defun nnimap-wait-for-response (sequence &optional messagep) 820 (defun nnimap-wait-for-response (sequence &optional messagep)
751 (goto-char (point-max)) 821 (goto-char (point-max))
752 (while (or (bobp) 822 (while (not (re-search-backward (format "^%d .*\n" sequence)
753 (progn 823 (max (point-min) (- (point) 500))
754 (forward-line -1) 824 t))
755 (not (looking-at (format "^%d .*\n" sequence)))))
756 (when messagep 825 (when messagep
757 (message "Read %dKB" (/ (buffer-size) 1000))) 826 (message "Read %dKB" (/ (buffer-size) 1000)))
758 (nnheader-accept-process-output (get-buffer-process (current-buffer))) 827 (nnheader-accept-process-output (get-buffer-process (current-buffer)))
759 (goto-char (point-max)))) 828 (goto-char (point-max))))
760 829