]> code.delx.au - gnu-emacs/blobdiff - lisp/net/imap.el
Merge from origin/emacs-24
[gnu-emacs] / lisp / net / imap.el
index ab7cfe3427ee7faca32a637db719ed87c7cc1e1e..3e5982398fd473d5fa6af5c251b98e6bbe6dcf36 100644 (file)
@@ -1,7 +1,6 @@
 ;;; imap.el --- imap library
 
-;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-;;   2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
+;; Copyright (C) 1998-2015 Free Software Foundation, Inc.
 
 ;; Author: Simon Josefsson <simon@josefsson.org>
 ;; Keywords: mail
@@ -69,7 +68,7 @@
 ;; imap-body-lines
 ;;
 ;; It is my hope that these commands should be pretty self
-;; explanatory for someone that know IMAP.  All functions have
+;; explanatory for someone who knows IMAP.  All functions have
 ;; additional documentation on how to invoke them.
 ;;
 ;; imap.el supports RFC1730/2060/RFC3501 (IMAP4/IMAP4rev1).  The implemented
 
 (eval-when-compile (require 'cl))
 (eval-and-compile
-  (unless (fboundp 'declare-function) (defmacro declare-function (&rest r)))
+  ;; For Emacs <22.2 and XEmacs.
+  (unless (fboundp 'declare-function) (defmacro declare-function (&rest _r)))
   (autoload 'starttls-open-stream "starttls")
   (autoload 'starttls-negotiate "starttls")
   (autoload 'sasl-find-mechanism "sasl")
@@ -211,7 +211,7 @@ until a successful connection is made."
   :type '(repeat string))
 
 (defcustom imap-process-connection-type nil
-  "*Value for `process-connection-type' to use for Kerberos4, GSSAPI and SSL.
+  "Value for `process-connection-type' to use for Kerberos4, GSSAPI, shell, and SSL.
 The `process-connection-type' variable controls the type of device
 used to communicate with subprocesses.  Values are nil to use a
 pipe, or t or `pty' to use a pty.  The value has no effect if the
@@ -267,11 +267,11 @@ See also `imap-log'."
   :type 'string)
 
 (defcustom imap-read-timeout (if (string-match
-                                 "windows-nt\\|os/2\\|emx\\|cygwin"
+                                 "windows-nt\\|os/2\\|cygwin"
                                  (symbol-name system-type))
                                 1.0
                               0.1)
-  "*How long to wait between checking for the end of output.
+  "How long to wait between checking for the end of output.
 Shorter values mean quicker response, but is more CPU intensive."
   :type 'number
   :group 'imap)
@@ -475,10 +475,10 @@ sure of changing the value of `foo'."
       (setcdr alist (imap-remassoc key (cdr alist)))
       alist)))
 
-(defsubst imap-disable-multibyte ()
+(defmacro imap-disable-multibyte ()
   "Enable multibyte in the current buffer."
-  (when (fboundp 'set-buffer-multibyte)
-    (set-buffer-multibyte nil)))
+  (unless (featurep 'xemacs)
+    '(set-buffer-multibyte nil)))
 
 (defsubst imap-utf7-encode (string)
   (if imap-use-utf7
@@ -515,6 +515,16 @@ sure of changing the value of `foo'."
 \f
 ;; Server functions; stream stuff:
 
+(defun imap-log (string-or-buffer)
+  (when imap-log
+    (with-current-buffer (get-buffer-create imap-log-buffer)
+      (imap-disable-multibyte)
+      (buffer-disable-undo)
+      (goto-char (point-max))
+      (if (bufferp string-or-buffer)
+         (insert-buffer-substring string-or-buffer)
+       (insert string-or-buffer)))))
+
 (defun imap-kerberos4-stream-p (buffer)
   (imap-capability 'AUTH=KERBEROS_V4 buffer))
 
@@ -569,12 +579,6 @@ sure of changing the value of `foo'."
                                  (setq response (match-string 1)))))
              (accept-process-output process 1)
              (sit-for 1))
-           (and imap-log
-                (with-current-buffer (get-buffer-create imap-log-buffer)
-                  (imap-disable-multibyte)
-                  (buffer-disable-undo)
-                  (goto-char (point-max))
-                  (insert-buffer-substring buffer)))
            (erase-buffer)
            (message "Opening Kerberos 4 IMAP connection with `%s'...%s" cmd
                     (if response (concat "done, " response) "failed"))
@@ -645,12 +649,7 @@ sure of changing the value of `foo'."
                                  (setq response (match-string 1)))))
              (accept-process-output process 1)
              (sit-for 1))
-           (and imap-log
-                (with-current-buffer (get-buffer-create imap-log-buffer)
-                  (imap-disable-multibyte)
-                  (buffer-disable-undo)
-                  (goto-char (point-max))
-                  (insert-buffer-substring buffer)))
+           (imap-log buffer)
            (erase-buffer)
            (message "GSSAPI IMAP connection: %s" (or response "failed"))
            (if (and response (let ((case-fold-search nil))
@@ -662,7 +661,7 @@ sure of changing the value of `foo'."
              nil)))))
     done))
 
-(defun imap-ssl-p (buffer)
+(defun imap-ssl-p (_buffer)
   nil)
 
 (defun imap-ssl-open (name buffer server port)
@@ -701,12 +700,7 @@ sure of changing the value of `foo'."
                        (not (imap-parse-greeting)))
              (accept-process-output process 1)
              (sit-for 1))
-           (and imap-log
-                (with-current-buffer (get-buffer-create imap-log-buffer)
-                  (imap-disable-multibyte)
-                  (buffer-disable-undo)
-                  (goto-char (point-max))
-                  (insert-buffer-substring buffer)))
+           (imap-log buffer)
            (erase-buffer)
            (when (memq (process-status process) '(open run))
              (setq done process))))))
@@ -717,7 +711,7 @@ sure of changing the value of `foo'."
       (message "imap: Opening SSL connection with `%s'...failed" cmd)
       nil)))
 
-(defun imap-tls-p (buffer)
+(defun imap-tls-p (_buffer)
   nil)
 
 (defun imap-tls-open (name buffer server port)
@@ -740,16 +734,11 @@ sure of changing the value of `foo'."
                  (not (imap-parse-greeting)))
        (accept-process-output process 1)
        (sit-for 1))
-      (and imap-log
-          (with-current-buffer (get-buffer-create imap-log-buffer)
-            (imap-disable-multibyte)
-            (buffer-disable-undo)
-            (goto-char (point-max))
-            (insert-buffer-substring buffer)))
+      (imap-log buffer)
       (when (memq (process-status process) '(open run))
        process))))
 
-(defun imap-network-p (buffer)
+(defun imap-network-p (_buffer)
   t)
 
 (defun imap-network-open (name buffer server port)
@@ -764,16 +753,11 @@ sure of changing the value of `foo'."
                  (not (imap-parse-greeting)))
        (accept-process-output process 1)
        (sit-for 1))
-      (and imap-log
-          (with-current-buffer (get-buffer-create imap-log-buffer)
-            (imap-disable-multibyte)
-            (buffer-disable-undo)
-            (goto-char (point-max))
-            (insert-buffer-substring buffer)))
+      (imap-log buffer)
       (when (memq (process-status process) '(open run))
        process))))
 
