pop3.el (pop3-open-server, pop3-read-response, pop3-list, pop3-retr, pop3-quit):...
[gnus] / lisp / nnimap.el
index bdceb0d..e7bf0f3 100644 (file)
@@ -32,6 +32,8 @@
 (eval-when-compile
   (require 'cl))
 
+(require 'netrc)
+
 (nnoo-declare nnimap)
 
 (defvoo nnimap-address nil
@@ -89,10 +91,6 @@ not done by default on servers that doesn't support that command.")
 (defun nnimap-buffer ()
   (nnimap-find-process-buffer nntp-server-buffer))
 
-(defmacro nnimap-with-process-buffer (&rest body)
-  `(with-current-buffer (nnimap-find-process-buffer (current-buffer))
-     ,@body))
-
 (defun nnimap-retrieve-headers (articles &optional group server fetch-old)
   (with-current-buffer nntp-server-buffer
     (erase-buffer)
@@ -209,41 +207,52 @@ not done by default on servers that doesn't support that command.")
            (cond
             ((eq nnimap-stream 'network)
              (open-network-stream "*nnimap*" (current-buffer) nnimap-address
-                                  (or nnimap-server-port "imap"))
-             (netrc-credentials nnimap-address "imap"))
+                                  (or nnimap-server-port
+                                      (if (netrc-find-service-number "imap")
+                                          "imap"
+                                        "143")))
+             (auth-source-user-or-password
+              '("login" "password") nnimap-address "imap" nil t))
             ((eq nnimap-stream 'stream)
              (nnimap-open-shell-stream
               "*nnimap*" (current-buffer) nnimap-address
               (or nnimap-server-port "imap"))
-             (netrc-credentials nnimap-address "imap"))
+             (auth-source-user-or-password
+              '("login" "password") nnimap-address "imap" nil t))
             ((eq nnimap-stream 'ssl)
              (open-tls-stream "*nnimap*" (current-buffer) nnimap-address
-                              (or nnimap-server-port "imaps"))
-             (netrc-credentials nnimap-address "imaps" "imap")))))
+                              (or nnimap-server-port
+                                  (if (netrc-find-service-number "imaps")
+                                      "imaps"
+                                    "993")))
+             (or
+              (auth-source-user-or-password
+               '("login" "password") nnimap-address "imap")
+              (auth-source-user-or-password
+               '("login" "password") nnimap-address "imaps" nil t))))))
       (setf (nnimap-process nnimap-object)
            (get-buffer-process (current-buffer)))
       (unless credentials
-       (delete-process (nnimap-process nnimap-object))
-       (error "Can't find user name/password for %s" nnimap-address))
+       (delete-process (nnimap-process nnimap-object)))
       (when (and (nnimap-process nnimap-object)
                 (memq (process-status (nnimap-process nnimap-object))
                       '(open run)))
        (gnus-set-process-query-on-exit-flag (nnimap-process nnimap-object) nil)
        (let ((result (nnimap-command "LOGIN %S %S"
                                      (car credentials) (cadr credentials))))
-         (unless (car result)
-           (delete-process (nnimap-process nnimap-object))
-           (error "Unable to login to the server: %s"
-                  (mapconcat #'identity (cadr result) " ")))
-         (setf (nnimap-capabilities nnimap-object)
-               (mapcar
-                #'upcase
-                (or (nnimap-find-parameter "CAPABILITY" (cdr result))
-                    (nnimap-find-parameter
-                     "CAPABILITY" (cdr (nnimap-command "CAPABILITY"))))))
-         (when (member "QRESYNC" (nnimap-capabilities nnimap-object))
-           (nnimap-command "ENABLE QRESYNC"))
-         t)))))
+         (if (not (car result))
+             (progn
+               (delete-process (nnimap-process nnimap-object))
+               nil)
+           (setf (nnimap-capabilities nnimap-object)
+                 (mapcar
+                  #'upcase
+                  (or (nnimap-find-parameter "CAPABILITY" (cdr result))
+                      (nnimap-find-parameter
+                       "CAPABILITY" (cdr (nnimap-command "CAPABILITY"))))))
+           (when (member "QRESYNC" (nnimap-capabilities nnimap-object))
+             (nnimap-command "ENABLE QRESYNC"))
+           t))))))
 
 (defun nnimap-find-parameter (parameter elems)
   (let (result)
@@ -280,14 +289,14 @@ not done by default on servers that doesn't support that command.")
       (when (and result
                 article)
        (erase-buffer)
-       (nnimap-with-process-buffer
-        (erase-buffer)
-        (setq result
-              (nnimap-command
-               (if (member "IMAP4REV1" (nnimap-capabilities nnimap-object))
-                   "UID FETCH %d BODY.PEEK[]"
-                 "UID FETCH %d RFC822.PEEK")
-               article)))
+       (with-current-buffer (nnimap-buffer)
+         (erase-buffer)
+         (setq result
+               (nnimap-command
+                (if (member "IMAP4REV1" (nnimap-capabilities nnimap-object))
+                    "UID FETCH %d BODY.PEEK[]"
+                  "UID FETCH %d RFC822.PEEK")
+                article)))
        (let ((buffer (nnimap-find-process-buffer (current-buffer))))
          (when (car result)
            (with-current-buffer to-buffer
@@ -407,7 +416,7 @@ not done by default on servers that doesn't support that command.")
 (defun nnimap-request-set-mark (group actions &optional server)
   (when (nnimap-possibly-change-group group server)
     (let (sequence)
-      (with-current-buffer (nnimap-find-process-buffer nntp-server-buffer)
+      (with-current-buffer (nnimap-buffer)
        ;; Just send all the STORE commands without waiting for
        ;; response.  If they're successful, they're successful.
        (dolist (action actions)
@@ -431,17 +440,16 @@ not done by default on servers that doesn't support that command.")
     (let ((message (buffer-string))
          (message-id (message-field-value "message-id"))
          sequence)
-      (with-current-buffer nntp-server-buffer
-       (nnimap-with-process-buffer
-        (setq sequence (nnimap-send-command
-                        "APPEND %S {%d}" (utf7-encode group t)
-                        (length message)))
-        (process-send-string (get-buffer-process (current-buffer)) message)
-        (process-send-string (get-buffer-process (current-buffer)) "\r\n")
-        (let ((result (nnimap-get-response sequence)))
-          (when result
-            (cons group
-                  (nnimap-find-article-by-message-id group message-id)))))))))
+      (with-current-buffer (nnimap-buffer)
+       (setq sequence (nnimap-send-command
+                       "APPEND %S {%d}" (utf7-encode group t)
+                       (length message)))
+       (process-send-string (get-buffer-process (current-buffer)) message)
+       (process-send-string (get-buffer-process (current-buffer)) "\r\n")
+       (let ((result (nnimap-get-response sequence)))
+         (when result
+           (cons group
+                 (nnimap-find-article-by-message-id group message-id))))))))
 
 (defun nnimap-add-cr ()
   (goto-char (point-min))
@@ -454,7 +462,8 @@ not done by default on servers that doesn't support that command.")
     (when (car result)
       (dolist (line (cdr result))
        (when (and (equal (car line) "LIST")
-                  (not (string-match "noselect" (caadr line))))
+                  (not (and (caadr line)
+                            (string-match "noselect" (caadr line)))))
          (push (car (last line)) groups)))
       (nreverse groups))))
 
@@ -463,18 +472,18 @@ not done by default on servers that doesn't support that command.")
   (with-current-buffer nntp-server-buffer
     (erase-buffer)
     (let ((groups
-          (nnimap-with-process-buffer
-           (nnimap-get-groups)))
+          (with-current-buffer (nnimap-buffer)
+            (nnimap-get-groups)))
          sequences responses)
       (when groups
-       (nnimap-with-process-buffer
-        (dolist (group groups)
-          (push (list (nnimap-send-command "EXAMINE %S" (utf7-encode group t))
-                      group)
-                sequences))
-        (nnimap-wait-for-response (caar sequences))
-        (setq responses
-              (nnimap-get-responses (mapcar #'car sequences))))
+       (with-current-buffer (nnimap-buffer)
+         (dolist (group groups)
+           (push (list (nnimap-send-command "EXAMINE %S" (utf7-encode group t))
+                       group)
+                 sequences))
+         (nnimap-wait-for-response (caar sequences))
+         (setq responses
+               (nnimap-get-responses (mapcar #'car sequences))))
        (dolist (response responses)
          (let* ((sequence (car response))
                 (response (cadr response))
@@ -542,7 +551,8 @@ not done by default on servers that doesn't support that command.")
        sequences))))
 
 (defun nnimap-finish-retrieve-group-infos (server infos sequences)
-  (when (nnimap-possibly-change-group nil server)
+  (when (and sequences
+            (nnimap-possibly-change-group nil server))
     (with-current-buffer (nnimap-buffer)
       ;; Wait for the final data to trickle in.
       (nnimap-wait-for-response (cadar sequences))
@@ -566,7 +576,8 @@ not done by default on servers that doesn't support that command.")
            (completep (and start-article
                            (= start-article 1))))
        ;; First set the active ranges based on high/low.
-       (if completep
+       (if (or completep
+               (not (gnus-active group)))
            (gnus-set-active group
                             (if high
                                 (cons low high)
@@ -671,18 +682,23 @@ not done by default on servers that doesn't support that command.")
   nil)
 
 (defun nnimap-possibly-change-group (group server)
-  (when (and server
-            (not (nnimap-server-opened server)))
-    (nnimap-open-server server))
-  (if (not group)
-      t
-    (with-current-buffer (nnimap-buffer)
-      (if (equal group (nnimap-group nnimap-object))
-         t
-       (let ((result (nnimap-command "SELECT %S" (utf7-encode group t))))
-         (when (car result)
-           (setf (nnimap-group nnimap-object) group)
-           result))))))
+  (let ((open-result t))
+    (when (and server
+              (not (nnimap-server-opened server)))
+      (setq open-result (nnimap-open-server server)))
+    (cond
+     ((not open-result)
+      nil)
+     ((not group)
+      t)
+     (t
+      (with-current-buffer (nnimap-buffer)
+       (if (equal group (nnimap-group nnimap-object))
+           t
+         (let ((result (nnimap-command "SELECT %S" (utf7-encode group t))))
+           (when (car result)
+             (setf (nnimap-group nnimap-object) group)
+             result))))))))
 
 (defun nnimap-find-connection (buffer)
   "Find the connection delivering to BUFFER."