* rfc2047.el (rfc2047-qp-or-base64): New function to reduce
[gnus] / lisp / nnimap.el
index 3be9481..1e170d8 100644 (file)
@@ -1,5 +1,6 @@
 ;;; nnimap.el --- imap backend for Gnus
-;; Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
+;;        Free Software Foundation, Inc.
 
 ;; Author: Simon Josefsson <jas@pdc.kth.se>
 ;;         Jim Radford <radford@robby.caltech.edu>
@@ -69,6 +70,8 @@
 (require 'gnus-start)
 (require 'gnus-int)
 
+(eval-when-compile (require 'cl))
+
 (nnoo-declare nnimap)
 
 (defconst nnimap-version "nnimap 1.0")
@@ -82,7 +85,7 @@
 
 (defvoo nnimap-server-port nil
   "Port number on physical IMAP server.
-If nil, defaults to 993 for SSL connections and 143 otherwise.")
+If nil, defaults to 993 for TLS/SSL connections and 143 otherwise.")
 
 ;; Splitting variables
 
@@ -191,17 +194,26 @@ RFC2060 section 6.4.4."
   :type 'string)
 
 (defcustom nnimap-split-fancy nil
-  "Like the variable `nnmail-split-fancy', which see."
+  "Like the variable `nnmail-split-fancy'."
   :group 'nnimap
   :type 'sexp)
 
-(defcustom nnimap-split-download-body nil
+(defvar nnimap-split-download-body-default nil
+  "Internal variable with default value for `nnimap-split-download-body'.")
+
+(defcustom nnimap-split-download-body 'default
   "Whether to download entire articles during splitting.
 This is generally not required, and will slow things down considerably.
 You may need it if you want to use an advanced splitting function that
-analyses the body before splitting the article."
+analyses the body before splitting the article.
+If this variable is nil, bodies will not be downloaded; if this
+variable is the symbol `default' the default behaviour is
+used (which currently is nil, unless you use a statistical
+spam.el test); if this variable is another non-nil value bodies
+will be downloaded."
   :group 'nnimap
-  :type 'boolean)
+  :type '(choice (const :tag "Let system decide" deault)
+                boolean))
 
 ;; Performance / bug workaround variables
 
@@ -250,14 +262,16 @@ handle.
 
 Change this if
 
-1) you want to connect with SSL.  The SSL integration with IMAP is
-   brain-dead so you'll have to tell it specifically.
+1) you want to connect with TLS/SSL.  The TLS/SSL integration
+   with IMAP is suboptimal so you'll have to tell it
+   specifically.
 
 2) your server is more capable than your environment -- i.e. your
    server accept Kerberos login's but you haven't installed the
    `imtest' program or your machine isn't configured for Kerberos.
 
-Possible choices: kerberos4, ssl, network")
+Possible choices: gssapi, kerberos4, starttls, tls, ssl, network, shell.
+See also `imap-streams' and `imap-stream-alist'.")
 
 (defvoo nnimap-authenticator nil
   "How nnimap authenticate itself to the server.
@@ -271,7 +285,8 @@ connect to a server that accept Kerberos login's but you haven't
 installed the `imtest' program or your machine isn't configured for
 Kerberos.
 
-Possible choices: kerberos4, cram-md5, login, anonymous.")
+Possible choices: gssapi, kerberos4, digest-md5, cram-md5, login, anonymous.
+See also `imap-authenticators' and `imap-authenticator-alist'")
 
 (defvoo nnimap-directory (nnheader-concat gnus-directory "overview/")
   "Directory to keep NOV cache files for nnimap groups.
@@ -387,6 +402,43 @@ just like \"ticked\" articles, in other IMAP clients.")
 If this is 'imap-mailbox-lsub, then use a server-side subscription list to
 restrict visible folders.")
 
+(defcustom nnimap-id nil
+  "Plist with client identity to send to server upon login.
+Nil means no information is sent, symbol `no' to disable ID query
+alltogheter, or plist with identifier-value pairs to send to
+server.  RFC 2971 describes the list as follows:
+
+   Any string may be sent as a field, but the following are defined to
+   describe certain values that might be sent.  Implementations are free
+   to send none, any, or all of these.  Strings are not case-sensitive.
+   Field strings MUST NOT be longer than 30 octets.  Value strings MUST
+   NOT be longer than 1024 octets.  Implementations MUST NOT send more
+   than 30 field-value pairs.
+
+     name            Name of the program
+     version         Version number of the program
+     os              Name of the operating system
+     os-version      Version of the operating system
+     vendor          Vendor of the client/server
+     support-url     URL to contact for support
+     address         Postal address of contact/vendor
+     date            Date program was released, specified as a date-time
+                       in IMAP4rev1
+     command         Command used to start the program
+     arguments       Arguments supplied on the command line, if any
+                       if any
+     environment     Description of environment, i.e., UNIX environment
+                       variables or Windows registry settings
+
+   Implementations MUST NOT send the same field name more than once.
+
+An example plist would be '(\"name\" \"Gnus\" \"version\" gnus-version-number
+\"os\" system-configuration \"vendor\" \"GNU\")."
+  :group 'nnimap
+  :type '(choice (const :tag "No information" nil)
+                (const :tag "Disable ID query" no)
+                (plist :key-type string :value-type string)))
+
 (defcustom nnimap-debug nil
   "If non-nil, random debug spews are placed in *nnimap-debug* buffer."
   :group 'nnimap
@@ -705,15 +757,18 @@ If EXAMINE is non-nil the group is selected read-only."
           (port (if nnimap-server-port
                     (int-to-string nnimap-server-port)
                   "imap"))
-          (alist (gnus-netrc-machine list (or nnimap-server-address
-                                              nnimap-address server)
-                                     port "imap"))
+          (alist (or (gnus-netrc-machine list server port "imap")
+                     (gnus-netrc-machine list
+                                         (or nnimap-server-address
+                                             nnimap-address)
+                                         port "imap")))
           (user (gnus-netrc-get alist "login"))
           (passwd (gnus-netrc-get alist "password")))
       (if (imap-authenticate user passwd nnimap-server-buffer)
          (prog1
              (push (list server nnimap-server-buffer)
                    nnimap-server-buffer-alist)
+           (imap-id nnimap-id nnimap-server-buffer)
            (nnimap-possibly-change-server server))
        (imap-close nnimap-server-buffer)
        (kill-buffer nnimap-server-buffer)
@@ -1254,9 +1309,11 @@ function is generally only called when Gnus is shutting down."
          (when (setq rule (nnimap-split-find-rule server inbox))
            ;; iterate over articles
            (dolist (article (imap-search nnimap-split-predicate))
-             (when (if nnimap-split-download-body
+             (when (if (if (eq nnimap-split-download-body 'default)
+                           nnimap-split-download-body-default
+                         nnimap-split-download-body)
                        (and (nnimap-request-article article)
-                            (mail-narrow-to-head))
+                            (with-current-buffer nntp-server-buffer (mail-narrow-to-head)))
                      (nnimap-request-head article))
                ;; copy article to right group(s)
                (setq removeorig nil)
@@ -1272,16 +1329,20 @@ function is generally only called when Gnus is shutting down."
                         (setq removeorig t)
                         (when nnmail-cache-accepted-message-ids
                           (with-current-buffer nntp-server-buffer
-                             (let (msgid)
-                               (and (setq msgid
+                            (let (msgid)
+                              (and (setq msgid
                                          (nnmail-fetch-field "message-id"))
-                                    (nnmail-cache-insert msgid to-group)))))
+                                   (nnmail-cache-insert msgid 
+                                                        to-group
+                                                        (nnmail-fetch-field "subject"))))))
                         ;; Add the group-art list to the history list.
                         (push (list (cons to-group 0)) nnmail-split-history))
                        (t
                         (message "IMAP split failed to move %s:%s:%d to %s"
                                  server inbox article to-group))))
-               (if nnimap-split-download-body
+               (if (if (eq nnimap-split-download-body 'default)
+                       nnimap-split-download-body-default
+                     nnimap-split-download-body)
                    (widen))
                ;; remove article if it was successfully copied somewhere
                (and removeorig
@@ -1307,7 +1368,7 @@ function is generally only called when Gnus is shutting down."
       (nnimap-before-find-minmax-bugworkaround)
       (dolist (pattern (nnimap-pattern-to-list-arguments
                        nnimap-list-pattern))
-       (dolist (mbx (imap-mailbox-lsub "*" (car pattern) nil
+       (dolist (mbx (imap-mailbox-lsub (cdr pattern) (car pattern) nil
                                        nnimap-server-buffer))
          (or (catch 'found
                (dolist (mailbox (imap-mailbox-get 'list-flags mbx
@@ -1444,13 +1505,14 @@ function is generally only called when Gnus is shutting down."
                    ;; remove any 'From blabla' lines, some IMAP servers
                    ;; reject the entire message otherwise.
                    (when (looking-at "^From[^:]")
-                     (kill-region (point) (progn (forward-line) (point))))
+                     (delete-region (point) (progn (forward-line) (point))))
                    ;; turn into rfc822 format (\r\n eol's)
                    (while (search-forward "\n" nil t)
                      (replace-match "\r\n"))
                    (when nnmail-cache-accepted-message-ids
                      (nnmail-cache-insert (nnmail-fetch-field "message-id")
-                                          group)))
+                                          group
+                                          (nnmail-fetch-field "subject"))))
                  (when (and last nnmail-cache-accepted-message-ids)
                    (nnmail-cache-close))
                  ;; this 'or' is for Cyrus server bug