-(defun imap-shell-p (buffer)
+(defun imap-shell-p (_buffer)
   nil)
 
 (defun imap-shell-open (name buffer server port)
@@ -786,6 +770,7 @@ sure of changing the value of `foo'."
       (let* ((port (or port imap-default-port))
             (coding-system-for-read imap-coding-system-for-read)
             (coding-system-for-write imap-coding-system-for-write)
+             (process-connection-type imap-process-connection-type)
             (process (start-process
                       name buffer shell-file-name shell-command-switch
                       (format-spec
@@ -803,12 +788,7 @@ sure of changing the value of `foo'."
                      (not (imap-parse-greeting)))
            (accept-process-output process 1)
            (sit-for 1))
-         (and imap-log
-              (with-current-buffer (get-buffer-create imap-log-buffer)
-                (imap-disable-multibyte)
-                (buffer-disable-undo)
-                (goto-char (point-max))
-                (insert-buffer-substring buffer)))
+         (imap-log buffer)
          (erase-buffer)
          (when (memq (process-status process) '(open run))
            (setq done process)))))
@@ -845,11 +825,7 @@ sure of changing the value of `foo'."
                  (not (re-search-forward "[0-9]+ OK.*\r?\n" nil t)))
        (accept-process-output process 1)
        (sit-for 1))
-      (and imap-log
-          (with-current-buffer (get-buffer-create imap-log-buffer)
-            (buffer-disable-undo)
-            (goto-char (point-max))
-            (insert-buffer-substring buffer)))
+      (imap-log buffer)
       (when (and (setq tls-info (starttls-negotiate process))
                 (memq (process-status process) '(open run)))
        (setq done process)))
@@ -862,9 +838,10 @@ sure of changing the value of `foo'."
 
 (defun imap-interactive-login (buffer loginfunc)
   "Login to server in BUFFER.
-LOGINFUNC is passed a username and a password, it should return t if
-it where successful authenticating itself to the server, nil otherwise.
-Returns t if login was successful, nil otherwise."
+Return t if login was successful, nil otherwise.
+
+LOGINFUNC is passed a username and a password.  It should return
+t if it successfully authenticates, nil otherwise."
   (with-current-buffer buffer
     (make-local-variable 'imap-username)
     (make-local-variable 'imap-password)
@@ -904,10 +881,10 @@ Returns t if login was successful, nil otherwise."
       ;;                      passwd nil))))
       ret)))
 
