Synch to No Gnus 200601241028.
[elisp/gnus.git-] / lisp / pop3.el
index 418da1f..8a43c47 100644 (file)
@@ -1,7 +1,7 @@
 ;;; pop3.el --- Post Office Protocol (RFC 1460) interface
 
-;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
-;;        Free Software Foundation, Inc.
+;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
+;;   2004, 2005 Free Software Foundation, Inc.
 
 ;; Author: Richard L. Pieri <ratinox@peorth.gweep.net>
 ;;      Daiki Ueno  <ueno@ueda.info.waseda.ac.jp>
@@ -23,8 +23,8 @@
 
 ;; You should have received a copy of the GNU General Public License
 ;; along with GNU Emacs; see the file COPYING.  If not, write to the
-;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
 
 ;;; Commentary:
 
 
 ;;; Gnus:
 
-;; You can use this program for Gnus, without needing any modification.
-;; There are two ways to do that; one is to replace Gnus' pop3.el with
-;; it when installing Gnus; the other is to replace Gnus' pop3.el which
-;; has been installed with this module and byte-compile it.
+;; Put something like the following line in your ~/.gnus.el file if
+;; you'd like to use this module together with Gnus, not T-gnus.
+;;
+;;(eval-after-load "mail-source" '(require 'pop3))
+;;
+;; There are two ways to install this module; one is to replace
+;; pop3.el of the Gnus version with this module when installing Gnus;
+;; the other is to replace pop3.el of the Gnus version which has been
+;; installed with this module and byte-compile it.
 
 ;; Note: you should not modify the value for the `pop' section of the
 ;; `mail-source-keyword-map' variable.
