2000-08-21 Yuuichi Teranishi <teranisi@gohome.org>
authorteranisi <teranisi>
Mon, 21 Aug 2000 06:39:56 +0000 (06:39 +0000)
committerteranisi <teranisi>
Mon, 21 Aug 2000 06:39:56 +0000 (06:39 +0000)
* 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  <ueno@unixuser.org>

* 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
elmo/elmo-dop.el
elmo/elmo-imap4.el
elmo/elmo-nntp.el
elmo/elmo-pop3.el
elmo/elmo-util.el
elmo/elmo-vars.el

index 1fcf75f..ee6ab9c 100644 (file)
@@ -1,3 +1,67 @@
+2000-08-21  Yuuichi Teranishi  <teranisi@gohome.org>
+
+       * 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  <ueno@unixuser.org>
+
+       * 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 <okada@opaopa.org>
 
        * elmo-maildir.el (elmo-maildir-delete-folder): Set argument of the
index 2bf02e9..1e1e56f 100644 (file)
@@ -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")))
index cadc05a..f490479 100644 (file)
 (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)))
index e6dd617..a0e3f31 100644 (file)
@@ -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) 
index 4343105..628799e 100644 (file)
         (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)
        (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
        (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))
     (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) 
index 4693a79..e79bcee 100644 (file)
 (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))
index 019f441..cf86d48 100644 (file)
   "*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*")