From: yamaoka Date: Mon, 6 Nov 2000 22:12:15 +0000 (+0000) Subject: Synch with Gnus. X-Git-Tag: t-gnus-6_14-quimby-before-installer-changed-~9 X-Git-Url: http://git.chise.org/gitweb/?a=commitdiff_plain;h=dcc7995bdd8abe90717199b263b1abf3a4ab942d;p=elisp%2Fgnus.git- Synch with Gnus. --- diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 0ae7df3..13aa3e6 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,34 @@ +2000-11-06 16:02:52 ShengHuo ZHU + + * mm-uu.el (mm-uu-gpg-key-skip-to-last): New function. + (mm-uu-pgp-key-extract): Use application/pgp-keys, don't snarf, + let mailcap do it. + * mml2015.el: Remove snarf code. + * mm-decode.el: Remove snarf code. + +2000-11-06 14:03:10 ShengHuo ZHU + + * mml.el (mml-insert-mml-markup): Ignore internal stuff. + (mml-insert-mime): Understand gnus-decoded. + (mime-to-mml): New parameter handles. + * gnus-art.el (gnus-mime-save-part-and-strip): Use it. + * gnus-sum.el (gnus-summary-edit-article): Add argument `3'. + +2000-11-06 13:51:37 ShengHuo ZHU + + * mm-decode.el (mime-security): New group. + (mm-verify-function-alist): Add test function. + (mm-decrypt-function-alist): Ditto. + (mm-snarf-option): Set default value as nil. + (mm-find-part-by-type): Recursive parameter. + (mm-possibly-verify-or-decrypt): Support draft-ietf-openpgp-multsig. + * mml2015.el: Support draft-ietf-openpgp-multsig. + +2000-11-06 13:01:27 ShengHuo ZHU + + * gnus-art.el (gnus-mime-view-part-as-charset): New function. + (gnus-article-view-part-as-charset): New function. + 2000-11-05 22:34:07 ShengHuo ZHU * mm-decode.el (mm-verify-option): Default value. diff --git a/lisp/gnus-art.el b/lisp/gnus-art.el index d56b864..ac0821a 100644 --- a/lisp/gnus-art.el +++ b/lisp/gnus-art.el @@ -694,6 +694,7 @@ used." ("view the part" . gnus-mime-view-part) ("pipe to command" . gnus-mime-pipe-part) ("toggle display" . gnus-article-press-button) + ("toggle display" . gnus-article-view-part-as-charset) ("view as type" . gnus-mime-view-part-as-type) ("internalize type" . gnus-mime-internalize-part) ("externalize type" . gnus-mime-externalize-part)) @@ -3290,6 +3291,7 @@ value of the variable `gnus-show-mime' is non-nil." '((gnus-article-press-button "\r" "Toggle Display") (gnus-mime-view-part "v" "View Interactively...") (gnus-mime-view-part-as-type "t" "View As Type...") + (gnus-mime-view-part-as-charset "C" "View As charset...") (gnus-mime-save-part "o" "Save...") (gnus-mime-save-part-and-strip "\C-o" "Save and Strip") (gnus-mime-copy-part "c" "View As Text, In Other Buffer") @@ -3377,21 +3379,9 @@ value of the variable `gnus-show-mime' is non-nil." (or gnus-article-ignored-charsets ',gnus-newsgroup-ignored-charsets)) (mbl mml-buffer-list)) - (insert-buffer gnus-original-article-buffer) - (save-restriction - (message-narrow-to-head) - (message-remove-header "Content-Type") - (message-remove-header "MIME-Version") - (message-remove-header "Content-Transfer-Encoding") - (mail-decode-encoded-word-region (point-min) (point-max)) - (goto-char (point-max))) - (forward-char 1) - (delete-region (point) (point-max)) (setq mml-buffer-list nil) - (if (stringp (car gnus-article-mime-handles)) - (mml-insert-mime gnus-article-mime-handles) - (mml-insert-mime gnus-article-mime-handles t)) - (mm-destroy-parts gnus-article-mime-handles) + (insert-buffer gnus-original-article-buffer) + (mime-to-mml gnus-article-mime-handles) (setq gnus-article-mime-handles nil) (make-local-hook 'kill-buffer-hook) (let ((mbl1 mml-buffer-list)) @@ -3496,7 +3486,7 @@ value of the variable `gnus-show-mime' is non-nil." contents charset (b (point)) buffer-read-only) - (if (mm-handle-undisplayer handle) + (if (and (not arg) (mm-handle-undisplayer handle)) (mm-remove-part handle) (setq contents (mm-get-part handle)) (cond @@ -3505,6 +3495,8 @@ value of the variable `gnus-show-mime' is non-nil." (mm-handle-type handle) 'charset) gnus-newsgroup-charset))) ((numberp arg) + (if (mm-handle-undisplayer handle) + (mm-remove-part handle)) (setq charset (or (cdr (assq arg gnus-summary-show-article-charset-alist)) @@ -3519,6 +3511,23 @@ value of the variable `gnus-show-mime' is non-nil." contents)) (goto-char b)))) +(defun gnus-mime-view-part-as-charset (&optional handle arg) + "Insert the MIME part under point into the current buffer." + (interactive (list nil current-prefix-arg)) + (gnus-article-check-buffer) + (let* ((handle (or handle (get-text-property (point) 'gnus-data))) + contents charset + (b (point)) + buffer-read-only) + (if (mm-handle-undisplayer handle) + (mm-remove-part handle)) + (let ((gnus-newsgroup-charset + (or (cdr (assq arg + gnus-summary-show-article-charset-alist)) + (read-coding-system "Charset: "))) + (gnus-newsgroup-ignored-charsets 'gnus-all)) + (gnus-article-press-button)))) + (defun gnus-mime-externalize-part (&optional handle) "View the MIME part under point with an external viewer." (interactive) @@ -3589,6 +3598,11 @@ In no internal viewer is available, use an external viewer." (interactive "p") (gnus-article-part-wrapper n 'gnus-mime-copy-part)) +(defun gnus-article-view-part-as-charset (n) + "Copy MIME part N, which is the numerical prefix." + (interactive "p") + (gnus-article-part-wrapper n 'gnus-mime-view-part-as-charset)) + (defun gnus-article-externalize-part (n) "View MIME part N externally, which is the numerical prefix." (interactive "p") diff --git a/lisp/gnus-sum.el b/lisp/gnus-sum.el index e1d3978..3541e54 100644 --- a/lisp/gnus-sum.el +++ b/lisp/gnus-sum.el @@ -1669,6 +1669,7 @@ increase the score of each group you read." "v" gnus-article-view-part "o" gnus-article-save-part "c" gnus-article-copy-part + "C" gnus-article-view-part-as-charset "e" gnus-article-externalize-part "i" gnus-article-inline-part "|" gnus-article-pipe-part)) diff --git a/lisp/mm-decode.el b/lisp/mm-decode.el index 17e63aa..9b48183 100644 --- a/lisp/mm-decode.el +++ b/lisp/mm-decode.el @@ -40,6 +40,13 @@ :group 'news :group 'multimedia) +(defgroup mime-security () + "MIME security in mail and news articles." + :link '(custom-manual "(emacs-mime)Customization") + :group 'mail + :group 'news + :group 'multimedia) + ;;; Convenience macros. (defmacro mm-handle-buffer (handle) @@ -230,12 +237,13 @@ to: (defvar mm-dissect-default-type "text/plain") (autoload 'mml2015-verify "mml2015") +(autoload 'mml2015-verify-test "mml2015") (autoload 'mml-smime-verify "mml-smime") (defvar mm-verify-function-alist - '(("application/pgp-signature" mml2015-verify "PGP") - ("application/pkcs7-signature" mml-smime-verify "S/MIME") - ("application/x-pkcs7-signature" mml-smime-verify "S/MIME"))) + '(("application/pgp-signature" mml2015-verify "PGP" mml2015-verify-test) + ("application/pkcs7-signature" mml-smime-verify "S/MIME" nil) + ("application/x-pkcs7-signature" mml-smime-verify "S/MIME" nil))) (defcustom mm-verify-option 'known "Option of verifying signed parts. @@ -245,12 +253,13 @@ to: (item never) (item :tag "only known protocols" known) (item :tag "ask" nil)) - :group 'gnus-article) + :group 'mime-security) (autoload 'mml2015-decrypt "mml2015") +(autoload 'mml2015-decrypt-test "mml2015") (defvar mm-decrypt-function-alist - '(("application/pgp-encrypted" mml2015-decrypt "PGP"))) + '(("application/pgp-encrypted" mml2015-decrypt "PGP" mml2015-decrypt-test))) (defcustom mm-decrypt-option 'known "Option of decrypting signed parts. @@ -260,17 +269,7 @@ to: (item never) (item :tag "only known protocols" known) (item :tag "ask" nil)) - :group 'gnus-article) - -(defcustom mm-snarf-option 'known - "Option of snarfing PGP key. -`never', not snarf; `always', always snarf; -`known', only snarf known protocols. Otherwise, ask user." - :type '(choice (item always) - (item never) - (item :tag "only known protocols" known) - (item :tag "ask" nil)) - :group 'gnus-article) + :group 'mime-security) (defvar mm-viewer-completion-map (let ((map (make-sparse-keymap 'mm-viewer-completion-map))) @@ -926,16 +925,21 @@ external if displayed external." (and (mm-valid-image-format-p format) (mm-image-fit-p handle))) -(defun mm-find-part-by-type (handles type &optional notp) +(defun mm-find-part-by-type (handles type &optional notp recursive) "Search in HANDLES for part with TYPE. -If NOTP, returns first non-matching part." +If NOTP, returns first non-matching part. +If RECURSIVE, search recursively." (let (handle) (while handles - (if (if notp - (not (equal (mm-handle-media-type (car handles)) type)) - (equal (mm-handle-media-type (car handles)) type)) - (setq handle (car handles) - handles nil)) + (if (and recursive (stringp (caar handles))) + (if (setq handle (mm-find-part-by-type (cdar handles) type + notp recursive)) + (setq handles nil)) + (if (if notp + (not (equal (mm-handle-media-type (car handles)) type)) + (equal (mm-handle-media-type (car handles)) type)) + (setq handle (car handles) + handles nil))) (setq handles (cdr handles))) handle)) @@ -982,23 +986,27 @@ If NOTP, returns first non-matching part." (defun mm-possibly-verify-or-decrypt (parts ctl) (let ((subtype (cadr (split-string (car ctl) "/"))) - protocol func) + protocol func functest) (cond ((equal subtype "signed") - (unless (setq protocol (mail-content-type-get ctl 'protocol)) - ;; The message is broken. - (let ((parts parts)) - (while parts - (if (assoc (mm-handle-media-type (car parts)) - mm-verify-function-alist) - (setq protocol (mm-handle-media-type (car parts)) - parts nil) - (setq parts (cdr parts)))))) + (unless (and (setq protocol (mail-content-type-get ctl 'protocol)) + (not (equal protocol "multipart/mixed"))) + ;; The message is broken or draft-ietf-openpgp-multsig-01. + (let ((protocols mm-verify-function-alist)) + (while protocols + (if (and (or (not (setq functest (nth 3 (car protocols)))) + (funcall functest parts ctl)) + (mm-find-part-by-type parts (caar protocols) nil t)) + (setq protocol (caar protocols) + protocols nil) + (setq protocols (cdr protocols)))))) (setq func (nth 1 (assoc protocol mm-verify-function-alist))) + (setq functest (nth 3 (assoc protocol mm-verify-function-alist))) (if (cond ((eq mm-verify-option 'never) nil) ((eq mm-verify-option 'always) t) - ((eq mm-verify-option 'known) func) + ((eq mm-verify-option 'known) + (and func (funcall functest parts ctl))) (t (y-or-n-p (format "Verify signed (%s) part? " (or (nth 2 (assoc protocol mm-verify-function-alist)) @@ -1022,10 +1030,12 @@ If NOTP, returns first non-matching part." parts nil) (setq parts (cdr parts)))))) (setq func (nth 1 (assoc protocol mm-decrypt-function-alist))) + (setq functest (nth 3 (assoc protocol mm-decrypt-function-alist))) (if (cond ((eq mm-decrypt-option 'never) nil) ((eq mm-decrypt-option 'always) t) - ((eq mm-decrypt-option 'known) func) + ((eq mm-decrypt-option 'known) + (and func (funcall functest parts ctl))) (t (y-or-n-p (format "Decrypt (%s) part? " (or (nth 2 (assoc protocol mm-decrypt-function-alist)) diff --git a/lisp/mm-uu.el b/lisp/mm-uu.el index a210b9c..47aa032 100644 --- a/lisp/mm-uu.el +++ b/lisp/mm-uu.el @@ -57,10 +57,10 @@ decoder, such as hexbin." (item :tag "external" binhex-decode-region-external)) :group 'gnus-article-mime) -(defvar mm-uu-pgp-begin-signature +(defvar mm-uu-pgp-beginning-signature "^-----BEGIN PGP SIGNATURE-----") -(defvar mm-uu-begin-line nil) +(defvar mm-uu-beginning-regexp nil) (defvar mm-dissect-disposition "inline" "The default disposition of uu parts. @@ -115,8 +115,8 @@ This can be either \"inline\" or \"attachment\".") "^-----BEGIN PGP PUBLIC KEY BLOCK-----" "^-----END PGP PUBLIC KEY BLOCK-----" mm-uu-pgp-key-extract - nil - mm-uu-pgp-key-test))) + mm-uu-gpg-key-skip-to-last + nil))) (defcustom mm-uu-configure-list nil "A list of mm-uu configuration. @@ -136,7 +136,7 @@ To disable dissecting shar codes, for instance, add (defsubst mm-uu-type (entry) (car entry)) -(defsubst mm-uu-begin-regexp (entry) +(defsubst mm-uu-beginning-regexp (entry) (nth 1 entry)) (defsubst mm-uu-end-regexp (entry) @@ -164,14 +164,14 @@ To disable dissecting shar codes, for instance, add (defun mm-uu-configure (&optional symbol value) (if symbol (set-default symbol value)) - (setq mm-uu-begin-line nil) + (setq mm-uu-beginning-regexp nil) (mapcar (lambda (entry) (if (mm-uu-configure-p (mm-uu-type entry) 'disabled) nil - (setq mm-uu-begin-line - (concat mm-uu-begin-line - (if mm-uu-begin-line "\\|") - (mm-uu-begin-regexp entry))))) + (setq mm-uu-beginning-regexp + (concat mm-uu-beginning-regexp + (if mm-uu-beginning-regexp "\\|") + (mm-uu-beginning-regexp entry))))) mm-uu-type-alist)) (mm-uu-configure) @@ -270,7 +270,7 @@ To disable dissecting shar codes, for instance, add (goto-char (point-min)) (if (search-forward "\n\n" nil t) (delete-region (point-min) (point))) - (if (re-search-forward mm-uu-pgp-begin-signature nil t) + (if (re-search-forward mm-uu-pgp-beginning-signature nil t) (delete-region (match-beginning 0) (point-max)))) (mm-make-handle buf '("text/plain" (charset . gnus-decoded))))) @@ -299,22 +299,22 @@ To disable dissecting shar codes, for instance, add (mm-make-handle buf '("text/plain" (charset . gnus-decoded))))) -(defun mm-uu-pgp-key-test () - (and - mml2015-use - (mml2015-clear-snarf-function) - (cond - ((eq mm-snarf-option 'never) nil) - ((eq mm-snarf-option 'always) t) - ((eq mm-snarf-option 'known) t) - (t (y-or-n-p "Snarf pgp signed part?"))))) +(defun mm-uu-gpg-key-skip-to-last () + (let ((point (point)) + (end-regexp (mm-uu-end-regexp entry)) + (beginning-regexp (mm-uu-beginning-regexp entry))) + (when (and end-regexp + (not (mm-uu-configure-p (mm-uu-type entry) 'disabled))) + (while (re-search-forward end-regexp nil t) + (skip-chars-forward " \t\n\r") + (if (looking-at beginning-regexp) + (setq point (match-end 0))))) + (goto-char point))) (defun mm-uu-pgp-key-extract () (let ((buf (mm-uu-copy-to-buffer start-point end-point))) - (with-current-buffer buf - (funcall (mml2015-clear-snarf-function))) (mm-make-handle buf - '("application/x-pgp-key")))) + '("application/pgp-keys")))) ;;;### autoload (defun mm-uu-dissect () @@ -334,23 +334,24 @@ To disable dissecting shar codes, for instance, add ;;; decoding. (setq text-start (point) text-plain-type '("text/plain" (charset . gnus-decoded))) - (while (re-search-forward mm-uu-begin-line nil t) + (while (re-search-forward mm-uu-beginning-regexp nil t) (setq start-point (match-beginning 0)) (let ((alist mm-uu-type-alist) - (begin-line (match-string 0))) + (beginning-regexp (match-string 0))) (while (not entry) - (if (string-match (mm-uu-begin-regexp (car alist)) begin-line) + (if (string-match (mm-uu-beginning-regexp (car alist)) + beginning-regexp) (setq entry (car alist)) (pop alist)))) (if (setq func (mm-uu-function-1 entry)) (funcall func)) (forward-line);; in case of failure (when (and (not (mm-uu-configure-p (mm-uu-type entry) 'disabled)) - (let ((end-line (mm-uu-end-regexp entry))) - (if (not end-line) + (let ((end-regexp (mm-uu-end-regexp entry))) + (if (not end-regexp) (or (setq end-point (point-max)) t) (prog1 - (re-search-forward end-line nil t) + (re-search-forward end-regexp nil t) (forward-line) (setq end-point (point))))) (or (not (setq func (mm-uu-function-2 entry))) diff --git a/lisp/mml.el b/lisp/mml.el index 589988c..0d8facf 100644 --- a/lisp/mml.el +++ b/lisp/mml.el @@ -541,20 +541,22 @@ If MML is non-nil, return the buffer up till the correspondent mml tag." ;;; Transforming MIME to MML ;;; -(defun mime-to-mml () - "Translate the current buffer (which should be a message) into MML." +(defun mime-to-mml (&optional handles) + "Translate the current buffer (which should be a message) into MML. +If HANDLES is non-nil, use it instead reparsing the buffer." ;; First decode the head. (save-restriction (message-narrow-to-head) (mail-decode-encoded-word-region (point-min) (point-max))) - (let ((handles (mm-dissect-buffer t))) - (goto-char (point-min)) - (search-forward "\n\n" nil t) - (delete-region (point) (point-max)) - (if (stringp (car handles)) - (mml-insert-mime handles) - (mml-insert-mime handles t)) - (mm-destroy-parts handles)) + (unless handles + (setq handles (mm-dissect-buffer t))) + (goto-char (point-min)) + (search-forward "\n\n" nil t) + (delete-region (point) (point-max)) + (if (stringp (car handles)) + (mml-insert-mime handles) + (mml-insert-mime handles t)) + (mm-destroy-parts handles) (save-restriction (message-narrow-to-head) ;; Remove them, they are confusing. @@ -595,10 +597,11 @@ If MML is non-nil, return the buffer up till the correspondent mml tag." (mapcar 'mml-insert-mime (cdr handle)) (insert "<#/multipart>\n")) (textp - (let ((text (mm-get-part handle)) - (charset (mail-content-type-get + (let ((charset (mail-content-type-get (mm-handle-type handle) 'charset))) - (insert (mm-decode-string text charset))) + (if (eq charset 'gnus-decoded) + (mm-insert-part handle) + (insert (mm-decode-string (mm-get-part handle) charset)))) (goto-char (point-max))) (t (insert "<#/part>\n"))))) @@ -613,7 +616,8 @@ If MML is non-nil, return the buffer up till the correspondent mml tag." (insert "<#part type=" (mm-handle-media-type handle))) (dolist (elem (append (cdr (mm-handle-type handle)) (cdr (mm-handle-disposition handle)))) - (insert " " (symbol-name (car elem)) "=\"" (cdr elem) "\"")) + (unless (symbolp (cdr elem)) + (insert " " (symbol-name (car elem)) "=\"" (cdr elem) "\""))) (when (mm-handle-disposition handle) (insert " disposition=" (car (mm-handle-disposition handle)))) (when buffer diff --git a/lisp/mml2015.el b/lisp/mml2015.el index e4bf3d9..46385b1 100644 --- a/lisp/mml2015.el +++ b/lisp/mml2015.el @@ -48,15 +48,13 @@ mml2015-mailcrypt-verify mml2015-mailcrypt-decrypt mml2015-mailcrypt-clear-verify - mml2015-mailcrypt-clear-decrypt - mml2015-mailcrypt-clear-snarf) + mml2015-mailcrypt-clear-decrypt) (gpg mml2015-gpg-sign mml2015-gpg-encrypt mml2015-gpg-verify mml2015-gpg-decrypt nil - mml2015-gpg-clear-decrypt - nil)) + mml2015-gpg-clear-decrypt)) "Alist of PGP/MIME functions.") (defvar mml2015-result-buffer nil) @@ -69,8 +67,7 @@ (autoload 'mc-pgp-always-sign "mailcrypt") (autoload 'mc-encrypt-generic "mc-toplev") (autoload 'mc-cleanup-recipient-headers "mc-toplev") - (autoload 'mc-sign-generic "mc-toplev") - (autoload 'mc-snarf-keys "mc-toplev")) + (autoload 'mc-sign-generic "mc-toplev")) (eval-when-compile (defvar mc-default-scheme) @@ -78,12 +75,12 @@ (defvar mml2015-decrypt-function 'mailcrypt-decrypt) (defvar mml2015-verify-function 'mailcrypt-verify) -(defvar mml2015-snarf-function 'mc-snarf-keys) (defun mml2015-mailcrypt-decrypt (handle ctl) (let (child handles result) - (unless (setq child (mm-find-part-by-type (cdr handle) - "application/octet-stream")) + (unless (setq child (mm-find-part-by-type + (cdr handle) + "application/octet-stream" nil t)) (error "Corrupted pgp-encrypted part.")) (with-temp-buffer (mm-insert-part child) @@ -111,7 +108,9 @@ (defun mml2015-mailcrypt-verify (handle ctl) (let (part) (unless (setq part (mm-find-raw-part-by-type - ctl "application/pgp-signature" t)) + ctl (or (mail-content-type-get ctl 'protocol) + "application/pgp-signature") + t)) (error "Corrupted pgp-signature part.")) (with-temp-buffer (insert "-----BEGIN PGP SIGNED MESSAGE-----\n") @@ -122,7 +121,7 @@ (insert part "\n") (goto-char (point-max)) (unless (setq part (mm-find-part-by-type - (cdr handle) "application/pgp-signature")) + (cdr handle) "application/pgp-signature" nil t)) (error "Corrupted pgp-signature part.")) (mm-insert-part part) (unless (funcall mml2015-verify-function) @@ -133,9 +132,6 @@ (unless (funcall mml2015-verify-function) (error "Verify error."))) -(defun mml2015-mailcrypt-clear-snarf () - (funcall mml2015-snarf-function)) - (defun mml2015-mailcrypt-sign (cont) (mc-sign-generic (message-options-get 'message-sender) nil nil nil nil) @@ -245,7 +241,9 @@ (defun mml2015-gpg-verify (handle ctl) (let (part message signature) (unless (setq part (mm-find-raw-part-by-type - ctl "application/pgp-signature" t)) + ctl (or (mail-content-type-get ctl 'protocol) + "application/pgp-signature") + t)) (error "Corrupted pgp-signature part.")) (with-temp-buffer (setq message (current-buffer)) @@ -253,7 +251,7 @@ (with-temp-buffer (setq signature (current-buffer)) (unless (setq part (mm-find-part-by-type - (cdr handle) "application/pgp-signature")) + (cdr handle) "application/pgp-signature" nil t)) (error "Corrupted pgp-signature part.")) (mm-insert-part part) (unless (gpg-verify message signature mml2015-result-buffer) @@ -339,9 +337,6 @@ (gnus-get-buffer-create "*MML2015 Result*")) nil)) -(defsubst mml2015-clear-snarf-function () - (nth 7 (assq mml2015-use mml2015-function-alist))) - (defsubst mml2015-clear-decrypt-function () (nth 6 (assq mml2015-use mml2015-function-alist))) @@ -357,6 +352,10 @@ handle))) ;;;###autoload +(defun mml2015-decrypt-test (handle ctl) + mml2015-use) + +;;;###autoload (defun mml2015-verify (handle ctl) (mml2015-clean-buffer) (let ((func (nth 3 (assq mml2015-use mml2015-function-alist)))) @@ -365,6 +364,10 @@ handle))) ;;;###autoload +(defun mml2015-verify-test (handle ctl) + mml2015-use) + +;;;###autoload (defun mml2015-encrypt (cont) (mml2015-clean-buffer) (let ((func (nth 2 (assq mml2015-use mml2015-function-alist))))