@@ -79,7 +84,7 @@
 (require 'mail-utils)
 
 (defgroup pop3 nil
-  "Post Office Protocol"
+  "Post Office Protocol."
   :group 'mail
   :group 'mail-source)
 
                             (getenv "LOGNAME")
                             (getenv "USER"))
   "*POP3 maildrop."
-  :version "21.4" ;; Oort Gnus
+  :version "22.1" ;; Oort Gnus
   :type 'string
   :group 'pop3)
 
 (defcustom pop3-mailhost (or (getenv "MAILHOST") ;; nil -> mismatch
                             "pop3")
   "*POP3 mailhost."
-  :version "21.4" ;; Oort Gnus
+  :version "22.1" ;; Oort Gnus
   :type 'string
   :group 'pop3)
 
 (defcustom pop3-port 110
   "*POP3 port."
-  :version "21.4" ;; Oort Gnus
+  :version "22.1" ;; Oort Gnus
   :type 'number
   :group 'pop3)
 
 
 (defcustom pop3-password-required t
   "*Non-nil if a password is required when connecting to POP server."
-  :version "21.4" ;; Oort Gnus
+  :version "22.1" ;; Oort Gnus
   :type 'boolean
   :group 'pop3)
 
 
 (defcustom pop3-authentication-scheme 'pass
   "*POP3 authentication scheme.
-Defaults to 'pass, for the standard USER/PASS authentication.  Other valid
-values are 'apop."
-  :version "21.4" ;; Oort Gnus
-  :type '(choice (const :tag "USER/PASS" pass)
+Defaults to `pass', for the standard USER/PASS authentication.  The other
+valid value is 'apop'."
+  :type '(choice (const :tag "Normal user/password" pass)
                 (const :tag "APOP" apop))
+  :version "22.1" ;; Oort Gnus
   :group 'pop3)
 
 (defcustom pop3-leave-mail-on-server nil
@@ -139,7 +144,7 @@ no state information between sessions, so what the client
 believes is there and what is actually there may not match up.
 If they do not, then the whole thing can fall apart and leave you
 with a corrupt mailbox."
-  :version "21.4" ;; Oort Gnus
+  :version "22.1" ;; Oort Gnus
   :type 'boolean
   :group 'pop3)
 
@@ -150,18 +155,18 @@ Used for APOP authentication.")
 (defcustom pop3-maximum-message-size nil
   "If non-nil only download messages smaller than this."
   :type '(choice (const :tag "Unlimited" nil)
-                (integer :tag "Maximum size" :format "%t: %v\n" :size 0))
+                (integer :tag "Maximum size"))
   :group 'pop3)
 
 (defcustom pop3-except-header-regexp nil
   "If non-nil we do not retrieve messages whose headers are matching this regexp."
   :type '(choice (const :tag "Retrieve any messages" nil)
-                (regexp :format "%t: %v\n" :size 0))
+                (regexp :format "\n%t: %v"))
   :group 'pop3)
 
 (defcustom pop3-uidl-file-name "~/.uidls"
   "File in which to store the UIDL of processed messages."
-  :type '(file :format "%t: %v\n" :size 0)
+  :type 'file
   :group 'pop3)
 
 (defvar pop3-uidl-support nil
@@ -183,13 +188,13 @@ Users don't have to set this value.")
       "openssl"
     "ssleay")
   "The program to run in a subprocess to open an SSL connection."
-  :type '(string :format "%t: %v\n" :size 0)
+  :type 'string
   :group 'pop3)
 
 (defcustom pop3-ssl-program-arguments
   '("s_client" "-quiet")
   "Arguments to be passed to the program `pop3-ssl-program-name'."
-  :type '(repeat (string :format "%v\n" :size 0))
+  :type '(repeat (string :format "%v"))
   :group 'pop3)
 
 (defun pop3-progress-message (format percent &rest args)
@@ -301,6 +306,19 @@ Shorter values mean quicker response, but are more CPU intensive.")
     (pop3-quit process)
     message-count))
 
+(defcustom pop3-stream-type nil
+  "*Transport security type for POP3 connexions.
+This may be either nil (plain connexion), `ssl' (use an
+SSL/TSL-secured stream) or `starttls' (use the starttls mechanism
+to turn on TLS security after opening the stream).  However, if
+this is nil, `ssl' is assumed for connexions to port
+995 (pop3s)."
+  :version "23.0" ;; No Gnus
+  :group 'pop3
+  :type '(choice (const :tag "Plain" nil)
+                (const :tag "SSL/TLS" ssl)
+                (const starttls)))
+
 (defun pop3-open-server (mailhost port)
   "Open TCP connection to MAILHOST on PORT.
 Returns the process associated with the connection.
@@ -314,10 +332,21 @@ Argument PORT specifies connecting port."
       (setq
        process
        (cond
-       ((eq pop3-connection-type 'ssl)
+       ((or (eq pop3-connection-type 'ssl)
+            (eq pop3-stream-type 'ssl)
+            (and (not pop3-stream-type) (member port '(995 "pop3s"))))
+        ;; gnutls-cli, openssl don't accept service names
+        (if (or (equal port "pop3s")
+                (null port))
+            (setq port 995))
         (pop3-open-ssl-stream "POP" (current-buffer) mailhost port))
-       ((eq pop3-connection-type 'tls)
-        (pop3-open-tls-stream "POP" (current-buffer) mailhost port))
+       ((or (memq pop3-connection-type '(tls starttls))
+            (memq pop3-stream-type '(tls starttls)))
+        ;; gnutls-cli, openssl don't accept service names
+        (if (equal port "pop3")
+            (setq port 110))
+        (pop3-open-tls-stream "POP" (current-buffer)
+                              mailhost (or port 110)))
        (t
         (let ((coding-system-for-read 'binary)
               (coding-system-for-write 'binary))
@@ -341,6 +370,7 @@ Argument PORT specifies connecting port."
            "-connect" ,(format "%s:%d" host service)))
         (process (open-ssl-stream name buffer host service)))
     (when process
+      ;; There's a load of info printed that needs deleting.
       (with-current-buffer buffer
        (goto-char (point-min))
        (while (and (memq (process-status process) '(open run))
@@ -476,6 +506,8 @@ If NOW, use that time instead."
            ;; Date: 08 Jul 1996 23:22:24 -0400
            ;; should be
            ;; Tue Jul 9 09:04:21 1996
+
+           ;; Fixme: This should use timezone on the date field contents.
            (setq date
                  (cond ((not date)
                         "Tue Jan 1 00:00:0 1900")
@@ -603,7 +635,7 @@ If NOW, use that time instead."
   (pop3-send-command process (format "USER %s" user))
   (let ((response (pop3-read-response process t)))
     (if (not (and response (string-match "+OK" response)))
-       (error (format "USER %s not valid" user)))))
+       (error "USER %s not valid" user))))
 
 (defun pop3-pass (process)
   "Send authentication information to the server."
@@ -640,8 +672,8 @@ If NOW, use that time instead."
   "Return the number of messages in the maildrop and the maildrop's size."
   (pop3-send-command process "STAT")
   (let ((response (pop3-read-response process t)))
-    (list (string-to-int (nth 1 (split-string response " ")))
-         (string-to-int (nth 2 (split-string response " "))))))
+    (list (string-to-number (nth 1 (split-string response " ")))
+         (string-to-number (nth 2 (split-string response " "))))))
 
 (defun pop3-retr (process msg crashbuf)
   "Retrieve message-id MSG to buffer CRASHBUF."
@@ -667,7 +699,7 @@ If NOW, use that time instead."
   "Return highest accessed message-id number for the session."
   (pop3-send-command process "LAST")
   (let ((response (pop3-read-response process t)))
-    (string-to-int (nth 1 (split-string response " ")))))
+    (string-to-number (nth 1 (split-string response " ")))))
 
 (defun pop3-rset (process)
   "Remove all delete marks from current maildrop."
@@ -712,7 +744,7 @@ where
          (apply 'narrow-to-region (pop3-get-extended-response process))
          (goto-char (point-min))
          (while (looking-at "\\([^ \n\t]*\\) \\([^ \n\t]*\\)")
-           (setq msgno (string-to-int (match-string 1))
+           (setq msgno (string-to-number (match-string 1))
                  uidl (match-string 2))
            (push (cons msgno uidl) pairs)
            (beginning-of-line 2))
@@ -741,8 +773,8 @@ where
          (apply 'narrow-to-region (pop3-get-extended-response process))
          (goto-char (point-min))
          (while (looking-at "\\([^ \n\t]*\\) \\([^ \n\t]*\\)")
-           (setq msgno (string-to-int (match-string 1))
-                 len (string-to-int (match-string 2)))
+           (setq msgno (string-to-number (match-string 1))
+                 len (string-to-number (match-string 2)))
            (push (cons msgno len) pairs)
            (beginning-of-line 2))
          (cons (length pairs) (nreverse pairs)))))))
@@ -822,6 +854,13 @@ to `mail-sources' while fetching mails with Gnus."
 ;;  +OK [negotiation is ready]
 ;;  -ERR [security layer is already active]
 
+;; STLS      (RFC 2595)
+;; Arguments: none
+;; Restrictions: Only permitted in AUTHORIZATION state.
+;; Possible responses:
+;;  +OK
+;;  -ERR
+
 ;;; TRANSACTION STATE
 
 ;; STAT