Mercurial > emacs
diff lisp/gnus/nnimap.el @ 110615:84a76c5e1b1c
Merge changes made in Gnus trunk.
sieve-manage.el (sieve-manage-default-stream): Make default stream customizable.
nnimap.el (nnimap-request-accept-article): Send a "." at the end, which may or may not help.
nnimap.el (nnimap-open-connection): Have the `network' nnimap connection use STARTTLS opportunistically.
gnus-sum.el (gnus-summary-insert-new-articles): Copy the old-high watermark so that nothing alters it while scanning for new messages.
nnimap.el (nnimap-request-accept-article): Remove the "." at the end, since some servers don't like it.
nnimap.el (nnimap-open-connection): Forget credentials if the server says the password was wrong.
nnimap.el (nnimap-parse-line): Protect against invalid data.
gnus-art.el, gnus-sum.el, nnimap.el: Allow setting the partial fetch per server instead of globally.
message.el (message-cite-prefix-regexp): Revert last edit.
nnmairix.el: Make it work with latest changes in nnimap.
gnus-sum.el (gnus-summary-move-article): Don't alter gnus-newsgroup-active.
gnus-sum.el (gnus-summary-exit): Kill the article buffer later, so that you don't get flashes of other buffers.
nnimap.el: Fix up partial nnimap fetching.
gnus-sum.el: Rework the `/ N' based on the new gnus-newsgroup-highest variable.
author | Katsumi Yamaoka <yamaoka@jpl.org> |
---|---|
date | Mon, 27 Sep 2010 23:07:47 +0000 |
parents | 5bd3c6bdbcb0 |
children | b1c50a3d738a |
line wrap: on
line diff
--- a/lisp/gnus/nnimap.el Mon Sep 27 22:53:35 2010 +0200 +++ b/lisp/gnus/nnimap.el Mon Sep 27 23:07:47 2010 +0000 @@ -85,6 +85,13 @@ (defvoo nnimap-current-infos nil) +(defvoo nnimap-fetch-partial-articles nil + "If non-nil, Gnus will fetch partial articles. +If t, nnimap will fetch only the first part. If a string, it +will fetch all parts that have types that match that string. A +likely value would be \"text/\" to automatically fetch all +textual parts.") + (defvar nnimap-process nil) (defvar nnimap-status-string "") @@ -271,91 +278,110 @@ (unless nnimap-keepalive-timer (setq nnimap-keepalive-timer (run-at-time (* 60 15) (* 60 15) 'nnimap-keepalive))) - (with-current-buffer (nnimap-make-process-buffer buffer) - (let* ((coding-system-for-read 'binary) - (coding-system-for-write 'binary) - (port nil) - (ports - (cond - ((eq nnimap-stream 'network) - (open-network-stream - "*nnimap*" (current-buffer) nnimap-address - (setq port - (or nnimap-server-port - (if (netrc-find-service-number "imap") - "imap" - "143")))) - '("143" "imap")) - ((eq nnimap-stream 'shell) - (nnimap-open-shell-stream - "*nnimap*" (current-buffer) nnimap-address - (setq port (or nnimap-server-port "imap"))) - '("imap")) - ((eq nnimap-stream 'starttls) - (starttls-open-stream - "*nnimap*" (current-buffer) nnimap-address - (setq port (or nnimap-server-port "imap"))) - '("imap")) - ((eq nnimap-stream 'ssl) - (open-tls-stream - "*nnimap*" (current-buffer) nnimap-address - (setq port - (or nnimap-server-port - (if (netrc-find-service-number "imaps") - "imaps" - "993")))) - '("143" "993" "imap" "imaps")))) - connection-result login-result credentials) - (setf (nnimap-process nnimap-object) - (get-buffer-process (current-buffer))) - (if (not (and (nnimap-process nnimap-object) - (memq (process-status (nnimap-process nnimap-object)) - '(open run)))) - (nnheader-report 'nnimap "Unable to contact %s:%s via %s" - nnimap-address port nnimap-stream) - (gnus-set-process-query-on-exit-flag (nnimap-process nnimap-object) nil) - (if (not (setq connection-result (nnimap-wait-for-connection))) - (nnheader-report 'nnimap - "%s" (buffer-substring - (point) (line-end-position))) - (setf (nnimap-greeting nnimap-object) - (buffer-substring (line-beginning-position) - (line-end-position))) - (when (eq nnimap-stream 'starttls) - (nnimap-command "STARTTLS") - (starttls-negotiate (nnimap-process nnimap-object))) - (when nnimap-server-port - (push (format "%s" nnimap-server-port) ports)) - (unless (equal connection-result "PREAUTH") - (if (not (setq credentials - (if (eq nnimap-authenticator 'anonymous) - (list "anonymous" - (message-make-address)) - (or - ;; First look for the credentials based - ;; on the virtual server name. - (nnimap-credentials - (nnoo-current-server 'nnimap) ports t) - ;; Then look them up based on the - ;; physical address. - (nnimap-credentials nnimap-address ports))))) - (setq nnimap-object nil) - (setq login-result (nnimap-command "LOGIN %S %S" - (car credentials) - (cadr credentials))) - (unless (car login-result) - (delete-process (nnimap-process nnimap-object)) - (setq nnimap-object nil)))) - (when nnimap-object + (block nil + (with-current-buffer (nnimap-make-process-buffer buffer) + (let* ((coding-system-for-read 'binary) + (coding-system-for-write 'binary) + (port nil) + (ports + (cond + ((eq nnimap-stream 'network) + (open-network-stream + "*nnimap*" (current-buffer) nnimap-address + (setq port + (or nnimap-server-port + (if (netrc-find-service-number "imap") + "imap" + "143")))) + '("143" "imap")) + ((eq nnimap-stream 'shell) + (nnimap-open-shell-stream + "*nnimap*" (current-buffer) nnimap-address + (setq port (or nnimap-server-port "imap"))) + '("imap")) + ((eq nnimap-stream 'starttls) + (starttls-open-stream + "*nnimap*" (current-buffer) nnimap-address + (setq port (or nnimap-server-port "imap"))) + '("imap")) + ((eq nnimap-stream 'ssl) + (open-tls-stream + "*nnimap*" (current-buffer) nnimap-address + (setq port + (or nnimap-server-port + (if (netrc-find-service-number "imaps") + "imaps" + "993")))) + '("143" "993" "imap" "imaps")))) + connection-result login-result credentials) + (setf (nnimap-process nnimap-object) + (get-buffer-process (current-buffer))) + (if (not (and (nnimap-process nnimap-object) + (memq (process-status (nnimap-process nnimap-object)) + '(open run)))) + (nnheader-report 'nnimap "Unable to contact %s:%s via %s" + nnimap-address port nnimap-stream) + (gnus-set-process-query-on-exit-flag (nnimap-process nnimap-object) nil) + (if (not (setq connection-result (nnimap-wait-for-connection))) + (nnheader-report 'nnimap + "%s" (buffer-substring + (point) (line-end-position))) + ;; Store the greeting (for debugging purposes). + (setf (nnimap-greeting nnimap-object) + (buffer-substring (line-beginning-position) + (line-end-position))) + ;; Store the capabilities. (setf (nnimap-capabilities nnimap-object) (mapcar #'upcase - (or (nnimap-find-parameter "CAPABILITY" (cdr login-result)) - (nnimap-find-parameter - "CAPABILITY" (cdr (nnimap-command "CAPABILITY")))))) - (when (member "QRESYNC" (nnimap-capabilities nnimap-object)) - (nnimap-command "ENABLE QRESYNC")) - t)))))) + (nnimap-find-parameter + "CAPABILITY" (cdr (nnimap-command "CAPABILITY"))))) + (when (eq nnimap-stream 'starttls) + (nnimap-command "STARTTLS") + (starttls-negotiate (nnimap-process nnimap-object))) + ;; If this is a STARTTLS-capable server, then sever the + ;; connection and start a STARTTLS connection instead. + (when (and (eq nnimap-stream 'network) + (member "STARTTLS" (nnimap-capabilities nnimap-object))) + (let ((nnimap-stream 'starttls)) + (delete-process (nnimap-process nnimap-object)) + (kill-buffer (current-buffer)) + (return + (nnimap-open-connection buffer)))) + (when nnimap-server-port + (push (format "%s" nnimap-server-port) ports)) + (unless (equal connection-result "PREAUTH") + (if (not (setq credentials + (if (eq nnimap-authenticator 'anonymous) + (list "anonymous" + (message-make-address)) + (or + ;; First look for the credentials based + ;; on the virtual server name. + (nnimap-credentials + (nnoo-current-server 'nnimap) ports t) + ;; Then look them up based on the + ;; physical address. + (nnimap-credentials nnimap-address ports))))) + (setq nnimap-object nil) + (setq login-result (nnimap-command "LOGIN %S %S" + (car credentials) + (cadr credentials))) + (unless (car login-result) + ;; If the login failed, then forget the credentials + ;; that are now possibly cached. + (dolist (host (list (nnoo-current-server 'nnimap) + nnimap-address)) + (dolist (port ports) + (dolist (element '("login" "password")) + (auth-source-forget-user-or-password + element host port)))) + (delete-process (nnimap-process nnimap-object)) + (setq nnimap-object nil)))) + (when nnimap-object + (when (member "QRESYNC" (nnimap-capabilities nnimap-object)) + (nnimap-command "ENABLE QRESYNC")) + t))))))) (defun nnimap-find-parameter (parameter elems) (let (result) @@ -395,14 +421,12 @@ (erase-buffer) (with-current-buffer (nnimap-buffer) (erase-buffer) - (when gnus-fetch-partial-articles - (if (eq gnus-fetch-partial-articles t) - (setq parts '(1)) - (nnimap-command "UID FETCH %d (BODYSTRUCTURE)" article) - (goto-char (point-min)) - (when (re-search-forward "FETCH.*BODYSTRUCTURE" nil t) - (setq structure (ignore-errors (read (current-buffer))) - parts (nnimap-find-wanted-parts structure))))) + (when nnimap-fetch-partial-articles + (nnimap-command "UID FETCH %d (BODYSTRUCTURE)" article) + (goto-char (point-min)) + (when (re-search-forward "FETCH.*BODYSTRUCTURE" nil t) + (setq structure (ignore-errors (read (current-buffer))) + parts (nnimap-find-wanted-parts structure)))) (when (if parts (nnimap-get-partial-article article parts structure) (nnimap-get-whole-article article)) @@ -525,7 +549,9 @@ (number-to-string num) (format "%s.%s" prefix num)))) (setcar (nthcdr 9 sub) id) - (when (string-match gnus-fetch-partial-articles type) + (when (if (eq nnimap-fetch-partial-articles t) + (equal id "1") + (string-match nnimap-fetch-partial-articles type)) (push id parts)))) (incf num))) (nreverse parts))) @@ -941,7 +967,10 @@ (t ;; No articles and no uidnext. nil))) - (setcdr (gnus-active group) (or high (1- uidnext)))) + (gnus-set-active + group + (cons (car (gnus-active group)) + (or high (1- uidnext))))) (when (and (not high) uidnext) (setq high (1- uidnext))) @@ -1193,13 +1222,18 @@ (cond ((eql char ?\[) (split-string (buffer-substring - (1+ (point)) (1- (search-forward "]"))))) + (1+ (point)) + (1- (search-forward "]" (line-end-position) 'move))))) ((eql char ?\() (split-string (buffer-substring - (1+ (point)) (1- (search-forward ")"))))) + (1+ (point)) + (1- (search-forward ")" (line-end-position) 'move))))) ((eql char ?\") (forward-char 1) - (buffer-substring (point) (1- (search-forward "\"")))) + (buffer-substring + (point) + (1- (or (search-forward "\"" (line-end-position) 'move) + (point))))) (t (buffer-substring (point) (if (search-forward " " nil t) (1- (point))