gnus-notifications: add actions support
[gnus] / lisp / sieve-manage.el
index 574f319..74bcbcc 100644 (file)
@@ -1,7 +1,6 @@
-;;; sieve-manage.el --- Implementation of the managesive protocol in elisp
+;;; sieve-manage.el --- Implementation of the managesieve protocol in elisp
 
-;; Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007,
-;;   2008, 2009, 2010  Free Software Foundation, Inc.
+;; Copyright (C) 2001-2012  Free Software Foundation, Inc.
 
 ;; Author: Simon Josefsson <simon@josefsson.org>
 
 ;;
 ;; and that's it.  Example of a managesieve session in *scratch*:
 ;;
+;; (with-current-buffer (sieve-manage-open "mail.example.com")
+;;   (sieve-manage-authenticate)
+;;   (sieve-manage-listscripts))
 ;;
-;; (sieve-manage-listscripts my-buf)
-;; ("vacation" "testscript" ("splitmail") "badscript")
+;; => ((active . "main") "vacation")
 ;;
 ;; References:
 ;;
@@ -68,7 +69,7 @@
 
 ;;; Code:
 
-;; For Emacs < 22.2.
+;; For Emacs <22.2 and XEmacs.
 (eval-and-compile
   (unless (fboundp 'declare-function) (defmacro declare-function (&rest r))))
 
   (require 'password))
 
 (eval-when-compile
+  (require 'cl)                                ; caddr
   (require 'sasl)
   (require 'starttls))
 (autoload 'sasl-find-mechanism "sasl")
 (autoload 'starttls-open-stream "starttls")
-(autoload 'auth-source-user-or-password "auth-source")
+(autoload 'auth-source-search "auth-source")
 
 ;; User customizable variables:
 
@@ -148,13 +150,14 @@ for doing the actual authentication."
   :group 'sieve-manage)
 
 (defcustom sieve-manage-default-port 2000
-  "Default port number for managesieve protocol."
+  "Default port number or service name for managesieve protocol."
   :type 'integer
   :group 'sieve-manage)
 
 (defcustom sieve-manage-default-stream 'network
   "Default stream type to use for `sieve-manage'.
 Must be a name of a stream in `sieve-manage-stream-alist'."
+  :version "24.1"
   :type 'symbol
   :group 'sieve-manage)
 
@@ -271,16 +274,21 @@ Valid states are `closed', `initial', `nonauth', and `auth'.")
   "Login to server using the SASL MECH method."
   (message "sieve: Authenticating using %s..." mech)
   (with-current-buffer buffer
-    (let* ((user-password (auth-source-user-or-password
-                           '("login" "password")
-                           sieve-manage-server
-                           "sieve" nil t))
+    (let* ((auth-info (auth-source-search :host sieve-manage-server
+                                          :port "sieve"
+                                          :max 1
+                                          :create t))
+           (user-name (or (plist-get (nth 0 auth-info) :user) ""))
+           (user-password (or (plist-get (nth 0 auth-info) :secret) ""))
+           (user-password (if (functionp user-password)
+                              (funcall user-password)
+                            user-password))
            (client (sasl-make-client (sasl-find-mechanism (list mech))
-                                     (car user-password) "sieve" sieve-manage-server))
+                                     user-name "sieve" sieve-manage-server))
            (sasl-read-passphrase
             ;; We *need* to copy the password, because sasl will modify it
             ;; somehow.
-            `(lambda (prompt) ,(copy-sequence (cadr user-password))))
+            `(lambda (prompt) ,(copy-sequence user-password)))
            (step (sasl-next-step client nil))
            (tag (sieve-manage-send
                  (concat
@@ -387,13 +395,14 @@ Optional argument AUTH indicates authenticator to use, see
 If nil, chooses the best stream the server is capable of.
 Optional argument BUFFER is buffer (buffer, or string naming buffer)
 to work in."
-  (setq buffer (or buffer (format " *sieve* %s:%d" server (or port sieve-manage-default-port))))
+  (or port (setq port sieve-manage-default-port))
+  (setq buffer (or buffer (format " *sieve* %s:%s" server port)))
   (with-current-buffer (get-buffer-create buffer)
     (mapc 'make-local-variable sieve-manage-local-variables)
     (sieve-manage-disable-multibyte)
     (buffer-disable-undo)
     (setq sieve-manage-server (or server sieve-manage-server))
-    (setq sieve-manage-port (or port sieve-manage-port))
+    (setq sieve-manage-port port)
     (setq sieve-manage-stream (or stream sieve-manage-stream))
     (message "sieve: Connecting to %s..." sieve-manage-server)
     (if (let ((sieve-manage-stream
@@ -444,6 +453,17 @@ to work in."
       (sieve-manage-erase)
       buffer)))
 
+(defun sieve-manage-authenticate (&optional buffer)
+  "Authenticate on server in BUFFER.
+Return `sieve-manage-state' value."
+  (with-current-buffer (or buffer (current-buffer))
+    (if (eq sieve-manage-state 'nonauth)
+        (when (funcall (nth 2 (assq sieve-manage-auth
+                                    sieve-manage-authenticator-alist))
+                       (current-buffer))
+          (setq sieve-manage-state 'auth))
+      sieve-manage-state)))
+
 (defun sieve-manage-opened (&optional buffer)
   "Return non-nil if connection to managesieve server in BUFFER is open.
 If BUFFER is nil then the current buffer is used."