1 ;;; wl-acap.el -- ACAP support for Wanderlust.
3 ;; Copyright (C) 2001 Yuuichi Teranishi <teranisi@gohome.org>
5 ;; Author: Yuuichi Teranishi <teranisi@gohome.org>
6 ;; Keywords: mail, net news
8 ;; This file is part of Wanderlust (Yet Another Message Interface on Emacsen).
10 ;; This program is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
15 ;; This program is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU Emacs; see the file COPYING. If not, write to the
22 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.
40 ((and (featurep 'xemacs)
41 (module-installed-p 'xemacs-ucs))
42 (require 'xemacs-ucs))
43 ((module-installed-p 'un-define)
44 (require 'un-define))))
46 (defconst wl-acap-dataset-class "vendor.wanderlust")
47 (defconst wl-acap-entry-name "settings")
49 (defcustom wl-acap-user (or (getenv "USER")
56 (defcustom wl-acap-server nil
58 If nil, SLP is used to find ACAP server.
59 If nil and SLP is not available, localhost is assumed."
63 (defcustom wl-acap-port nil
65 Only valid when `wl-acap-server' is non-nil.
66 If nil, default acap port is used."
70 (defcustom wl-acap-authenticate-type 'cram-md5
71 "ACAP authenticate type."
75 (defcustom wl-acap-stream-type nil
80 (defcustom wl-acap-extra-options nil
81 "Extra options to be saved on ACAP server."
82 :type '(repeat symbol)
85 ;; Encoding string as BASE64 is temporal solution.
86 ;; As far as I know, current implementation of ACAP server
87 ;; (cyrus-smlacapd 0.5) does not accept literal argument for STORE.
88 (defvar wl-acap-base64-encode-options
90 wl-draft-config-alist)
91 "Options which should be encoded with base64 to store ACAP server.")
93 (defcustom wl-acap-coding-system 'utf-8
94 "Coding system for ACAP."
98 (defun wl-acap-init ()
99 "A candidate for `wl-folder-init-function'."
100 (let ((service (wl-acap-find-acap-service))
101 proc entries settings folder-top type)
102 (setq proc (acap-open (car service)
104 (upcase (symbol-name wl-acap-authenticate-type))
106 (setq entries (acap-response-entries
107 (acap-search proc (concat "/"
108 wl-acap-dataset-class
112 (when (string= (acap-response-entry-entry (car entries))
114 (setq settings (car (acap-response-entry-return-data-list
117 (setq entries (cdr entries)))
122 (let ((sym (wl-acap-symbol (car x))))
124 ((and sym (eq sym 'wl-folders))
126 (setq wl-folder-entity
127 (wl-acap-create-folder-entity (cadr x)))
129 ((and sym (boundp sym))
130 (setq type (custom-variable-type sym))
135 ((or (eq (car type) 'string)
136 (and (eq (car type) 'choice)
137 (memq 'string type)))
138 (if (memq sym wl-acap-base64-encode-options)
139 (wl-acap-base64-decode-string (cadr x))
145 wl-acap-base64-encode-options)
146 (wl-acap-base64-decode-string (cadr x))
147 (read (concat "\"" (cadr x) "\""))))))))))
148 (t 'wl-acap-ignored))))
151 (dolist (setting settings)
152 (set (car setting) (cdr setting)))
153 ;; Database directory becomes specific to the ACAP server.
154 (setq elmo-msgdb-dir (expand-file-name
155 (concat "acap/" (car service) "/" wl-acap-user)
159 (defun wl-acap-create-folder-entity (string)
161 (message "Initializing folder...")
163 (setq string (elmo-base64-decode-string string))
164 (setq string (decode-coding-string string wl-acap-coding-system))
166 (goto-char (point-min))
167 (while (and (not (eobp))
168 (setq entity (wl-create-folder-entity-from-buffer)))
169 (unless (eq entity 'ignore)
170 (wl-append folders (list entity))))
171 (message "Initializing folder...done")
172 (list wl-folder-desktop-name 'group folders))))
174 (defun wl-acap-find-acap-service ()
175 (or (and wl-acap-server
176 (cons wl-acap-server wl-acap-port))
178 (message "Searching ACAP server...")
179 (prog1 (let ((response (condition-case nil
180 (slp-findsrvs "acap")
183 ;; Only the first service entry is used.
184 (setq response (car (slp-response-body response)))
185 (cons (slp-response-srv-url-host response)
186 (slp-response-srv-url-port response))))
187 (message "Searching ACAP server...done.")))
188 (cons "localhost" nil)))
190 (defun wl-acap-name (option)
191 (let ((name (symbol-name option))
193 (cond ((string-match "^wl-" name)
194 (setq name (substring name (match-end 0))
196 ((string-match "^elmo-" name)
197 (setq name (substring name (match-end 0))
200 wl-acap-dataset-class "." prefix "."
201 (mapconcat 'capitalize (split-string name "-") ""))))
203 (defun wl-acap-symbol (name)
204 (let (case-fold-search li)
205 (when (string-match (concat "^" (regexp-quote wl-acap-dataset-class)
206 "\\.\\([^\\.]+\\)\\.") name)
207 (setq li (list (match-string 1 name))
208 name (substring name (match-end 0)))
209 (while (string-match "^[A-Z][a-z0-9]*" name)
210 (setq li (cons (match-string 0 name) li))
211 (setq name (substring name (match-end 0))))
212 (intern (mapconcat 'downcase (nreverse li) "-")))))
214 (defun wl-acap-list-options ()
215 (nconc (mapcar 'car (append (custom-group-members 'wl-setting nil)
216 (custom-group-members 'elmo-setting nil)))
217 wl-acap-extra-options))
219 (defun wl-acap-store-folders (proc)
221 (insert-file-contents wl-folders-file)
224 (list (concat "/" wl-acap-dataset-class "/~/"
226 (concat wl-acap-dataset-class ".wl.Folders")
227 (wl-acap-base64-encode-string (buffer-string))))))
229 (defun wl-acap-base64-encode-string (string)
230 (elmo-base64-encode-string
231 (encode-coding-string string wl-acap-coding-system)
234 (defun wl-acap-base64-decode-string (string)
235 (decode-coding-string
236 (elmo-base64-decode-string string )
237 wl-acap-coding-system))
239 (defun wl-acap-store ()
240 "Store Wanderlust configuration to the ACAP server."
243 (let ((service (wl-acap-find-acap-service))
245 (setq proc (acap-open (car service)
247 (upcase (symbol-name wl-acap-authenticate-type))
249 (dolist (option (wl-acap-list-options))
251 (cons (wl-acap-name option) settings)
253 (cons (when (symbol-value option)
254 (setq type (custom-variable-type option))
256 ((or (eq (car type) 'string)
257 (and (eq (car type) 'choice)
258 (memq 'string type)))
259 (if (memq option wl-acap-base64-encode-options)
260 (wl-acap-base64-encode-string
261 (symbol-value option))
262 (symbol-value option)))
263 (t (if (memq option wl-acap-base64-encode-options)
264 (wl-acap-base64-encode-string
265 (prin1-to-string (symbol-value option)))
266 (prin1-to-string (symbol-value option))))))
270 (message "Storing settings...")
275 "/" wl-acap-dataset-class "/~/" wl-acap-entry-name))
276 (nreverse settings)))
277 (message "Storing folders...")
278 (wl-acap-store-folders proc))
281 (message "Store completed."))))
285 ;;; wl-acap.el ends here