;;; 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>
;; 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.
(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
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)
(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
"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)
(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.1" ; fixme?
+ :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.
(setq
process
(cond
- ((eq pop3-connection-type 'ssl)
+ ((or (eq pop3-connection-type 'ssl)
+ (eq pop3-stream-type 'ssl)
+ (and (not pop3-stream-type) (= port 995))) ; pop3s
(pop3-open-ssl-stream "POP" (current-buffer) mailhost port))
- ((eq pop3-connection-type 'tls)
+ ((or (memq pop3-connection-type '(tls starttls))
+ (memq pop3-stream-type '(tls starttls)))
(pop3-open-tls-stream "POP" (current-buffer) mailhost port))
(t
(let ((coding-system-for-read 'binary)
"-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))
;; 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")
(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."
"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."
"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."
(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))
(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)))))))
;; +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