* epg.el (epg--list-keys-1): Respect epg-gpg-home-directory.
[elisp/epg.git] / epg.el
diff --git a/epg.el b/epg.el
index 82d5cb6..6000dc5 100644 (file)
--- a/epg.el
+++ b/epg.el
 
 ;;; Code:
 
-(defgroup epg ()
-  "The EasyPG Library"
-  :group 'emacs)
-
-(defcustom epg-gpg-program "gpg"
-  "The `gpg' executable."
-  :group 'epg
-  :type 'string)
-
-(defcustom epg-gpgsm-program "gpgsm"
-  "The `gpgsm' executable."
-  :group 'epg
-  :type 'string)
-
-(defconst epg-version-number "0.0.3")
+(require 'epg-config)
 
 (defvar epg-user-id nil
   "GnuPG ID of your default identity.")
@@ -803,6 +789,8 @@ This function is for internal use only."
   (let* ((args (append (list "--no-tty"
                             "--status-fd" "1"
                             "--yes")
+                      (if epg-gpg-home-directory
+                          (list "--homedir" epg-gpg-home-directory))
                       (unless (eq (epg-context-protocol context) 'CMS)
                         (list "--command-fd" "0"))
                       (if (epg-context-armor context) '("--armor"))
@@ -870,19 +858,18 @@ This function is for internal use only."
                (goto-char epg-read-point)
                (beginning-of-line)
                (while (looking-at ".*\n") ;the input line finished
-                 (save-excursion
-                   (if (looking-at "\\[GNUPG:] \\([A-Z_]+\\) ?\\(.*\\)")
-                       (let* ((status (match-string 1))
-                              (string (match-string 2))
-                              (symbol (intern-soft (concat "epg--status-"
-                                                           status))))
-                         (if (member status epg-pending-status-list)
-                             (setq epg-pending-status-list nil))
-                         (if (and symbol
-                                  (fboundp symbol))
-                             (funcall symbol epg-context string)))))
-                 (forward-line))
-               (setq epg-read-point (point)))
+                 (if (looking-at "\\[GNUPG:] \\([A-Z_]+\\) ?\\(.*\\)")
+                     (let* ((status (match-string 1))
+                            (string (match-string 2))
+                            (symbol (intern-soft (concat "epg--status-"
+                                                         status))))
+                       (if (member status epg-pending-status-list)
+                           (setq epg-pending-status-list nil))
+                       (if (and symbol
+                                (fboundp symbol))
+                           (funcall symbol epg-context string))))
+                 (forward-line)
+                 (setq epg-read-point (point))))
            (setq epg-process-filter-running nil))))))
 
 (defun epg-read-output (context)
@@ -946,7 +933,8 @@ This function is for internal use only."
           (string-match "\\`passphrase\\." string))
       (let (inhibit-quit
            passphrase
-           passphrase-with-new-line)
+           passphrase-with-new-line
+           encoded-passphrase-with-new-line)
        (unwind-protect
            (condition-case nil
                (progn
@@ -961,10 +949,14 @@ This function is for internal use only."
                             (cdr (epg-context-passphrase-callback context)))))
                  (when passphrase
                    (setq passphrase-with-new-line (concat passphrase "\n"))
-                   (fillarray passphrase 0)
-                   (setq passphrase nil)
+                   (epg--clear-string passphrase)
+                   (setq passphrase nil
+                         encoded-passphrase-with-new-line
+                         (encode-coding-string passphrase-with-new-line
+                                               (terminal-coding-system)))
+                   
                    (process-send-string (epg-context-process context)
-                                        passphrase-with-new-line)))
+                                        encoded-passphrase-with-new-line)))
              (quit
               (epg-context-set-result-for
                context 'error
@@ -972,9 +964,11 @@ This function is for internal use only."
                      (epg-context-result-for context 'error)))
               (delete-process (epg-context-process context))))
          (if passphrase
-             (fillarray passphrase 0))
+             (epg--clear-string passphrase))
          (if passphrase-with-new-line
-             (fillarray passphrase-with-new-line 0))))))
+             (epg--clear-string passphrase-with-new-line))
+         (if encoded-passphrase-with-new-line
+             (epg--clear-string encoded-passphrase-with-new-line))))))
 
 (defun epg--status-GET_BOOL (context string)
   (let ((entry (assoc string epg-prompt-alist))
@@ -1306,28 +1300,10 @@ This function is for internal use only."
                                               handback)
   (message "%s: %d%%/%d%%" what current total))
 
-(defun epg-configuration ()
-  "Return a list of internal configuration parameters of `epg-gpg-program'."
-  (let (config type)
-    (with-temp-buffer
-      (apply #'call-process epg-gpg-program nil (list t nil) nil
-            '("--with-colons" "--list-config"))
-      (goto-char (point-min))
-      (while (re-search-forward "^cfg:\\([^:]+\\):\\(.*\\)" nil t)
-       (setq type (intern (match-string 1))
-             config (cons (cons type
-                                (if (memq type
-                                          '(pubkey cipher digest compress))
-                                    (mapcar #'string-to-number
-                                            (delete "" (split-string
-                                                        (match-string 2)
-                                                        ";")))
-                                  (match-string 2)))
-                          config))))
-    config))
-
 (defun epg--list-keys-1 (context name mode)
-  (let ((args (append (list "--with-colons" "--no-greeting" "--batch"
+  (let ((args (append (if epg-gpg-home-directory
+                         (list "--homedir" epg-gpg-home-directory))
+                     (list "--with-colons" "--no-greeting" "--batch"
                            "--with-fingerprint"
                            "--with-fingerprint"
                            (if (memq mode '(t secret))
@@ -1504,6 +1480,11 @@ You can then use `write-region' to write new data into the file."
             (file-directory-p tempdir)
             (delete-directory tempdir))))))
 
+(if (fboundp 'clear-string)
+    (defalias 'epg--clear-string 'clear-string)
+  (defun epg--clear-string (string)
+    (fillarray string 0)))
+
 ;;;###autoload
 (defun epg-cancel (context)
   (if (buffer-live-p (process-buffer (epg-context-process context)))
@@ -1782,9 +1763,13 @@ If you are unsure, use synchronous version of this function
                     (if sign
                         (cons "--sign"
                               (apply #'nconc
-                                     (mapcar (lambda (signer)
-                                               (list "-u" signer))
-                                             (epg-context-signers context)))))
+                                     (mapcar
+                                      (lambda (signer)
+                                        (list "-u"
+                                              (epg-sub-key-id
+                                               (car (epg-key-sub-key-list
+                                                     signer)))))
+                                      (epg-context-signers context)))))
                     (apply #'nconc
                            (mapcar
                             (lambda (recipient)