1 ;; mew.el --- Messaging in the Emacs World
3 ;; Author: Kazu Yamamoto <Kazu@Mew.org>
4 ;; Created: Mar 23, 1994
5 ;; Revised: Feb 28, 1999
9 ;; The updated version is available from:
10 ;; ftp://ftp.Mew.org/pub/Mew/mew-current.tar.gz
11 ;; http://www.Mew.org/
14 ;; (autoload 'mew "mew" nil t)
15 ;; (autoload 'mew-send "mew" nil t)
16 ;; (setq mew-mail-domain-list '("your mail domain"))
17 ;; (setq mew-icon-directory "icon directory")
19 ;; Optional setup (e.g. for C-xm):
20 ;; (autoload 'mew-user-agent-compose "mew" nil t)
21 ;; (if (boundp 'mail-user-agent)
22 ;; (setq mail-user-agent 'mew-user-agent))
23 ;; (if (fboundp 'define-mail-user-agent)
24 ;; (define-mail-user-agent
26 ;; 'mew-user-agent-compose
27 ;; 'mew-draft-send-letter
33 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
38 (defconst mew-version-number "1.94.2"
39 "Version number for this version of Mew.")
40 (defconst mew-version (format "Mew version %s" mew-version-number)
41 "Version string for this version of Mew.")
46 (defun mew-version-show ()
47 "Show mew-version in minibuffer."
49 (message "%s" mew-version))
51 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
56 (defvar mew-debug nil)
57 ;;(setq mew-debug nil)
60 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
66 (defun mew (&optional arg)
67 "Execute Mew. If 'mew-auto-get' is 't', messages stored in your
68 spool are fetched to the +inbox folder and messages in the +inbox
69 folder are listed up in Summary mode. If 'mew-auto-get' is 'nil', list
70 up messages in the inbox folder. If '\\[universal-argument]' is specified, perform this
71 function thinking that 'mew-auto-get' is reversed."
74 (if (null mew-mail-path) (mew-init))
75 (let ((auto (if arg (not mew-auto-get) mew-auto-get)))
78 (mew-summary-goto-folder t (mew-inbox-folder)))))
81 (defun mew-send (&optional to cc subject)
82 "Execute Mew then prepare a draft. This may be used as library
85 (mew-current-set 'window (current-window-configuration))
86 (if (null mew-mail-path) (mew-init))
87 (mew-summary-send to cc subject))
90 (defun mew-user-agent-compose (&optional to subject other-headers continue
91 switch-function yank-action
93 "Set up mail composition draft with Mew.
94 This is 'mail-user-agent' entry point to Mew.
96 The optional arguments TO and SUBJECT specify recipients and the
97 initial Subject field, respectively.
99 OTHER-HEADERS is an alist specifying additional
100 header fields. Elements look like (HEADER . VALUE) where both
101 HEADER and VALUE are strings.
103 A Draft buffer is prepared according to SWITCH-FUNCTION.
105 CONTINUE, YANK-ACTION and SEND-ACTIONS are ignored."
106 (if (null mew-mail-path) (mew-init))
107 (let* ((draft (mew-folder-new-message mew-draft-folder))
108 (attachdir (mew-attachdir draft)))
109 (mew-current-set 'window (current-window-configuration))
110 (mew-window-configure (current-buffer) 'draft)
111 (mew-summary-prepare-draft
113 (let ((special-display-buffer-names nil)
114 (special-display-regexps nil)
115 (same-window-buffer-names nil)
116 (same-window-regexps nil))
117 (funcall switch-function (find-file-noselect draft)))
118 (switch-to-buffer (find-file-noselect draft)))
119 (mew-draft-rename draft)
120 (mew-delete-directory-recursively attachdir)
121 (mew-draft-header subject nil to nil nil nil nil other-headers)
123 (run-hooks 'mew-draft-mode-newdraft-hook))))
126 ;;; Functions for boot time
131 (message "Setting Mew world ...")
132 (run-hooks 'mew-env-hook)
133 (mew-set-environment)
134 (run-hooks 'mew-init-hook)
135 (mew-status-update t)
137 (if (get-buffer mew-buffer-hello) (kill-buffer mew-buffer-hello))
138 (message "Setting Mew world ... done"))
140 (defun mew-set-environment (&optional no-dir)
146 ((string-match "^18" emacs-version)
147 (setq error-message "Not support Emacs 18 nor Mule 1\n")
149 ((null mew-mail-domain-list)
150 (setq error-message "Must set 'mew-mail-domain-list'")
152 ;; initialize IM variables
153 (if (setq error-message (mew-config-init)) (error ""))
155 (or no-dir (mew-buffers-init))
156 (or no-dir (mew-temp-dir-init))
160 (set-buffer mew-buffer-hello)
161 (goto-char (point-max))
162 (insert "\n\nMew errors:\n\n")
163 (and error-message (insert error-message))
164 (set-buffer-modified-p nil)
165 (setq buffer-read-only t)
166 ;; cause an error again
167 (error "Mew found some errors above.")))))
169 (defun mew-status-update (arg)
170 "Read Addrbook and update its information. If executed with '\\[universal-argument]',
171 information of folders is also updated in addition to that of
172 Addrbook. If 'mew-use-folders-file-p' is 't', the list of
173 folders is stored in '~/Mail/.folders'. The default value is 't'."
175 (message "Updating status ... ")
176 (if (interactive-p) (mew-set-environment 'no-dir))
177 (if arg (mew-folder-setup nil (interactive-p)))
179 (mew-pgp-set-version)
180 (mew-highlight-face-setup mew-highlight-header-face-list)
181 (mew-highlight-face-setup mew-highlight-body-face-list)
182 (mew-highlight-face-setup mew-highlight-mark-face-list)
183 (mew-highlight-make-keywords-regex)
185 (message "Updating status ... done"))
187 (defun mew-uniq-variables ()
188 (setq mew-mime-content-type-list (mew-uniq-list mew-mime-content-type-list)))
190 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
195 (defvar mew-mail-path nil)
196 (defvar mew-news-path nil)
197 (defvar mew-queue-path nil)
198 (defvar mew-inbox-folder nil)
199 (defvar mew-draft-folder nil)
200 (defvar mew-addrbook-file nil)
201 (defvar mew-alias-file nil)
202 (defvar mew-petname-file nil)
203 (defvar mew-trash-folder nil)
204 (defvar mew-imap-account nil)
205 (defvar mew-config-cases nil)
206 (defvar mew-config-case-inbox nil)
208 (defvar mew-path-alist
209 '(("MailPath" . mew-mail-path)
210 ("NewsPath" . mew-news-path)
211 ("QueuePath" . mew-queue-path)
212 ("InboxFolder" . mew-inbox-folder)
213 ("DraftFolder" . mew-draft-folder)
214 ("TrashFolder" . mew-trash-folder)
215 ("AddrBookFile" . mew-addrbook-file)
216 ("AliasFile" . mew-alias-file)
217 ("PetnameFile" . mew-petname-file)
218 ("ImapAccount" . mew-imap-account)
219 ("ConfigCases" . mew-config-cases)
220 ("ConfigCaseInbox" . mew-config-case-inbox)))
222 (defvar mew-draft-mime-folder nil)
224 (defmacro mew-config-error (var key)
225 (` (if (null (, var))
226 (setq errmsg (concat errmsg "\t" (, key)
227 " was NOT found in Config.\n")))))
229 (defun mew-config-init ()
231 (if (not (mew-which mew-prog-impath exec-path))
232 (format "%s is not found in 'exec-path'" mew-prog-impath)
233 (mew-im-call-process nil mew-prog-impath "--path=yes")
234 (goto-char (point-min))
235 (let (key value pair)
237 (if (looking-at "^\\([^=\n]+\\)=\\(.+\\)$")
238 ;; Petname may be null string.
240 (setq key (mew-match 1))
241 (setq value (mew-match 2))
242 (if (setq pair (mew-assoc-match2 key mew-path-alist 0))
243 (set (cdr pair) value))))
246 (setq mew-config-list (mew-split mew-config-cases ?,))
247 (setq mew-config-list (list mew-config-default)))
248 (if mew-config-case-inbox
250 (setq mew-config-case-inbox (mew-split mew-config-case-inbox ?,))
251 (while mew-config-case-inbox
252 (setq tmp (cons (mew-split (car mew-config-case-inbox) ?:) tmp))
253 (setq mew-config-case-inbox (cdr mew-config-case-inbox)))
254 (setq mew-config-case-inbox (nreverse tmp))))
256 (mew-config-error mew-mail-path "MailDir")
257 (mew-config-error mew-news-path "NewsDir")
258 (mew-config-error mew-inbox-folder "InboxFolder")
259 (mew-config-error mew-draft-folder "DraftFolder")
260 (mew-config-error mew-trash-folder "TrashFolder")
262 errmsg ;; return value
263 ;; xxx hard coding... +draft/mime
264 (setq mew-draft-mime-folder
265 (concat (file-name-as-directory mew-draft-folder) "mime"))
266 (mew-config-set-modes (list mew-mail-path mew-news-path))
267 (mew-config-create-folders (cons mew-draft-folder
268 (cons mew-trash-folder
269 (mew-inbox-folders))))
270 nil)))) ;; return value
272 (defun mew-config-set-modes (dirs)
275 (setq dir (file-chase-links (car dirs)))
276 (setq dirs (cdr dirs))
277 (if (file-exists-p dir)
278 (if (/= mew-folder-mode (mew-file-get-mode dir))
279 (set-file-modes dir mew-folder-mode))))))
281 (defun mew-config-create-folders (folders)
284 (setq target (mew-expand-folder (car folders)))
285 (if (file-exists-p target)
287 (mew-make-directory target)
288 (message "%s was created" target))
289 (setq folders (cdr folders)))))
291 (defun mew-config-clean-up ()
292 (setq mew-mail-path nil)
293 (setq mew-news-path nil)
294 (setq mew-queue-path nil)
295 ;; (setq mew-inbox-folder nil)
296 (setq mew-draft-folder nil)
297 (setq mew-petname-file nil)
298 (setq mew-trash-folder nil)
299 (setq mew-imap-account nil)
300 (setq mew-config-cases nil))
302 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
307 (defvar mew-folder-list nil)
308 (defvar mew-folder-alist nil)
310 (defun mew-folder-setup (&optional new-folder interactivep)
313 (if (mew-folder-member new-folder mew-folder-list)
315 (setq mew-folder-list (sort (cons new-folder mew-folder-list)
316 (function mew-string<)))
317 (setq mew-folder-alist (mew-folder-make-alist mew-folder-list))))
319 (setq mew-folder-list (mew-folder-make-list interactivep))
320 (setq mew-folder-alist (mew-folder-make-alist mew-folder-list)))))
322 (defun mew-folder-delete (folder)
323 (setq mew-folder-list (delete folder mew-folder-list))
324 (setq mew-folder-alist (delq (assoc folder mew-folder-alist)
327 (defun mew-folder-clean-up ()
328 (setq mew-folder-list nil)
329 (setq mew-folder-alist nil))
331 (defun mew-folder-make-list (updatep)
333 (let ((case-fold-search t)
337 (file (expand-file-name mew-folders-file mew-mail-path)))
341 mew-use-folders-file-p
342 (file-readable-p file))
343 (insert-file-contents file))
345 (mapcar (function (lambda (x) (insert x "\n")))
346 (nconc (funcall mew-folder-list-function "+")
347 (funcall mew-folder-list-function "=")))
349 (mew-folder-mail-to-imap))
350 (if mew-use-folders-file-p
351 (write-region (point-min) (point-max) file nil 'no-msg))))
352 (goto-char (point-min))
355 (if (not (or (looking-at "[+=]")
356 (and mew-use-imap (looking-at "%"))))
359 (setq folder (mew-buffer-substring start (1- (point))))
360 (if (and (car folders)
361 (string-match (concat "^" (regexp-quote
362 (file-name-as-directory
365 ;; regexp-quote is not necessary since not "+".
368 (cons (file-name-as-directory (car folders))
370 (setq folders (cons folder folders)))))
371 (sort (nreverse folders) (function mew-string<)))))
373 (defun mew-folder-mail-to-imap ()
374 (goto-char (point-min))
376 (while (re-search-forward "^+@[^#]+#[^/]+/\\(.*\\)$" nil t)
377 (replace-match (concat "%" (mew-match 1))))))
379 (defmacro mew-folder-make-alist (list)
380 (` (mapcar (function mew-folder-pair) (, list))))
382 (defun mew-folder-pair (folder)
383 (let* ((dir (directory-file-name (mew-folder-to-dir folder)))
384 ;; foo/bar -> foo/bar
385 ;; foo/bar/ -> foo/bar
386 (subdir (file-name-nondirectory dir)))
389 (if (mew-folders-ignore-p folder)
391 (list folder subdir))))
393 (defun mew-folders-ignore-p (folder)
394 (let ((ignores mew-folders-ignore))
396 ;; while always returns nil
398 (if (string-match (concat "^" (car ignores)) folder)
400 (setq ignores (cdr ignores))))))
402 (defun mew-string< (a b)
403 (let ((case-fold-search nil) (ret (string< a b)))
404 (if (or (string-match (concat "^" (regexp-quote a)) b)
405 (string-match (concat "^" (regexp-quote b)) a))
409 (defun mew-inbox-folder ()
411 ((string= mew-config-imget mew-config-default);; this may be lengthy
413 ((assoc mew-config-imget mew-config-case-inbox)
414 (nth 1 (assoc mew-config-imget mew-config-case-inbox)))
418 (defun mew-inbox-folders ()
419 (if (null mew-config-case-inbox)
420 (list mew-inbox-folder)
421 (let ((inboxes (mapcar (function (lambda (x) (nth 1 x)))
422 mew-config-case-inbox)))
423 (if (member mew-inbox-folder inboxes)
425 (cons mew-inbox-folder inboxes)))))
427 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
429 ;;; Window configuration stack
432 (defvar mew-window-stack nil)
434 (defun mew-window-clean-up ()
435 (setq mew-window-stack nil))
437 (defun mew-window-push ()
438 (let ((frame (selected-frame))
439 (config (current-window-configuration)))
440 (setq mew-window-stack (cons (cons frame config) mew-window-stack))))
442 (defun mew-window-pop ()
443 (let* ((frame (selected-frame))
444 (assoc (assoc frame mew-window-stack)))
445 (if (and assoc (window-configuration-p (cdr assoc)))
446 (set-window-configuration (cdr assoc))
447 (switch-to-buffer (get-buffer-create mew-window-home-buffer)))
448 (setq mew-window-stack (delete assoc mew-window-stack))))
454 (defun mew-buffer-message ()
459 (mew-member-case-equal
462 (frame-parameters (selected-frame))))
464 (mapcar (function (lambda (frame)
465 (cdr (assq 'window-id
466 (frame-parameters frame)))))
468 (function string<)))))
472 ;;; Window configuration
475 (defun mew-window-configure (nbuf action)
476 ;;; action : summary, message, draft or list
477 ;;; list for action (1 0) for Summary only
478 ;;; list for action (3 10) for Summary and Message
482 (car (cdr (assq action mew-window-configuration)))))
483 (obufwin (get-buffer-window (current-buffer)))
484 (msgwin (get-buffer-window (mew-buffer-message)))
485 (height nil) (winsum nil) (sum-height 0) (msg-height 0))
486 (setq height (+ (if obufwin (window-height obufwin) 0)
487 (if msgwin (window-height msgwin) 0)))
488 (if (or mew-window-use-full
489 (<= height (* 2 window-min-height)))
491 ;; Delete other windows and use full emacs window.
492 (delete-other-windows)
493 (setq height (window-height (selected-window)))))
494 (if (get-buffer (mew-buffer-message))
495 (delete-windows-on (mew-buffer-message))
497 (set-buffer (get-buffer-create (mew-buffer-message)))
498 ;; "truncate?" is asked in Message mode.
499 ;; so set the same toolbar as Sumamry mode
500 (mew-summary-toolbar-update)
502 (setq winsum (apply (function +) windows))
503 (if (not (zerop (nth 0 windows)))
504 (setq sum-height (max window-min-height
505 (/ (* height (nth 0 windows)) winsum))))
506 (if (and (equal action 'message) (equal (% sum-height 2) 1))
507 (setq sum-height (1+ sum-height)))
508 (if (not (zerop (nth 1 windows)))
509 (setq msg-height (max window-min-height
510 (- height sum-height))))
511 (setq height (+ sum-height msg-height))
512 (if (null (zerop sum-height))
513 (switch-to-buffer nbuf 'norecord))
514 (if (zerop msg-height)
516 (split-window nil sum-height)
518 (switch-to-buffer (mew-buffer-message) 'norecord))))
520 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
525 (defvar mew-buffers nil)
527 (defun mew-buffers-init ()
528 (setq mew-buffers (mew-inbox-folders))) ;; for quiting
530 (defun mew-buffers-setup (folder)
531 (if (not (mew-folder-member folder mew-buffers))
532 (setq mew-buffers (cons folder mew-buffers))))
534 (defun mew-buffers-bury ()
535 (let ((buffers mew-buffers))
537 (if (get-buffer (car buffers))
538 (bury-buffer (car buffers)))
539 (setq buffers (cdr buffers)))))
541 (defun mew-buffers-clean-up ()
543 (if (get-buffer (car mew-buffers))
544 (mew-kill-buffer (car mew-buffers)))
545 (setq mew-buffers (cdr mew-buffers)))
548 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
550 ;;; Temporary directory
553 (defvar mew-temp-dir nil) ;; the default is "/tmp/user_name_uniq"
554 (defvar mew-temp-file nil) ;; the default is "/tmp/user_name_uniq/mew"
556 (defun mew-temp-dir-init ()
557 "Setting temporary directory for Mew.
558 mew-temp-file must be local and readable for the user only
559 for privacy/speed reasons. "
560 (setq mew-temp-dir (make-temp-name mew-temp-file-initial))
561 (mew-make-directory mew-temp-dir)
562 (set-file-modes mew-temp-dir mew-folder-mode)
563 (setq mew-temp-file (expand-file-name "mew" mew-temp-dir))
564 (add-hook 'kill-emacs-hook (function mew-temp-dir-clean-up)))
566 (defun mew-temp-dir-clean-up ()
567 "A function to remove Mew's temporary directory recursively.
568 It is typically called by kill-emacs-hook."
569 (remove-hook 'kill-emacs-hook (function mew-temp-dir-clean-up))
570 (if (and mew-temp-dir (file-exists-p mew-temp-dir))
571 (mew-delete-directory-recursively mew-temp-dir))
572 (setq mew-temp-dir nil)
573 (setq mew-temp-file nil))
575 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
580 (defun mew-bury-buffer (&optional buf)
582 (delete-windows-on buf t))
584 (defun mew-kill-buffer (&optional buf)
585 "Erase the current mode(buffer)."
587 (let* ((buf (or buf (current-buffer)))
588 (folder (if (bufferp buf) (buffer-name buf) buf)))
589 (if (eq major-mode 'mew-virtual-mode)
590 (mew-folder-delete folder))
591 (if (and (eq major-mode 'mew-summary-mode)
592 (mew-folder-remotep folder))
593 (mew-remote-folder-cache-delete folder))
598 (mew-overlay-delete-buffer))
599 (kill-buffer buf)))))
601 (defun mew-buffer-message-clean-up (func)
603 (let ((bl (buffer-list))
604 (regexp (concat "^" (regexp-quote mew-buffer-message)))
609 (if (and (setq bn (buffer-name b))
610 (string-match regexp bn))
612 (funcall func (mew-buffer-message))))
614 (defun mew-buffer-draft-clean-up ()
615 (let ((bl (buffer-list))
616 (regexp (concat "^" (regexp-quote mew-draft-folder)))
621 (if (and (setq bn (buffer-name b))
622 (string-match regexp bn)
623 (equal 'mew-draft-mode
627 (mew-kill-buffer b)))))
630 (defmacro mew-quit-toolbar-update ()
631 '(if (fboundp 'redraw-frame) ;; for BOW
632 (redraw-frame (selected-frame)))) ;; update toolbar
634 (defun mew-summary-suspend ()
635 "Suspend Mew then switch to another buffer. All buffers of
636 Mew remain, so you can resume with buffer operations."
638 (mew-buffer-message-clean-up (function mew-bury-buffer))
641 (mew-quit-toolbar-update)
642 (run-hooks 'mew-suspend-hook))
644 (defun mew-summary-quit ()
645 "Quit Mew. All buffers of Mew are erased."
647 (if (not (y-or-n-p "Quit Mew? "))
650 (mew-buffer-message-clean-up (function mew-kill-buffer)) ;; Message mode
651 (mew-buffer-draft-clean-up) ;; Draft mode
653 (mapcar (function mew-kill-buffer) mew-buffer-list) ;; other buffers
656 (mew-buffers-clean-up) ;; Summary mode and Virtual mode
657 (mew-temp-dir-clean-up)
659 (run-hooks 'mew-quit-hook)
661 ;; lastly, clean up variables
663 (mew-folder-clean-up)
664 (mew-current-clean-up)
665 (mew-addrbook-clean-up)
666 (mew-passwd-clean-up)
669 (mew-window-clean-up)
670 (mew-quit-toolbar-update)
672 (mew-config-clean-up) ;; MUST be last
676 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
678 ;;; Load Mew libraries
680 (require 'mew-addrbook)
681 (require 'mew-complete)
682 (require 'mew-minibuf)
684 (require 'mew-encode)
685 (require 'mew-decode)
688 (require 'mew-header)
691 (require 'mew-syntax)
694 (require 'mew-summary)
695 (require 'mew-virtual)
696 (require 'mew-message)
698 (require 'mew-attach)
700 (require 'mew-refile)
704 (require 'mew-highlight)
706 ;;; Copyright Notice:
708 ;; Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999 Mew developing team.
709 ;; All rights reserved.
711 ;; Redistribution and use in source and binary forms, with or without
712 ;; modification, are permitted provided that the following conditions
715 ;; 1. Redistributions of source code must retain the above copyright
716 ;; notice, this list of conditions and the following disclaimer.
717 ;; 2. Redistributions in binary form must reproduce the above copyright
718 ;; notice, this list of conditions and the following disclaimer in the
719 ;; documentation and/or other materials provided with the distribution.
720 ;; 3. Neither the name of the team nor the names of its contributors
721 ;; may be used to endorse or promote products derived from this software
722 ;; without specific prior written permission.
724 ;; THIS SOFTWARE IS PROVIDED BY THE TEAM AND CONTRIBUTORS ``AS IS'' AND
725 ;; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
726 ;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
727 ;; PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE TEAM OR CONTRIBUTORS BE
728 ;; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
729 ;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
730 ;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
731 ;; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
732 ;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
733 ;; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
734 ;; IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.