From 36f3ece034d4808e83f237578d8d9b7711f0838e Mon Sep 17 00:00:00 2001 From: teranisi Date: Mon, 21 Aug 2000 06:39:56 +0000 Subject: [PATCH] 2000-08-21 Yuuichi Teranishi * elmo-vars.el (elmo-default-imap4-stream-type): New variable. (elmo-default-nntp-stream-type): Ditto. (elmo-default-pop3-stream-type): Ditto. (elmo-network-stream-type-alist): Ditto. (elmo-default-imap4-ssl): Abolished. (elmo-default-nntp-ssl): Ditto. (elmo-default-pop3-ssl): Ditto. * elmo-util.el: (toplevel): Removed needless requires. (elmo-network-get-spec): Use `elmo-network-stream-type-alist'. (elmo-open-network-stream): Open network stream according to the value of `elmo-network-stream-type-alist'. (elmo-get-network-stream-type): New function. (elmo-network-stream-type-spec-string): New macro. (elmo-network-stream-type-symbol): Ditto. (elmo-network-stream-type-function): Ditto. * elmo-pop3.el (elmo-pop3-get-connection): Follow up changes for network-stream-type. All other related portions are changed. (elmo-pop3-open-connection): Ditto. * elmo-nntp.el (elmo-nntp-setting): Follow up changes for network-stream-type. All other related portions are changed. * elmo-imap4.el (elmo-imap4-get-connection): Follow up changes for network-stream-type.All other related portions are changed. (elmo-imap4-error): New macro. (elmo-imap4-error-type): Ditto. (elmo-imap4-error-process): Ditto. (elmo-imap4-error-message): Ditto. (elmo-imap4-auth-login): Use `elmo-imap4-error'. (elmo-imap4-auth-cram-md5): Ditto. (elmo-imap4-auth-digest-md5): Ditto. (elmo-imap4-login): Ditto. (elmo-imap4-open-connection): Remove password entry if authentication was in vain. (elmo-imap4-user-at-host): Abolished. (elmo-imap4-password-key): New buffer local variable. (elmo-imap4-open-connection-1): Set value of `elmo-imap4-password-key' using protocol, port, auth and stream-type. * elmo-dop.el (elmo-dop-list-folder): Use killed list. 2000-08-13 Daiki Ueno * elmo-vars.el (elmo-default-imap4-authenticate-type): Default to nil. * elmo-util.el (elmo-imap4-get-spec): Assume auth as symbol. * elmo-imap4.el (elmo-imap4-user-at-host): New variable. (elmo-imap4-authenticator-alist): New variable. (elmo-imap4-open-connection-1): Rename from elmo-imap4-open-connection. (elmo-imap4-open-connection): Abolish 5th argument `passphrase'; only wraps elmo-imap4-open-connection-1. (elmo-imap4-get-connection): Abolish local variable buffer, proc-stat, user-at-host. (elmo-imap4-auth-login): New function. (elmo-imap4-auth-cram-md5): New function. (elmo-imap4-auth-digest-md5): New function. (elmo-imap4-login): New function. --- elmo/ChangeLog | 64 ++++++++ elmo/elmo-dop.el | 17 +- elmo/elmo-imap4.el | 451 +++++++++++++++++++++++++++++++--------------------- elmo/elmo-nntp.el | 82 +++++----- elmo/elmo-pop3.el | 17 +- elmo/elmo-util.el | 118 ++++++++------ elmo/elmo-vars.el | 31 +++- 7 files changed, 484 insertions(+), 296 deletions(-) diff --git a/elmo/ChangeLog b/elmo/ChangeLog index 1fcf75f..ee6ab9c 100644 --- a/elmo/ChangeLog +++ b/elmo/ChangeLog @@ -1,3 +1,67 @@ +2000-08-21 Yuuichi Teranishi + + * elmo-vars.el (elmo-default-imap4-stream-type): New variable. + (elmo-default-nntp-stream-type): Ditto. + (elmo-default-pop3-stream-type): Ditto. + (elmo-network-stream-type-alist): Ditto. + (elmo-default-imap4-ssl): Abolished. + (elmo-default-nntp-ssl): Ditto. + (elmo-default-pop3-ssl): Ditto. + + * elmo-util.el: (toplevel): Removed needless requires. + (elmo-network-get-spec): Use `elmo-network-stream-type-alist'. + (elmo-open-network-stream): Open network stream according to + the value of `elmo-network-stream-type-alist'. + (elmo-get-network-stream-type): New function. + (elmo-network-stream-type-spec-string): New macro. + (elmo-network-stream-type-symbol): Ditto. + (elmo-network-stream-type-function): Ditto. + + * elmo-pop3.el (elmo-pop3-get-connection): Follow up changes for + network-stream-type. All other related portions are changed. + (elmo-pop3-open-connection): Ditto. + + * elmo-nntp.el (elmo-nntp-setting): Follow up changes for + network-stream-type. All other related portions are changed. + + * elmo-imap4.el (elmo-imap4-get-connection): Follow up changes for + network-stream-type.All other related portions are changed. + (elmo-imap4-error): New macro. + (elmo-imap4-error-type): Ditto. + (elmo-imap4-error-process): Ditto. + (elmo-imap4-error-message): Ditto. + (elmo-imap4-auth-login): Use `elmo-imap4-error'. + (elmo-imap4-auth-cram-md5): Ditto. + (elmo-imap4-auth-digest-md5): Ditto. + (elmo-imap4-login): Ditto. + (elmo-imap4-open-connection): Remove password entry if authentication + was in vain. + (elmo-imap4-user-at-host): Abolished. + (elmo-imap4-password-key): New buffer local variable. + (elmo-imap4-open-connection-1): Set value of `elmo-imap4-password-key' + using protocol, port, auth and stream-type. + + * elmo-dop.el (elmo-dop-list-folder): Use killed list. + +2000-08-13 Daiki Ueno + + * elmo-vars.el (elmo-default-imap4-authenticate-type): Default to nil. + + * elmo-util.el (elmo-imap4-get-spec): Assume auth as symbol. + + * elmo-imap4.el (elmo-imap4-user-at-host): New variable. + (elmo-imap4-authenticator-alist): New variable. + (elmo-imap4-open-connection-1): Rename from + elmo-imap4-open-connection. + (elmo-imap4-open-connection): Abolish 5th argument `passphrase'; + only wraps elmo-imap4-open-connection-1. + (elmo-imap4-get-connection): Abolish local variable buffer, proc-stat, + user-at-host. + (elmo-imap4-auth-login): New function. + (elmo-imap4-auth-cram-md5): New function. + (elmo-imap4-auth-digest-md5): New function. + (elmo-imap4-login): New function. + 2000-08-12 Kenichi OKADA * elmo-maildir.el (elmo-maildir-delete-folder): Set argument of the diff --git a/elmo/elmo-dop.el b/elmo/elmo-dop.el index 2bf02e9..1e1e56f 100644 --- a/elmo/elmo-dop.el +++ b/elmo/elmo-dop.el @@ -277,14 +277,16 @@ even an operation concerns the unplugged folder." '(imap4 nntp pop3 filter pipe)) (and (elmo-multi-p folder) (not (elmo-folder-local-p folder)))) (if elmo-enable-disconnected-operation - (let* ((number-alist (elmo-msgdb-number-load - (elmo-msgdb-expand-path folder))) + (let* ((path (elmo-msgdb-expand-path folder)) + (number-alist (elmo-msgdb-number-load path)) (number-list (mapcar 'car number-alist)) (append-list (elmo-dop-append-list-load folder)) (append-num (length append-list)) + (killed (and elmo-use-killed-list + (elmo-msgdb-killed-list-load path))) alreadies - (i 0) - max-num) + max-num + (i 0)) (while append-list (if (rassoc (car append-list) number-alist) (setq alreadies (append alreadies @@ -299,7 +301,12 @@ even an operation concerns the unplugged folder." (append number-list (list (+ max-num i 1)))) (setq i (+ 1 i))) - number-list) + (if killed + (delq nil + (mapcar (lambda (number) + (unless (memq number killed) number)) + number-list)) + number-list)) (error "Unplugged")) ;; not imap4 folder...list folder (elmo-call-func folder "list-folder"))) diff --git a/elmo/elmo-imap4.el b/elmo/elmo-imap4.el index cadc05a..f490479 100644 --- a/elmo/elmo-imap4.el +++ b/elmo/elmo-imap4.el @@ -65,6 +65,12 @@ (defvar elmo-imap4-use-uid t "Use UID as message number.") +(defvar elmo-imap4-authenticator-alist + '((login elmo-imap4-auth-login) + (cram-md5 elmo-imap4-auth-cram-md5) + (digest-md5 elmo-imap4-auth-digest-md5)) + "Definition of authenticators.") + (defconst elmo-imap4-quoted-specials-list '(?\\ ?\")) (defconst elmo-imap4-non-atom-char-regex @@ -87,6 +93,8 @@ '(("^{.*/nntp}.*$" . ".")) ; Default is for UW's remote nntp mailbox... "Extra namespace alist. A list of cons cell like: (REGEXP . DELIMITER) ") +(defvar elmo-imap4-password-key nil) + ;; buffer local variable (defvar elmo-imap4-server-capability nil) (defvar elmo-imap4-server-namespace nil) @@ -277,7 +285,7 @@ BUFFER must be a single-byte buffer." (process-buffer process)) elmo-imap4-server-namespace))) "/")) - response result append-serv ssl) + response result append-serv type) ;; Append delimiter (if (and root (not (string= root "")) @@ -304,12 +312,13 @@ BUFFER must be a single-byte buffer." (setq append-serv (concat append-serv ":" (int-to-string (elmo-imap4-spec-port spec))))) - (unless (eq (setq ssl (elmo-imap4-spec-ssl spec)) - elmo-default-imap4-ssl) - (if ssl - (setq append-serv (concat append-serv "!"))) - (if (eq ssl 'starttls) - (setq append-serv (concat append-serv "!")))) + (setq type (elmo-imap4-spec-stream-type spec)) + (unless (eq (elmo-network-stream-type-symbol type) + elmo-default-imap4-stream-type) + (if type + (setq append-serv (concat append-serv + (elmo-network-stream-type-spec-string + type))))) (mapcar '(lambda (fld) (concat "%" (elmo-imap4-decode-folder-string fld) (and append-serv @@ -407,51 +416,42 @@ BUFFER must be a single-byte buffer." (defun elmo-imap4-get-connection (spec) "Return opened IMAP connection for SPEC." (let* ((user (elmo-imap4-spec-username spec)) - (server (elmo-imap4-spec-hostname spec)) + (host (elmo-imap4-spec-hostname spec)) (port (elmo-imap4-spec-port spec)) (auth (elmo-imap4-spec-auth spec)) - (ssl (elmo-imap4-spec-ssl spec)) - (user-at-host (format "%s@%s" user server)) - entry connection result buffer process proc-stat + (type (elmo-imap4-spec-stream-type spec)) + entry connection result process user-at-host-on-port) - (if (not (elmo-plugged-p server port)) + (if (not (elmo-plugged-p host port)) (error "Unplugged")) - (setq user-at-host-on-port - (concat user-at-host ":" (int-to-string port) - (if (eq ssl 'starttls) "!!" (if ssl "!")))) + (setq user-at-host-on-port (format "%s@%s:%d" user host port)) + (if type + (setq user-at-host-on-port + (concat + user-at-host-on-port + (elmo-network-stream-type-spec-string type)))) (setq entry (assoc user-at-host-on-port elmo-imap4-connection-cache)) (if (and entry - (memq (setq proc-stat - (process-status (cadr (cdr entry)))) + (memq (process-status (cadr (cdr entry))) '(closed exit))) ;; connection is closed... - (let ((buffer (car (cdr entry)))) + (let ((buffer (car (cdr entry)))) (setq elmo-imap4-connection-cache (delq entry elmo-imap4-connection-cache)) (if buffer (kill-buffer buffer)) (setq entry nil))) (if entry (cdr entry) ; connection cache exists. - (setq result - (elmo-imap4-open-connection server user auth port - (elmo-get-passwd user-at-host) - ssl)) - (if (null result) - (error "Connection failed")) + (setq process + (elmo-imap4-open-connection host port user auth type)) (elmo-imap4-debug "Connected to %s" user-at-host-on-port) - (setq buffer (car result)) - (setq process (cdr result)) - (when (and process (null buffer)) - (elmo-remove-passwd user-at-host) - (delete-process process) - (error "Login failed")) ;; add a new entry to the top of the cache. (setq elmo-imap4-connection-cache (cons (cons user-at-host-on-port - (setq connection (list buffer process - "" ; current-folder.. - ))) + (setq connection (list (process-buffer process) process + "" ; current-folder.. + ))) elmo-imap4-connection-cache)) connection))) @@ -563,6 +563,16 @@ BUFFER must be a single-byte buffer." (setq ret-val (elmo-delete-cr-get-content-type))) (setq elmo-imap4-read-point (+ start bytes)) ret-val))) + +(defun elmo-imap4-send-string (buffer process string) + "Send STRING to server." + (save-excursion + (set-buffer buffer) + (erase-buffer) + (goto-char (point-min)) + (setq elmo-imap4-read-point (point)) + (process-send-string process string) + (process-send-string process "\r\n"))) (defun elmo-imap4-noop (connection) (let ((buffer (car connection)) @@ -1245,147 +1255,223 @@ If optional argument UNMARK is non-nil, unmark." (> (length (car x)) (length (car y)))))))) -(defun elmo-imap4-open-connection (imap4-server user auth port passphrase ssl) - "Open IMAP connection to IMAP4-SERVER on PORT for USER. -Return a cons cell of (session-buffer . process). +(defmacro elmo-imap4-error (type process message) + "Make error structure (Vector of [TYPE PROCESS MESSAGE]). +Type is one of the 'connection, 'authenticate" + (` (let ((vec (vector nil nil nil))) + (aset vec 0 (, type)) + (aset vec 1 (, process)) + (aset vec 2 (, message)) + vec))) + +(defmacro elmo-imap4-error-type (error) + (` (aref error 0))) + +(defmacro elmo-imap4-error-process (error) + (` (aref error 1))) + +(defmacro elmo-imap4-error-message (error) + (` (aref error 2))) + +(defun elmo-imap4-auth-login (buffer process name) + (with-current-buffer buffer + (elmo-imap4-send-command + (current-buffer) process "authenticate login" 'no-lock) + (or (elmo-imap4-read-response (current-buffer) process t) + (throw 'elmo-imap4-error + (elmo-imap4-error 'authenticate process + "AUTH=LOGIN failed."))) + (elmo-imap4-send-string + (current-buffer) process (elmo-base64-encode-string name)) + (or (elmo-imap4-read-response (current-buffer) process t) + (throw 'elmo-imap4-error + (elmo-imap4-error 'authenticate process + "AUTH=LOGIN failed."))) + (elmo-imap4-send-string + (current-buffer) process (elmo-base64-encode-string + (elmo-get-passwd elmo-imap4-password-key))) + (or (elmo-imap4-read-response (current-buffer) process) + (throw 'elmo-imap4-error + (elmo-imap4-error 'authenticate process + "AUTH=LOGIN failed."))))) + +(defun elmo-imap4-auth-cram-md5 (buffer process name) + (save-excursion + (set-buffer buffer) + (let (response) + (elmo-imap4-send-command + (current-buffer) process "authenticate cram-md5" 'no-lock) + (setq response (elmo-imap4-read-response (current-buffer) process t)) + (or response + (throw 'elmo-imap4-error + (elmo-imap4-error 'authenticate process + "AUTH=CRAM-MD5 failed."))) + (setq response (cadr (split-string response " "))) + (elmo-imap4-send-string + (current-buffer) process + (elmo-base64-encode-string + (sasl-cram-md5 name (elmo-get-passwd elmo-imap4-password-key) + (elmo-base64-decode-string response)))) + (or (elmo-imap4-read-response (current-buffer) process) + (throw 'elmo-imap4-error + (elmo-imap4-error 'authenticate process + "AUTH=CRAM-MD5 failed.")))))) + +(defun elmo-imap4-auth-digest-md5 (buffer process name) + (save-excursion + (set-buffer buffer) + (let (response) + (elmo-imap4-send-command + (current-buffer) process "authenticate digest-md5" 'no-lock) + (setq response (elmo-imap4-read-response (current-buffer) process t)) + (or response + (throw 'elmo-imap4-error + (elmo-imap4-error 'authenticate process + "AUTH=DIGEST-MD5 failed."))) + (setq response (cadr (split-string response " "))) + (elmo-imap4-send-string + (current-buffer) process + (elmo-base64-encode-string + (sasl-digest-md5-digest-response + (elmo-base64-decode-string response) + name (elmo-get-passwd elmo-imap4-password-key) + "imap" elmo-imap4-password-key);; XXX + 'no-line-break)) + (or (elmo-imap4-read-response (current-buffer) process t) + (throw 'elmo-imap4-error + (elmo-imap4-error 'authenticate process + "AUTH=DIGEST-MD5 failed."))) + (elmo-imap4-send-string (current-buffer) process "") + (or (elmo-imap4-read-response (current-buffer) process) + (throw 'elmo-imap4-error + (elmo-imap4-error 'authenticate process + "AUTH=DIGEST-MD5 failed.")))))) + +(defun elmo-imap4-login (buffer process name) + (save-excursion + (set-buffer buffer) + (elmo-imap4-send-command + (current-buffer) process + (list "login " (elmo-imap4-userid name) " " + (elmo-imap4-password + (elmo-get-passwd elmo-imap4-password-key))) + nil 'no-log) + (or (elmo-imap4-read-response (current-buffer) process) + (throw 'elmo-imap4-error + (elmo-imap4-error 'authenticate process + "LOGIN failed."))))) + +(defun elmo-imap4-open-connection (host port user auth type) + "Open IMAP connection to HOST on PORT for USER. Return nil if connection failed." - (let ((process nil) - (host imap4-server) - process-buffer ret-val response capability) - (catch 'done - (as-binary-process - (setq process-buffer - (get-buffer-create (format " *IMAP session to %s:%d" host port))) - (save-excursion - (set-buffer process-buffer) - (elmo-set-buffer-multibyte nil) - (make-variable-buffer-local 'elmo-imap4-server-capability) - (make-variable-buffer-local 'elmo-imap4-lock) - (erase-buffer)) - (setq process - (elmo-open-network-stream "IMAP" process-buffer host port ssl)) - (and (null process) (throw 'done nil)) - (set-process-filter process 'elmo-imap4-process-filter) - ;; flush connections when exiting... - (save-excursion - (set-buffer process-buffer) - (make-local-variable 'elmo-imap4-read-point) - (setq elmo-imap4-read-point (point-min)) - (if (null (setq response - (elmo-imap4-read-response process-buffer process t))) - (throw 'done nil) - (when (string-match "^\\* PREAUTH" response) - (setq ret-val (cons process-buffer process)) - (throw 'done nil))) - (elmo-imap4-send-command process-buffer process "capability") - (setq elmo-imap4-server-capability - (elmo-imap4-parse-capability - (elmo-imap4-read-response process-buffer process))) - (setq capability elmo-imap4-server-capability) - (if (eq ssl 'starttls) - (if (and (memq 'starttls capability) - (progn - (elmo-imap4-send-command process-buffer process "starttls") - (setq response - (elmo-imap4-read-response process-buffer process))) - - (string-match - (concat "^\\(" elmo-imap4-seq-prefix - (int-to-string elmo-imap4-seqno) - "\\|\\*\\) OK") - response)) - (starttls-negotiate process) - (error "STARTTLS aborted"))) - (if (or (and (string= "auth" auth) - (not (memq 'auth=login capability))) - (and (string= "cram-md5" auth) - (not (memq 'auth=cram-md5 capability))) - (and (string= "digest-md5" auth) - (not (memq 'auth=digest-md5 capability)))) - (if (or elmo-imap4-force-login - (y-or-n-p - (format - "There's no %s capability in server. continue?" auth))) - (setq auth "login") - (error "Login aborted"))) - (cond - ((string= "auth" auth) - (elmo-imap4-send-command - process-buffer process "authenticate login" 'no-lock) - ;; Base64 - (when (null (elmo-imap4-read-response process-buffer process t)) - (setq ret-val (cons nil process)) - (throw 'done nil)) - (elmo-imap4-send-string - process-buffer process (elmo-base64-encode-string user)) - (when (null (elmo-imap4-read-response process-buffer process t)) - (setq ret-val (cons nil process)) - (throw 'done nil)) - (elmo-imap4-send-string - process-buffer process (elmo-base64-encode-string passphrase)) - (when (null (elmo-imap4-read-response process-buffer process)) - (setq ret-val (cons nil process)) - (throw 'done nil)) - (setq ret-val (cons process-buffer process))) - ((string= "cram-md5" auth) - (elmo-imap4-send-command - process-buffer process "authenticate cram-md5" 'no-lock) - (when (null (setq response - (elmo-imap4-read-response - process-buffer process t))) - (setq ret-val (cons nil process)) - (throw 'done nil)) - (setq response (cadr (split-string response " "))) - (elmo-imap4-send-string - process-buffer process - (elmo-base64-encode-string - (sasl-cram-md5 user passphrase - (elmo-base64-decode-string response)))) - (when (null (elmo-imap4-read-response process-buffer process)) - (setq ret-val (cons nil process)) - (throw 'done nil)) - (setq ret-val (cons process-buffer process))) - ((string= "digest-md5" auth) - (elmo-imap4-send-command - process-buffer process "authenticate digest-md5" 'no-lock) - (when (null (setq response - (elmo-imap4-read-response - process-buffer process t))) - (setq ret-val (cons nil process)) - (throw 'done nil)) - (setq response (cadr (split-string response " "))) - (elmo-imap4-send-string - process-buffer process - (elmo-base64-encode-string - (sasl-digest-md5-digest-response - (elmo-base64-decode-string response) - user passphrase "imap" host) - 'no-line-break)) - (when (null (elmo-imap4-read-response - process-buffer process t)) - (setq ret-val (cons nil process)) - (throw 'done nil)) - (elmo-imap4-send-string process-buffer process "") - (when (null (elmo-imap4-read-response process-buffer process)) - (setq ret-val (cons nil process)) - (throw 'done nil)) - (setq ret-val (cons process-buffer process))) - (t ;; not auth... try login - (elmo-imap4-send-command - process-buffer process - (list "login " (elmo-imap4-userid user) " " (elmo-imap4-password passphrase)) - nil 'no-log) ;; No LOGGING. - (if (null (elmo-imap4-read-response process-buffer process)) - (setq ret-val (cons nil process)) - (setq ret-val (cons process-buffer process))))) - ;; get namespace of server if possible. - (when (memq 'namespace elmo-imap4-server-capability) - (elmo-imap4-send-command process-buffer process "namespace") - (setq elmo-imap4-server-namespace - (elmo-imap4-parse-namespace - (elmo-imap4-parse-response - (elmo-imap4-read-response process-buffer process)))))))) - ret-val)) + (let (process error) + (setq error + (catch 'elmo-imap4-error + (save-excursion + (setq process + (elmo-imap4-open-connection-1 host port user auth type))) + nil)) + (when error + (and (elmo-imap4-error-process error) + (delete-process (elmo-imap4-error-process error))) + (cond ((eq (elmo-imap4-error-type error) 'connection) + nil) + ((eq (elmo-imap4-error-type error) 'authenticate) + (and (elmo-imap4-error-process error) + (with-current-buffer (process-buffer + (elmo-imap4-error-process error)) + (elmo-remove-passwd elmo-imap4-password-key))))) + (error "Failed to open %s@%s: %s" user host + (elmo-imap4-error-message error))) + process)) + +(defun elmo-imap4-open-connection-1 (host port user auth type) + "Open IMAP connection to HOST on PORT for USER. +Return nil if connection failed." + (let ((process nil) response capability mechanism) + (as-binary-process + (setq process + (elmo-open-network-stream + "IMAP" (format " *IMAP session to %s:%d" host port) + host port type))) + (or process + (throw 'elmo-imap4-error + (elmo-imap4-error 'connection nil + "Connection failed."))) + (set-buffer (process-buffer process)) + (elmo-set-buffer-multibyte nil) + (buffer-disable-undo) + (make-variable-buffer-local 'elmo-imap4-server-capability) + (make-variable-buffer-local 'elmo-imap4-lock) + (make-local-variable 'elmo-imap4-read-point) + (setq elmo-imap4-read-point (point-min)) + (make-local-variable 'elmo-imap4-password-key) + (setq elmo-imap4-password-key (format "IMAP4:%s/%s@%s:%d" + user + (symbol-name (or auth "plain")) + host + port + (elmo-network-stream-type-spec-string + type))) + (erase-buffer) + (set-process-filter process 'elmo-imap4-process-filter) + ;; flush connections when exiting... + (setq response + (elmo-imap4-read-response (current-buffer) process t)) + (unless (string-match "^\\* PREAUTH" response) + (elmo-imap4-send-command (current-buffer) process "capability") + (setq elmo-imap4-server-capability + (elmo-imap4-parse-capability + (elmo-imap4-read-response (current-buffer) process)) + capability elmo-imap4-server-capability) + (when (eq (elmo-network-stream-type-symbol type) 'starttls) + (or (memq 'starttls capability) + (throw 'elmo-imap4-error + (elmo-imap4-error + 'connection + process + "There's no STARTTLS support in server."))) + (elmo-imap4-send-command (current-buffer) process "starttls") + (setq response + (elmo-imap4-read-response (current-buffer) process)) + (if (string-match + (concat "^\\(" elmo-imap4-seq-prefix + (int-to-string elmo-imap4-seqno) + "\\|\\*\\) OK") + response) + (starttls-negotiate process))) + (unless (or (not auth) + (and (memq (intern (format "auth=%s" auth)) + capability) + (setq mechanism + (assq auth elmo-imap4-authenticator-alist)))) + (if (or elmo-imap4-force-login + (y-or-n-p + (format + "There's no %s capability in server. continue?" auth))) + (progn + (setq auth nil) + (setq elmo-imap4-password-key + (format "IMAP4:%s/%s@%s:%d" + user + (symbol-name (or auth 'plain)) + host + port + (elmo-network-stream-type-spec-string + type)))) + (throw 'elmo-imap4-error + (cons process "There's no AUTHENTICATE mechanism.")))) + (if auth + (funcall (nth 1 mechanism) (current-buffer) process user) + (elmo-imap4-login (current-buffer) process user)));; try login + ;; get namespace of server if possible. + (when (memq 'namespace elmo-imap4-server-capability) + (elmo-imap4-send-command (current-buffer) process "namespace") + (setq elmo-imap4-server-namespace + (elmo-imap4-parse-namespace + (elmo-imap4-parse-response + (elmo-imap4-read-response (current-buffer) process))))) + process)) (defun elmo-imap4-get-seqno () (setq elmo-imap4-seqno (+ 1 elmo-imap4-seqno))) @@ -1472,16 +1558,6 @@ Return nil if connection failed." (process-send-string process "\r\n")) )) -(defun elmo-imap4-send-string (buffer process string) - "Send STRING to server." - (save-excursion - (set-buffer buffer) - (erase-buffer) - (goto-char (point-min)) - (setq elmo-imap4-read-point (point)) - (process-send-string process string) - (process-send-string process "\r\n"))) - (defun elmo-imap4-read-part (folder msg part) (save-excursion (let* ((spec (elmo-folder-get-spec folder)) @@ -1744,7 +1820,8 @@ Return nil if connection failed." process (list "status " - (elmo-imap4-mailbox (elmo-imap4-spec-mailbox spec)) + (elmo-imap4-mailbox + (elmo-imap4-spec-mailbox spec)) " (unseen messages)")) (setq response (elmo-imap4-read-response (process-buffer process) process)) @@ -1761,7 +1838,11 @@ Return nil if connection failed." (defun elmo-imap4-port-label (spec) (concat "imap4" - (if (nth 6 spec) "!ssl" ""))) + (if (elmo-imap4-spec-stream-type spec) + (concat "!" (symbol-name + (elmo-network-stream-type-symbol + (elmo-imap4-spec-stream-type spec))))))) + (defsubst elmo-imap4-portinfo (spec) (list (elmo-imap4-spec-hostname spec) (elmo-imap4-spec-port spec))) diff --git a/elmo/elmo-nntp.el b/elmo/elmo-nntp.el index e6dd617..a0e3f31 100644 --- a/elmo/elmo-nntp.el +++ b/elmo/elmo-nntp.el @@ -80,12 +80,12 @@ Don't cache if nil.") (put 'elmo-nntp-setting 'lisp-indent-function 1) (defmacro elmo-nntp-setting (spec &rest body) - (` (let* ((ssl (elmo-nntp-spec-ssl (, spec))) + (` (let* ((type (elmo-nntp-spec-stream-type (, spec))) (port (elmo-nntp-spec-port (, spec))) (user (elmo-nntp-spec-username (, spec))) (server (elmo-nntp-spec-hostname (, spec))) (folder (elmo-nntp-spec-group (, spec))) - (connection (elmo-nntp-get-connection server user port ssl)) + (connection (elmo-nntp-get-connection server user port type)) (buffer (car connection)) (process (cadr connection))) (,@ body)))) @@ -143,7 +143,7 @@ Don't cache if nil.") (defsubst elmo-nntp-max-number-precedes-list-active-p () elmo-nntp-max-number-precedes-list-active) -(defsubst elmo-nntp-folder-postfix (user server port ssl) +(defsubst elmo-nntp-folder-postfix (user server port type) (concat (and user (concat ":" user)) (if (and server @@ -153,10 +153,9 @@ Don't cache if nil.") (null (eq port elmo-default-nntp-port))) (concat ":" (if (numberp port) (int-to-string port) port))) - (unless (eq ssl elmo-default-nntp-ssl) - (if (eq ssl 'starttls) - "!!" - (if ssl "!"))))) + (unless (eq (elmo-network-stream-type-symbol type) + elmo-default-nntp-stream-type) + (elmo-network-stream-type-spec-string type)))) (defun elmo-nntp-flush-connection () (interactive) @@ -170,12 +169,12 @@ Don't cache if nil.") (setq cache (cdr cache))) (setq elmo-nntp-connection-cache nil))) -(defun elmo-nntp-get-connection (server user port ssl) +(defun elmo-nntp-get-connection (server user port type) "Return opened NNTP connection to SERVER on PORT for USER." (let* ((user-at-host (format "%s@%s" user server)) (user-at-host-on-port (concat user-at-host ":" (int-to-string port) - (if (eq ssl 'starttls) "!!" (if ssl "!")))) + (elmo-network-stream-type-spec-string type))) entry connection result buffer process proc-stat) (if (not (elmo-plugged-p server port)) (error "Unplugged")) @@ -192,7 +191,7 @@ Don't cache if nil.") (setq entry nil))) (if entry (cdr entry) - (setq result (elmo-nntp-open-connection server user port ssl)) + (setq result (elmo-nntp-open-connection server user port type)) (if (null result) (error "Connection failed")) (setq buffer (car result)) @@ -288,8 +287,8 @@ Don't cache if nil.") (insert-buffer-substring buffer start (- end 3)) (elmo-delete-cr-get-content-type))))) -(defun elmo-nntp-goto-folder (server folder user port ssl) - (let* ((connection (elmo-nntp-get-connection server user port ssl)) +(defun elmo-nntp-goto-folder (server folder user port type) + (let* ((connection (elmo-nntp-get-connection server user port type)) (buffer (car connection)) (process (cadr connection)) (cwf (caddr connection))) @@ -348,7 +347,7 @@ Don't cache if nil.") (save-excursion (set-buffer tmp-buffer) (if (and folder - (elmo-nntp-goto-folder server folder user port ssl)) + (elmo-nntp-goto-folder server folder user port type)) (setq ret-val (list folder))) ;; add top newsgroups (unless (setq response (elmo-nntp-list-folders-get-cache folder tmp-buffer)) @@ -431,11 +430,11 @@ Don't cache if nil.") (setq append-serv (concat "@" server))) (unless (eq port elmo-default-nntp-port) (setq append-serv (concat append-serv ":" (int-to-string port)))) - (unless (eq ssl elmo-default-nntp-ssl) - (if ssl - (setq append-serv (concat append-serv "!"))) - (if (eq ssl 'starttls) - (setq append-serv (concat append-serv "!")))) + (unless (eq (elmo-network-stream-type-symbol type) + elmo-default-nntp-stream-type) + (setq append-serv + (concat append-serv + (elmo-network-stream-type-spec-string type)))) (mapcar '(lambda (fld) (if (consp fld) (list (concat "-" (car fld) @@ -509,7 +508,7 @@ Don't cache if nil.") (let* ((port (elmo-nntp-spec-port spec)) (user (elmo-nntp-spec-username spec)) (server (elmo-nntp-spec-hostname spec)) - (ssl (elmo-nntp-spec-ssl spec)) + (type (elmo-nntp-spec-stream-type spec)) (folder (elmo-nntp-spec-group spec)) (dir (elmo-msgdb-expand-path nil spec)) (killed-list (and elmo-use-killed-list @@ -517,7 +516,7 @@ Don't cache if nil.") number-alist end-num) (if elmo-nntp-groups-async (let* ((fld (concat folder - (elmo-nntp-folder-postfix user server port ssl))) + (elmo-nntp-folder-postfix user server port type))) (entry (elmo-get-hash-val fld elmo-nntp-groups-hashtb))) (if entry (progn @@ -538,7 +537,7 @@ Don't cache if nil.") (setq killed-list (cdr killed-list)))))) (cons end-num (car entry))) (error "No such newsgroup \"%s\"" fld))) - (let* ((connection (elmo-nntp-get-connection server user port ssl)) + (let* ((connection (elmo-nntp-get-connection server user port type)) (buffer (car connection)) (process (cadr connection)) response e-num) @@ -685,7 +684,7 @@ Don't cache if nil.") ret-val ov-str use-xover dir) (if (and folder (not (string= cwf folder)) - (null (elmo-nntp-goto-folder server folder user port ssl))) + (null (elmo-nntp-goto-folder server folder user port type))) (error "group %s not found" folder)) (when (setq use-xover (elmo-nntp-xover-p server port)) (setq beg-num (car numlist) @@ -788,7 +787,7 @@ Don't cache if nil.") (if (and folder (not (string= cwf folder)) (null (elmo-nntp-goto-folder - server folder user port ssl))) + server folder user port type))) (error "group %s not found" folder)) (elmo-nntp-send-command buffer process (format "list active %s" folder)) @@ -845,16 +844,16 @@ Don't cache if nil.") ; (kill-buffer tmp-buffer) ret-val))) -(defun elmo-nntp-get-overview (server beg end folder user port ssl) +(defun elmo-nntp-get-overview (server beg end folder user port type) (save-excursion - (let* ((connection (elmo-nntp-get-connection server user port ssl)) + (let* ((connection (elmo-nntp-get-connection server user port type)) (buffer (car connection)) (process (cadr connection)) ; (cwf (caddr connection)) response errmsg ov-str) (catch 'done (if folder - (if (null (elmo-nntp-goto-folder server folder user port ssl)) + (if (null (elmo-nntp-goto-folder server folder user port type)) (progn (setq errmsg (format "group %s not found." folder)) (throw 'done nil)))) @@ -879,11 +878,11 @@ Don't cache if nil.") ov-str)))) -(defun elmo-nntp-get-message (server user number folder outbuf port ssl) +(defun elmo-nntp-get-message (server user number folder outbuf port type) "Get nntp message on FOLDER at SERVER. Returns message string." (save-excursion - (let* ((connection (elmo-nntp-get-connection server user port ssl)) + (let* ((connection (elmo-nntp-get-connection server user port type)) (buffer (car connection)) (process (cadr connection)) (cwf (caddr connection)) @@ -891,7 +890,7 @@ Returns message string." (catch 'done (if (and folder (not (string= cwf folder))) - (if (null (elmo-nntp-goto-folder server folder user port ssl)) + (if (null (elmo-nntp-goto-folder server folder user port type)) (progn (setq errmsg (format "group %s not found." folder)) (throw 'done nil)))) @@ -918,10 +917,10 @@ Returns message string." nil)) response))) -(defun elmo-nntp-get-newsgroup-by-msgid (msgid server user port ssl) +(defun elmo-nntp-get-newsgroup-by-msgid (msgid server user port type) "Get nntp header string." (save-excursion - (let* ((connection (elmo-nntp-get-connection server user port ssl)) + (let* ((connection (elmo-nntp-get-connection server user port type)) (buffer (car connection)) (process (cadr connection))) (elmo-nntp-send-command buffer process @@ -931,7 +930,7 @@ Returns message string." (set-buffer buffer) (std11-field-body "Newsgroups")))) -(defun elmo-nntp-open-connection (server user portnum ssl) +(defun elmo-nntp-open-connection (server user portnum type) "Open NNTP connection to SERVER on PORTNUM for USER. Return a cons cell of (session-buffer . process). Return nil if connection failed." @@ -950,7 +949,7 @@ Return nil if connection failed." (elmo-set-buffer-multibyte nil) (erase-buffer)) (setq process - (elmo-open-network-stream "NNTP" process-buffer host port ssl)) + (elmo-open-network-stream "NNTP" process-buffer host port type)) (and (null process) (throw 'done nil)) (set-process-filter process 'elmo-nntp-process-filter) ;; flush connections when exiting...? @@ -965,7 +964,7 @@ Return nil if connection failed." (if elmo-nntp-send-mode-reader (elmo-nntp-send-mode-reader process-buffer process)) ;; starttls - (if (eq ssl 'starttls) + (if (eq (elmo-network-stream-type-symbol type) 'starttls) (if (progn (elmo-nntp-send-command process-buffer process "starttls") (elmo-nntp-read-response process-buffer process)) @@ -1012,7 +1011,7 @@ Return nil if connection failed." (elmo-nntp-spec-group spec) outbuf (elmo-nntp-spec-port spec) - (elmo-nntp-spec-ssl spec))) + (elmo-nntp-spec-stream-type spec))) ;(defun elmo-msgdb-nntp-overview-create-range (spec beg end mark) ; (elmo-nntp-overview-create-range hostname beg end mark folder))) @@ -1028,7 +1027,7 @@ Return nil if connection failed." (elmo-nntp-get-connection hostname elmo-default-nntp-user - elmo-default-nntp-port elmo-default-nntp-ssl)) + elmo-default-nntp-port elmo-default-nntp-stream-type)) (buffer (car connection)) (process (cadr connection)) response has-message-id @@ -1139,7 +1138,7 @@ Return nil if connection failed." (unless (setq key (assoc (cons buffer process) connection-keys)) (erase-buffer) (setq key (cons (cons buffer process) - (vector 0 server user port ssl))) + (vector 0 server user port type))) (setq connection-keys (nconc connection-keys (list key)))) (elmo-nntp-send-command buffer process @@ -1168,7 +1167,7 @@ Return nil if connection failed." (server (aref key 1)) (user (aref key 2)) (port (aref key 3)) - (ssl (aref key 4)) + (type (aref key 4)) (hashtb (or elmo-nntp-groups-hashtb (setq elmo-nntp-groups-hashtb (elmo-make-hash count))))) @@ -1177,7 +1176,7 @@ Return nil if connection failed." (set-buffer cur) (goto-char (point-min)) (let ((case-replace nil) - (postfix (elmo-nntp-folder-postfix user server port ssl))) + (postfix (elmo-nntp-folder-postfix user server port type))) (if (not (string= postfix "")) (save-excursion (replace-regexp "^\\(211 [0-9]+ [0-9]+ [0-9]+ [^ \n]+\\).*$" @@ -1389,7 +1388,10 @@ Return nil if connection failed." (defun elmo-nntp-port-label (spec) (concat "nntp" - (if (elmo-nntp-spec-ssl spec) "!ssl" ""))) + (if (elmo-nntp-spec-stream-type spec) + (concat "!" (symbol-name + (elmo-network-stream-type-symbol + (elmo-nntp-spec-stream-type spec))))))) (defsubst elmo-nntp-portinfo (spec) (list (elmo-nntp-spec-hostname spec) diff --git a/elmo/elmo-pop3.el b/elmo/elmo-pop3.el index 4343105..628799e 100644 --- a/elmo/elmo-pop3.el +++ b/elmo/elmo-pop3.el @@ -112,7 +112,7 @@ (server (elmo-pop3-spec-hostname spec)) (port (elmo-pop3-spec-port spec)) (auth (elmo-pop3-spec-auth spec)) - (ssl (elmo-pop3-spec-ssl spec)) + (type (elmo-pop3-spec-stream-type spec)) (user-at-host (format "%s@%s" user server)) entry connection result buffer process proc-stat response user-at-host-on-port) @@ -120,7 +120,7 @@ (error "Unplugged")) (setq user-at-host-on-port (concat user-at-host ":" (int-to-string port) - (if (eq ssl 'starttls) "!!" (if ssl "!")))) + (elmo-network-stream-type-spec-string type))) (setq entry (assoc user-at-host-on-port elmo-pop3-connection-cache)) (if (and entry (memq (setq proc-stat @@ -138,7 +138,7 @@ (setq result (elmo-pop3-open-connection server user port auth - (elmo-get-passwd user-at-host) ssl)) + (elmo-get-passwd user-at-host) type)) (if (null result) (error "Connection failed")) (setq buffer (car result)) @@ -240,7 +240,7 @@ (goto-char (point-max)) (insert output))) -(defun elmo-pop3-open-connection (server user port auth passphrase ssl) +(defun elmo-pop3-open-connection (server user port auth passphrase type) "Open POP3 connection to SERVER on PORT for USER. Return a cons cell of (session-buffer . process). Return nil if connection failed." @@ -256,7 +256,7 @@ Return nil if connection failed." (elmo-set-buffer-multibyte nil) (erase-buffer)) (setq process - (elmo-open-network-stream "POP" process-buffer host port ssl)) + (elmo-open-network-stream "POP" process-buffer host port type)) (and (null process) (throw 'done nil)) (set-process-filter process 'elmo-pop3-process-filter) ;; flush connections when exiting... @@ -268,7 +268,7 @@ Return nil if connection failed." (elmo-pop3-read-response process-buffer process t))) (setq ret-val (cons nil process)) (throw 'done nil)) - (when (eq ssl 'starttls) + (when (eq (elmo-network-stream-type-symbol type) 'starttls) (elmo-pop3-send-command process-buffer process "stls") (string-match "^\+OK" (elmo-pop3-read-response @@ -799,7 +799,10 @@ Return nil if connection failed." (defun elmo-pop3-port-label (spec) (concat "pop3" - (if (elmo-pop3-spec-ssl spec) "!ssl" ""))) + (if (elmo-pop3-spec-stream-type spec) + (concat "!" (symbol-name + (elmo-network-stream-type-symbol + (elmo-pop3-spec-stream-type spec))))))) (defsubst elmo-pop3-portinfo (spec) (list (elmo-pop3-spec-hostname spec) diff --git a/elmo/elmo-util.el b/elmo/elmo-util.el index 4693a79..e79bcee 100644 --- a/elmo/elmo-util.el +++ b/elmo/elmo-util.el @@ -36,16 +36,6 @@ (require 'eword-decode) (require 'utf7) -(eval-when-compile - (condition-case nil - (progn - (require 'ssl) - (require 'starttls)) - (error)) - (defun-maybe starttls-negotiate (a)) - (defun-maybe starttls-open-stream (a b c d)) - (defun-maybe open-ssl-stream (a b c d))) - (defmacro elmo-set-buffer-multibyte (flag) "Set the multibyte flag of the current buffer to FLAG." (cond ((boundp 'MULE) @@ -287,9 +277,10 @@ File content is encoded with MIME-CHARSET." (utf7-encode-string string 'imap) string)) -(defun elmo-network-get-spec (folder default-server default-port default-tls) - (let (server port tls) - (if (string-match "\\(@[^@:/!]+\\)?\\(:[0-9]+\\)?\\(!*\\)$" folder) +(defun elmo-network-get-spec (folder default-server default-port + default-stream-type) + (let (server port type) + (if (string-match "\\(@[^@:/!]+\\)?\\(:[0-9]+\\)?\\(!.*\\)?$" folder) (progn (if (match-beginning 1) (setq server (elmo-match-substring 1 folder 1)) @@ -298,23 +289,21 @@ File content is encoded with MIME-CHARSET." (setq port (string-to-int (elmo-match-substring 2 folder 1))) (setq port default-port)) - (setq tls (elmo-match-string 3 folder)) - (if (and (match-beginning 3) - (> (length tls) 0)) - (setq tls (if (= 2 (length tls)) 'starttls - (string= tls "!"))) - (setq tls default-tls)) + (if (match-beginning 3) + (setq type (assoc (elmo-match-string 3 folder) + elmo-network-stream-type-alist)) + (setq type default-stream-type)) (setq folder (substring folder 0 (match-beginning 0)))) (setq server default-server port default-port - tls default-tls)) - (cons folder (list server port tls)))) + type (elmo-get-network-stream-type default-stream-type))) + (cons folder (list server port type)))) (defun elmo-imap4-get-spec (folder) - (let ((default-user elmo-default-imap4-user) - (default-server elmo-default-imap4-server) - (default-port elmo-default-imap4-port) - (default-tls elmo-default-imap4-ssl) + (let ((default-user elmo-default-imap4-user) + (default-server elmo-default-imap4-server) + (default-port elmo-default-imap4-port) + (default-stream-type elmo-default-imap4-stream-type) spec mailbox user auth) (when (string-match "\\(.*\\)@\\(.*\\)" default-server) ;; case: default-imap4-server is specified like @@ -322,7 +311,7 @@ File content is encoded with MIME-CHARSET." (setq default-user (elmo-match-string 1 default-server)) (setq default-server (elmo-match-string 2 default-server))) (setq spec (elmo-network-get-spec - folder default-server default-port default-tls)) + folder default-server default-port default-stream-type)) (setq folder (car spec)) (when (string-match "^\\(%\\)\\([^:@!]*\\)\\(:[^/!]+\\)?\\(/[^/:@!]+\\)?" @@ -335,7 +324,7 @@ File content is encoded with MIME-CHARSET." (elmo-match-substring 3 folder 1) default-user)) (setq auth (if (match-beginning 4) - (elmo-match-substring 4 folder 1) + (intern (elmo-match-substring 4 folder 1)) elmo-default-imap4-authenticate-type)) (append (list 'imap4 (elmo-imap4-encode-folder-string mailbox) @@ -357,7 +346,7 @@ File content is encoded with MIME-CHARSET." (defsubst elmo-imap4-spec-port (spec) (nth 5 spec)) -(defsubst elmo-imap4-spec-ssl (spec) +(defsubst elmo-imap4-spec-stream-type (spec) (nth 6 spec)) (defalias 'elmo-imap4-spec-folder 'elmo-imap4-spec-mailbox) @@ -377,7 +366,7 @@ File content is encoded with MIME-CHARSET." (setq spec (elmo-network-get-spec folder elmo-default-nntp-server elmo-default-nntp-port - elmo-default-nntp-ssl)) + elmo-default-nntp-stream-type)) (setq folder (car spec)) (when (string-match "^\\(-\\)\\([^:@!]*\\)\\(:[^/!]+\\)?\\(/[^/:@!]+\\)?" @@ -407,7 +396,7 @@ File content is encoded with MIME-CHARSET." (defsubst elmo-nntp-spec-port (spec) (nth 4 spec)) -(defsubst elmo-nntp-spec-ssl (spec) +(defsubst elmo-nntp-spec-stream-type (spec) (nth 5 spec)) (defun elmo-localdir-get-spec (folder) @@ -498,7 +487,7 @@ File content is encoded with MIME-CHARSET." (setq spec (elmo-network-get-spec folder elmo-default-pop3-server elmo-default-pop3-port - elmo-default-pop3-ssl)) + elmo-default-pop3-stream-type)) (setq folder (car spec)) (when (string-match "^\\(&\\)\\([^:/!]*\\)\\(/[^/:@!]+\\)?" @@ -525,7 +514,7 @@ File content is encoded with MIME-CHARSET." (defsubst elmo-pop3-spec-port (spec) (nth 4 spec)) -(defsubst elmo-pop3-spec-ssl (spec) +(defsubst elmo-pop3-spec-stream-type (spec) (nth 5 spec)) (defun elmo-internal-get-spec (folder) @@ -733,6 +722,11 @@ File content is encoded with MIME-CHARSET." (kill-buffer tmp-buffer) ret-val))) +(defun elmo-passwd-alist-clear () + "Clear password cache." + (interactive) + (setq elmo-passwd-alist nil)) + (defun elmo-passwd-alist-save () "Save password into file." (interactive) @@ -755,29 +749,29 @@ File content is encoded with MIME-CHARSET." (message (format "%s is not writable." filename))) (kill-buffer tmp-buffer)))) -(defun elmo-get-passwd (user-at-host) +(defun elmo-get-passwd (key) "Get password from password pool." - (let (data pass) + (let (pair pass) (if (not elmo-passwd-alist) (setq elmo-passwd-alist (elmo-passwd-alist-load))) - (setq data (assoc user-at-host elmo-passwd-alist)) - (if data - (elmo-base64-decode-string (cdr data)) + (setq pair (assoc key elmo-passwd-alist)) + (if pair + (elmo-base64-decode-string (cdr pair)) (setq pass (elmo-read-passwd (format "Password for %s: " - user-at-host) t)) + key) t)) (setq elmo-passwd-alist (append elmo-passwd-alist - (list (cons user-at-host + (list (cons key (elmo-base64-encode-string pass))))) (if elmo-passwd-life-time (run-with-timer elmo-passwd-life-time nil - (` (lambda () (elmo-remove-passwd (, user-at-host)))))) + (` (lambda () (elmo-remove-passwd (, key)))))) pass))) -(defun elmo-remove-passwd (user-at-host) +(defun elmo-remove-passwd (key) "Remove password from password pool (for failure)." (let (pass-cons) - (if (setq pass-cons (assoc user-at-host elmo-passwd-alist)) + (if (setq pass-cons (assoc key elmo-passwd-alist)) (progn (unwind-protect (fillarray (cdr pass-cons) 0)) @@ -1513,21 +1507,43 @@ Otherwise treat \\ in NEWTEXT string as special: (and (eq (car diff) 0) (< diff-time (nth 1 diff))))) -(defun elmo-open-network-stream (name buffer host service ssl) + +(defun elmo-get-network-stream-type (stream-type) + (let ((ali elmo-network-stream-type-alist) + entry) + (while ali + (when (eq (car (cdr (car ali))) stream-type) + (setq entry (car ali) + ali nil)) + (setq ali (cdr ali))) + entry)) + +(defmacro elmo-network-stream-type-spec-string (stream-type) + (` (nth 0 (, stream-type)))) + +(defmacro elmo-network-stream-type-symbol (stream-type) + (` (nth 1 (, stream-type)))) + +(defmacro elmo-network-stream-type-feature (stream-type) + (` (nth 2 (, stream-type)))) + +(defmacro elmo-network-stream-type-function (stream-type) + (` (nth 3 (, stream-type)))) + +(defun elmo-open-network-stream (name buffer host service stream-type) (let ((auto-plugged (and elmo-auto-change-plugged (> elmo-auto-change-plugged 0))) process) - (if (eq ssl 'starttls) - (require 'starttls) - (if ssl (require 'ssl))) + (if (and stream-type + (elmo-network-stream-type-feature stream-type)) + (require (elmo-network-stream-type-feature stream-type))) (condition-case err (let (process-connection-type) (setq process - (if (eq ssl 'starttls) - (starttls-open-stream name buffer host service) - (if ssl - (open-ssl-stream name buffer host service) - (open-network-stream name buffer host service))))) + (if stream-type + (funcall (elmo-network-stream-type-function stream-type) + name buffer host service) + (open-network-stream name buffer host service)))) (error (when auto-plugged (elmo-set-plugged nil host service (current-time)) diff --git a/elmo/elmo-vars.el b/elmo/elmo-vars.el index 019f441..cf86d48 100644 --- a/elmo/elmo-vars.el +++ b/elmo/elmo-vars.el @@ -47,16 +47,17 @@ "*Default IMAP4 mailbox.") (defvar elmo-default-imap4-server "localhost" "*Default IMAP4 server.") -(defvar elmo-default-imap4-authenticate-type "auth" - "*Default Authentication type for IMAP4.") ; "auth" or "login" +(defvar elmo-default-imap4-authenticate-type 'login + "*Default Authentication type for IMAP4.") (defvar elmo-default-imap4-user (or (getenv "USER") (getenv "LOGNAME") (user-login-name)) "*Default username for IMAP4.") (defvar elmo-default-imap4-port 143 "*Default Port number of IMAP.") -(defvar elmo-default-imap4-ssl nil - "*Non-nil forces using SSL by default.") +(defvar elmo-default-imap4-stream-type nil + "*Default stream type for IMAP4. +Any symbol value of `elmo-network-stream-type-alist'.") ;; POP3 (defvar elmo-default-pop3-user (or (getenv "USER") @@ -69,8 +70,9 @@ "*Default Authentication type for POP3.") ; "apop" or "user" (defvar elmo-default-pop3-port 110 "*Default POP3 port.") -(defvar elmo-default-pop3-ssl nil - "*Non-nil forces using SSL by default.") +(defvar elmo-default-pop3-stream-type nil + "*Default stream type for POP3. +Any symbol value of `elmo-network-stream-type-alist'.") ;; NNTP (defvar elmo-default-nntp-server "localhost" @@ -79,8 +81,9 @@ "*Default User of NNTP. nil means no user authentication.") (defvar elmo-default-nntp-port 119 "*Default Port number of NNTP.") -(defvar elmo-default-nntp-ssl nil - "*Non-nil forces using SSL by default.") +(defvar elmo-default-nntp-stream-type nil + "*Default stream type for NNTP. +Any symbol value of `elmo-network-stream-type-alist'.") ;; Local (defvar elmo-localdir-folder-path "~/Mail" @@ -253,6 +256,18 @@ If function, return value of function.") (?| . pipe) (?. . maildir))) +(defvar elmo-network-stream-type-alist + '(("!" ssl ssl open-ssl-stream) + ("!!" starttls starttls starttls-open-stream) + ("!socks" socks socks socks-open-network-stream)) + "An alist of (SPEC-STRING SYMBOL FEATURE OPEN-STREAM-FUNCTION). +SPEC-STRING is a string for stream-type spec (it must start with '!'). +SYMBOL is a symbol which indicates the name of the stream type. +SYMBOL should be identical in this alist. +FEATURE is a symbol of the feature for OPEN-STREAM-FUNCTION. +OPEN-STREAM-FUNCTION is a function to open network stream. +Arguments for this function are NAME, BUFFER, HOST and SERVICE.") + (defvar elmo-debug nil) (defconst mmelmo-entity-buffer-name "*MMELMO-BUFFER*") -- 1.7.10.4