-(defun imap-gssapi-auth-p (buffer)
+(defun imap-gssapi-auth-p (_buffer)
   (eq imap-stream 'gssapi))
 
-(defun imap-gssapi-auth (buffer)
+(defun imap-gssapi-auth (_buffer)
   (message "imap: Authenticating using GSSAPI...%s"
           (if (eq imap-stream 'gssapi) "done" "failed"))
   (eq imap-stream 'gssapi))
@@ -916,7 +893,7 @@ Returns t if login was successful, nil otherwise."
   (and (imap-capability 'AUTH=KERBEROS_V4 buffer)
        (eq imap-stream 'kerberos4)))
 
-(defun imap-kerberos4-auth (buffer)
+(defun imap-kerberos4-auth (_buffer)
   (message "imap: Authenticating using Kerberos 4...%s"
           (if (eq imap-stream 'kerberos4) "done" "failed"))
   (eq imap-stream 'kerberos4))
@@ -970,7 +947,7 @@ Returns t if login was successful, nil otherwise."
                                                (imap-quote-specials passwd)
                                                "\""))))))
 
-(defun imap-anonymous-p (buffer)
+(defun imap-anonymous-p (_buffer)
   t)
 
 (defun imap-anonymous-auth (buffer)
@@ -1211,11 +1188,12 @@ respond.  If BUFFER is nil, the current buffer is used."
 
 (defun imap-authenticate (&optional user passwd buffer)
   "Authenticate to server in BUFFER, using current buffer if nil.
-It uses the authenticator specified when opening the server.  If the
-authenticator requires username/passwords, they are queried from the
-user and optionally stored in the buffer.  If USER and/or PASSWD is
-specified, the user will not be questioned and the username and/or
-password is remembered in the buffer."
+It uses the authenticator specified when opening the server.
+
+Optional arguments USER and PASSWD specify the username and
+password to use if the authenticator requires a username and/or
+password.  If omitted or nil, the authenticator may query the
+user for a username and/or password."
   (with-current-buffer (or buffer (current-buffer))
     (if (not (eq imap-state 'nonauth))
        (or (eq imap-state 'auth)
@@ -1227,7 +1205,7 @@ password is remembered in the buffer."
       (when user (setq imap-username user))
       (when passwd (setq imap-password passwd))
       (if imap-auth
-         (and (setq imap-last-authenticator 
+         (and (setq imap-last-authenticator
                     (assq imap-auth imap-authenticator-alist))
               (funcall (nth 2 imap-last-authenticator) (current-buffer))
               (setq imap-state 'auth))
@@ -1499,7 +1477,7 @@ If BUFFER is nil the current buffer is assumed."
 (defun imap-mailbox-lsub (&optional root reference add-delimiter buffer)
   "Return a list of subscribed mailboxes on server in BUFFER.
 If ROOT is non-nil, only list matching mailboxes.  If ADD-DELIMITER is
-non-nil, a hierarchy delimiter is added to root.  REFERENCE is a
+non-nil, a hierarchy delimiter is added to root.  REFERENCE is an
 implementation-specific string that has to be passed to lsub command."
   (with-current-buffer (or buffer (current-buffer))
     ;; Make sure we know the hierarchy separator for root's hierarchy
@@ -1523,7 +1501,7 @@ implementation-specific string that has to be passed to lsub command."
 (defun imap-mailbox-list (root &optional reference add-delimiter buffer)
   "Return a list of mailboxes matching ROOT on server in BUFFER.
 If ADD-DELIMITER is non-nil, a hierarchy delimiter is added to
-root.  REFERENCE is a implementation-specific string that has to be
+root.  REFERENCE is an implementation-specific string that has to be
 passed to list command."
   (with-current-buffer (or buffer (current-buffer))
     ;; Make sure we know the hierarchy separator for root's hierarchy
@@ -1583,7 +1561,7 @@ returned, if ITEMS is a symbol only its value is returned."
        (imap-mailbox-get items mailbox)))))
 
 (defun imap-mailbox-status-asynch (mailbox items &optional buffer)
-  "Send status item request ITEM on MAILBOX to server in BUFFER.
+  "Send status item requests ITEMS on MAILBOX to server in BUFFER.
 ITEMS can be a symbol or a list of symbols, valid symbols are one of
 the STATUS data items -- i.e. 'messages, 'recent, 'uidnext, 'uidvalidity
 or 'unseen.  The IMAP command tag is returned."
@@ -1620,7 +1598,7 @@ or 'unseen.  The IMAP command tag is returned."
                                     rights))))))
 
 (defun imap-mailbox-acl-delete (identifier &optional mailbox buffer)
-  "Remove any <identifier,rights> pair for IDENTIFIER in MAILBOX from server in BUFFER."
+  "Remove <id,rights> pairs for IDENTIFIER from MAILBOX on server in BUFFER."
   (let ((mailbox (imap-utf7-encode mailbox)))
     (with-current-buffer (or buffer (current-buffer))
       (imap-ok-p
@@ -1666,8 +1644,8 @@ or 'unseen.  The IMAP command tag is returned."
 
 (defun imap-fetch (uids props &optional receive nouidfetch buffer)
   "Fetch properties PROPS from message set UIDS from server in BUFFER.
-UIDS can be a string, number or a list of numbers.  If RECEIVE
-is non-nil return these properties."
+UIDS can be a string, number or a list of numbers.  If RECEIVE is
+non-nil, return these properties."
   (with-current-buffer (or buffer (current-buffer))
     (when (imap-ok-p (imap-send-command-wait
                      (format "%sFETCH %s %s" (if nouidfetch "" "UID ")
@@ -1767,7 +1745,8 @@ is non-nil return these properties."
        (imap-mailbox-get-1 'search imap-current-mailbox)))))
 
 (defun imap-message-flag-permanent-p (flag &optional mailbox buffer)
-  "Return t if FLAG can be permanently (between IMAP sessions) saved on articles, in MAILBOX on server in BUFFER."
+  "Return t if FLAG can be permanently saved on articles.
+MAILBOX specifies a mailbox on the server in BUFFER."
   (with-current-buffer (or buffer (current-buffer))
     (or (member "\\*" (imap-mailbox-get 'permanentflags mailbox))
        (member flag (imap-mailbox-get 'permanentflags mailbox)))))
@@ -1859,7 +1838,7 @@ See `imap-enable-exchange-bug-workaround'."
            (and (imap-fetch-safe '("*" . "*:*") "UID")
                 (list (imap-mailbox-get-1 'uidvalidity mailbox)
                       (apply 'max (imap-message-map
-                                   (lambda (uid prop) uid) 'UID))))
+                                   (lambda (uid _prop) uid) 'UID))))
          (if old-mailbox
              (imap-mailbox-select old-mailbox (eq state 'examine))
            (imap-mailbox-unselect)))))))
@@ -1905,7 +1884,7 @@ first element.  The rest of list contains the saved articles' UIDs."
            (and (imap-fetch-safe '("*" . "*:*") "UID")
                 (list (imap-mailbox-get-1 'uidvalidity mailbox)
                       (apply 'max (imap-message-map
-                                   (lambda (uid prop) uid) 'UID))))
+                                   (lambda (uid _prop) uid) 'UID))))
          (if old-mailbox
              (imap-mailbox-select old-mailbox (eq state 'examine))
            (imap-mailbox-unselect)))))))
@@ -1914,7 +1893,7 @@ first element.  The rest of list contains the saved articles' UIDs."
   (with-current-buffer (or buffer (current-buffer))
     (imap-message-appenduid-1 (imap-utf7-encode mailbox))))
 
-(defun imap-message-append (mailbox article &optional flags date-time buffer)
+(defun imap-message-append (mailbox article &optional _flags _date-time buffer)
   "Append ARTICLE (a buffer) to MAILBOX on server in BUFFER.
 FLAGS and DATE-TIME is currently not used.  Return a cons holding
 uidvalidity of MAILBOX and UID the newly created article got, or nil
@@ -1942,7 +1921,7 @@ on failure."
     0))
 
 (defun imap-envelope-from (from)
-  "Return a from string line."
+  "Return a FROM string line."
   (and from
        (concat (aref from 0)
               (if (aref from 0) " <")
@@ -1959,12 +1938,7 @@ on failure."
 
 (defun imap-send-command-1 (cmdstr)
   (setq cmdstr (concat cmdstr imap-client-eol))
-  (and imap-log
-       (with-current-buffer (get-buffer-create imap-log-buffer)
-        (imap-disable-multibyte)
-        (buffer-disable-undo)
-        (goto-char (point-max))
-        (insert cmdstr)))
+  (imap-log cmdstr)
   (process-send-string imap-process cmdstr))
 
 (defun imap-send-command (command &optional buffer)
@@ -2002,13 +1976,7 @@ on failure."
                             (stream imap-stream)
                             (eol imap-client-eol))
                         (with-current-buffer cmd
-                          (and imap-log
-                               (with-current-buffer (get-buffer-create
-                                                     imap-log-buffer)
-                                 (imap-disable-multibyte)
-                                 (buffer-disable-undo)
-                                 (goto-char (point-max))
-                                 (insert-buffer-substring cmd)))
+                          (imap-log cmd)
                           (process-send-region process (point-min)
                                                (point-max)))
                         (process-send-string process imap-client-eol))))
@@ -2084,18 +2052,13 @@ Return nil if no complete line has arrived."
     (with-current-buffer (process-buffer proc)
       (goto-char (point-max))
       (insert string)
-      (and imap-log
-          (with-current-buffer (get-buffer-create imap-log-buffer)
-            (imap-disable-multibyte)
-            (buffer-disable-undo)
-            (goto-char (point-max))
-            (insert string)))
+      (imap-log string)
       (let (end)
        (goto-char (point-min))
        (while (setq end (imap-find-next-line))
          (save-restriction
            (narrow-to-region (point-min) end)
-           (delete-backward-char (length imap-server-eol))
+           (delete-char (- (length imap-server-eol)))
            (goto-char (point-min))
            (unwind-protect
                (cond ((eq imap-state 'initial)
@@ -2325,7 +2288,7 @@ Return nil if no complete line has arrived."
 ;;                       ; capability.
 
 (defun imap-parse-response ()
-  "Parse a IMAP command response."
+  "Parse an IMAP command response."
   (let (token)
     (case (setq token (read (current-buffer)))
       (+ (setq imap-continuation
@@ -3093,5 +3056,4 @@ Return nil if no complete line has arrived."
 
 (provide 'imap)
 
-;; arch-tag: 27369ed6-33e4-482f-96f1-8bb906ba70f7
 ;;; imap.el ends here