* epa.el (epa-sign-keys): New command.
authorueno <ueno>
Fri, 21 Apr 2006 06:41:55 +0000 (06:41 +0000)
committerueno <ueno>
Fri, 21 Apr 2006 06:41:55 +0000 (06:41 +0000)
* epg.el (epg-start-sign-keys): New function.
(epg-sign-keys): New function.
(epg-status-GET_HIDDEN): Enable local quit.
(epg-status-GET_BOOL): Ditto.
(epg-status-GET_LINE): Ditto.

ChangeLog
epa.el
epg.el

index f0ee038..1baf960 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2006-04-21  Daiki Ueno  <ueno@unixuser.org>
+
+       * epa.el (epa-sign-keys): New command.
+
+       * epg.el (epg-start-sign-keys): New function.
+       (epg-sign-keys): New function.
+       (epg-status-GET_HIDDEN): Enable local quit.
+       (epg-status-GET_BOOL): Ditto.
+       (epg-status-GET_LINE): Ditto.
+
 2006-04-20  Daiki Ueno  <ueno@unixuser.org>
 
        * epa.el (epa-list-keys-1): Add 'epa-list-keys property to keylist
diff --git a/epa.el b/epa.el
index 043ffd6..579fcf9 100644 (file)
--- a/epa.el
+++ b/epa.el
     (define-key keymap "d" 'epa-decrypt-file)
     (define-key keymap "v" 'epa-verify-file)
     (define-key keymap "s" 'epa-sign-file)
+    (define-key keymap "S" 'epa-sign-keys)
     (define-key keymap "e" 'epa-encrypt-file)
     (define-key keymap "r" 'epa-delete-keys)
     (define-key keymap "i" 'epa-import-keys)
     (define-key keymap "p" 'previous-line)
     (define-key keymap " " 'scroll-up)
     (define-key keymap [delete] 'scroll-down)
-    (define-key keymap "q" 'bury-buffer)
+    (define-key keymap "q" 'epa-exit-buffer)
     keymap))
 
+(defvar epa-exit-buffer-function #'bury-buffer)
+
 (define-widget 'epa-key 'push-button
   "Button for representing a epg-key object."
   :format "%[%v%]"
   ;; In XEmacs, auto-initialization of font-lock is not effective
   ;; if buffer-file-name is not set.
   (font-lock-set-defaults)
+  (make-local-variable 'epa-exit-buffer-function)
   (run-hooks 'epa-key-mode-hook))
 
 ;;;###autoload
          (nreverse keys)))
       (save-excursion
        (beginning-of-line)
-       (get-text-property (point) 'epa-key))))
+       (let ((key (get-text-property (point) 'epa-key)))
+         (if key
+             (list key))))))
 
 (defun epa-select-keys (prompt &optional names mode)
   (save-excursion
            (setq names (cdr names)))
        (epa-list-keys-1 nil mode))
       (epa-keys-mode)
+      (setq epa-exit-buffer-function #'abort-recursive-edit)
       (goto-char (point-min))
       (pop-to-buffer (current-buffer))
       (unwind-protect
   (interactive "P")
   (epa-mark (not arg)))
 
+(defun epa-exit-buffer ()
+  (interactive)
+  (funcall epa-exit-buffer-function))
+
 (defun epa-decrypt-file (file)
   (interactive "fFile: ")
   (let* ((default-name (file-name-sans-extension file))
@@ -521,6 +532,17 @@ If no one is selected, symmetric encryption will be performed.  ")))
     (epg-export-keys-to-file context keys file)
     (message "Exporting to %s...done" (file-name-nondirectory file))))
 
+(defun epa-sign-keys (keys &optional local)
+  (interactive
+   (let ((keys (epa-marked-keys)))
+     (unless keys
+       (error "No keys selected"))
+     (list keys current-prefix-arg)))
+  (let ((context (epg-make-context)))
+    (message "Signing keys...")
+    (epg-sign-keys context keys local)
+    (message "Signing keys...done")))
+
 (provide 'epa)
 
 ;;; epa.el ends here
diff --git a/epg.el b/epg.el
index 3ba189f..5245a57 100644 (file)
--- a/epg.el
+++ b/epg.el
@@ -552,35 +552,68 @@ This function is for internal use only."
 (defun epg-status-GET_HIDDEN (process string)
   (if (and epg-key-id
           (string-match "\\`passphrase\\." string))
-    (let ((passphrase
-          (funcall
-           (if (consp (epg-context-passphrase-callback epg-context))
-               (car (epg-context-passphrase-callback epg-context))
-             (epg-context-passphrase-callback epg-context))
-           epg-key-id
-           (if (consp (epg-context-passphrase-callback epg-context))
-               (cdr (epg-context-passphrase-callback epg-context)))))
-         string)
-      (if passphrase
-         (unwind-protect
-             (progn
-               (setq string (concat passphrase "\n"))
-               (fillarray passphrase 0)
-               (setq passphrase nil)
-               (process-send-string process string))
-           (if string
-               (fillarray string 0)))))))
+      (let (inhibit-quit
+           passphrase
+           passphrase-with-new-line)
+       (unwind-protect
+           (condition-case nil
+               (progn
+                 (setq passphrase
+                       (funcall
+                        (if (consp (epg-context-passphrase-callback
+                                    epg-context))
+                            (car (epg-context-passphrase-callback
+                                  epg-context))
+                          (epg-context-passphrase-callback epg-context))
+                        epg-key-id
+                        (if (consp (epg-context-passphrase-callback
+                                    epg-context))
+                            (cdr (epg-context-passphrase-callback
+                                  epg-context)))))
+                 (when passphrase
+                   (setq passphrase-with-new-line (concat passphrase "\n"))
+                   (fillarray passphrase 0)
+                   (setq passphrase nil)
+                   (process-send-string process passphrase-with-new-line)))
+             (quit
+              (epg-context-set-result-for
+               epg-context 'error
+               (cons 'quit
+                     (epg-context-result-for epg-context 'error)))
+              (delete-process process)))
+         (if passphrase
+             (fillarray passphrase 0))
+         (if passphrase-with-new-line
+             (fillarray passphrase-with-new-line 0))))))
 
 (defun epg-status-GET_BOOL (process string)
-  (let ((entry (assoc string epg-prompt-alist)))
-    (if (y-or-n-p (if entry (cdr entry) (concat string "? ")))
-       (process-send-string process "y\n")
-      (process-send-string process "n\n"))))
+  (let ((entry (assoc string epg-prompt-alist))
+       inhibit-quit)
+    (condition-case nil
+      (if (y-or-n-p (if entry (cdr entry) (concat string "? ")))
+         (process-send-string process "y\n")
+       (process-send-string process "n\n"))
+      (quit
+       (epg-context-set-result-for
+       epg-context 'error
+       (cons 'quit
+             (epg-context-result-for epg-context 'error)))
+       (delete-process process)))))
 
 (defun epg-status-GET_LINE (process string)
-  (let* ((entry (assoc string epg-prompt-alist))
-        (string (read-string (if entry (cdr entry) (concat string ": ")))))
-    (process-send-string process (concat string "\n"))))
+  (let ((entry (assoc string epg-prompt-alist))
+       inhibit-quit)
+    (condition-case nil
+       (process-send-string
+        process
+        (concat (read-string (if entry (cdr entry) (concat string ": ")))
+                "\n"))
+      (quit
+       (epg-context-set-result-for
+       epg-context 'error
+       (cons 'quit
+             (epg-context-result-for epg-context 'error)))
+       (delete-process process)))))
 
 (defun epg-status-GOODSIG (process string)
   (if (string-match "\\`\\([^ ]+\\) \\(.*\\)" string)
@@ -1254,7 +1287,8 @@ If you are unsure, use synchronous version of this function
        (epg-start-export-keys context keys)
        (epg-wait-for-completion context)
        (if (epg-context-result-for context 'error)
-           (error "Export keys failed"))
+           (error "Export keys failed: %S"
+                  (epg-context-result-for context 'error)))
        (unless file
          (epg-read-output context)))
     (unless file
@@ -1292,7 +1326,8 @@ If you are unsure, use synchronous version of this function
            (epg-flush context))
        (epg-wait-for-completion context)
        (if (epg-context-result-for context 'error)
-           (error "Import keys failed"))
+           (error "Import keys failed: %S"
+                  (epg-context-result-for context 'error)))
        (epg-read-output context))
     (epg-reset context)))
 
@@ -1330,10 +1365,42 @@ If you are unsure, use synchronous version of this function
   "Delete KEYS from the key ring."
   (unwind-protect
       (progn
-       (epg-start-delete-keys context keys)
+       (epg-start-delete-keys context keys allow-secret)
+       (epg-wait-for-completion context)
+       (if (epg-context-result-for context 'error)
+           (error "Delete keys failed: %S"
+                  (epg-context-result-for context 'error))))
+    (epg-reset context)))
+
+;;;###autoload
+(defun epg-start-sign-keys (context keys &optional local)
+  "Initiate an sign keys operation.
+
+If you use this function, you will need to wait for the completion of
+`epg-gpg-program' by using `epg-wait-for-completion' and call
+`epg-reset' to clear a temporaly output file.
+If you are unsure, use synchronous version of this function
+`epg-sign-keys' instead."
+  (epg-context-set-result context nil)
+  (epg-start context (cons (if local
+                              "--lsign-key"
+                            "--sign-key")
+                          (mapcar
+                           (lambda (key)
+                             (epg-sub-key-id
+                              (car (epg-key-sub-key-list key))))
+                           keys))))
+
+;;;###autoload
+(defun epg-sign-keys (context keys &optional local)
+  "Sign KEYS from the key ring."
+  (unwind-protect
+      (progn
+       (epg-start-sign-keys context keys local)
        (epg-wait-for-completion context)
        (if (epg-context-result-for context 'error)
-           (error "Delete key failed")))
+           (error "Sign keys failed: %S"
+                  (epg-context-result-for context 'error))))
     (epg-reset context)))
 
 (provide 'epg)