- (setq process
- (apply #'start-process "pgg-gpg" buffer pgg-gpg-program args)))
- (set-default-file-modes orig-mode))
- (set-process-filter process #'pgg-gpg-process-filter)
- (set-process-sentinel process #'pgg-gpg-process-sentinel)
- process))
-
-(defun pgg-gpg-process-filter (process input)
- (save-excursion
- (if pgg-gpg-debug
- (save-excursion
- (set-buffer (get-buffer-create " *pgg-gpg-debug*"))
- (goto-char (point-max))
- (insert input)))
- (set-buffer (process-buffer process))
- (goto-char (point-max))
- (insert input)
- (goto-char pgg-gpg-read-point)
- (beginning-of-line)
- (while (looking-at ".*\n") ;the input line is finished
- (save-excursion
- (if (looking-at "\\[GNUPG:] \\([A-Z_]+\\)\\>.*")
- (let* ((status (match-string 1))
- (symbol (intern-soft (concat "pgg-gpg-status-" status)))
- (entry (member status pgg-gpg-pending-status-list)))
- (if entry
- (setq pgg-gpg-pending-status-list
- (delq (car entry)
- pgg-gpg-pending-status-list)))
- (if (and symbol
- (fboundp symbol))
- (funcall symbol process (buffer-substring (match-beginning 1)
- (match-end 0)))))))
- (forward-line))
- (setq pgg-gpg-read-point (point))))
-
-(defun pgg-gpg-process-sentinel (process status)
- (set-process-filter process nil)
- (save-excursion
- ;; Copy the contents of process-buffer to pgg-errors-buffer.
- (set-buffer (get-buffer-create pgg-errors-buffer))
- (buffer-disable-undo)
- (erase-buffer)
- (when (buffer-live-p (process-buffer process))
- (insert-buffer-substring (process-buffer process))
- (goto-char (point-min))
- (delete-matching-lines "^\\[GNUPG:] ")
- (goto-char (point-min))
- (while (re-search-forward "^gpg: " nil t)
- (replace-match "")))
- ;; Read the contents of the output file to pgg-output-buffer.
- (set-buffer (get-buffer-create pgg-output-buffer))
- (buffer-disable-undo)
- (erase-buffer)
- (if (and (equal status "finished\n")
- (buffer-live-p (process-buffer process)))
- (let ((output-file-name (with-current-buffer (process-buffer process)
- pgg-gpg-output-file-name)))
- (when (file-exists-p output-file-name)
- (let ((coding-system-for-read (if pgg-text-mode
- 'raw-text
- 'binary)))
- (insert-file-contents output-file-name))
- (delete-file output-file-name))))))
-
-(defun pgg-gpg-wait-for-status (process status-list)
- (with-current-buffer (process-buffer process)
- (setq pgg-gpg-pending-status-list status-list)
- (while (and (eq (process-status process) 'run)
- pgg-gpg-pending-status-list)
- (accept-process-output process 1))))
-
-(defun pgg-gpg-wait-for-completion (process &optional status-list)
- (process-send-eof process)
- (while (eq (process-status process) 'run)
- (sit-for 0.1))
- (save-excursion
- (set-buffer (process-buffer process))
- (setq status-list (copy-sequence status-list))
- (let ((pointer status-list))
- (while pointer
+ (let ((coding-system-for-write 'binary))
+ (setq process
+ (apply #'start-process "*GnuPG*" errors-buffer
+ program args)))
+ (set-process-sentinel process #'ignore)
+ (when passphrase
+ (setq passphrase-with-newline (concat passphrase "\n"))
+ (if pgg-passphrase-coding-system
+ (progn
+ (setq encoded-passphrase-with-new-line
+ (encode-coding-string
+ passphrase-with-newline
+ (coding-system-change-eol-conversion
+ pgg-passphrase-coding-system 'unix)))
+ (pgg-clear-string passphrase-with-newline))
+ (setq encoded-passphrase-with-new-line passphrase-with-newline
+ passphrase-with-newline nil))
+ (process-send-string process encoded-passphrase-with-new-line))
+ (process-send-region process start end)
+ (process-send-eof process)
+ (while (eq 'run (process-status process))
+ (accept-process-output process 5))
+ ;; Accept any remaining pending output coming after the
+ ;; status change.
+ (accept-process-output process 5)
+ (setq status (process-status process)
+ exit-status (process-exit-status process))
+ (delete-process process)
+ (with-current-buffer (get-buffer-create output-buffer)
+ (buffer-disable-undo)
+ (erase-buffer)
+ (if (file-exists-p output-file-name)
+ (let ((coding-system-for-read (if pgg-text-mode
+ 'raw-text
+ 'binary)))
+ (insert-file-contents output-file-name)))
+ (set-buffer errors-buffer)
+ (if (memq status '(stop signal))
+ (error "%s exited abnormally: '%s'" program exit-status))
+ (if (= 127 exit-status)
+ (error "%s could not be found" program))))
+ (if passphrase-with-newline
+ (pgg-clear-string passphrase-with-newline))
+ (if encoded-passphrase-with-new-line
+ (pgg-clear-string encoded-passphrase-with-new-line))
+ (if (and process (eq 'run (process-status process)))
+ (interrupt-process process))
+ (if (file-exists-p output-file-name)
+ (delete-file output-file-name))
+ (set-default-file-modes orig-mode))))
+
+(defun pgg-gpg-possibly-cache-passphrase (passphrase &optional key notruncate)
+ (if (and passphrase
+ pgg-cache-passphrase
+ (progn
+ (goto-char (point-min))
+ (re-search-forward "^\\[GNUPG:] \\(GOOD_PASSPHRASE\\>\\)\\|\\(SIG_CREATED\\)" nil t)))
+ (pgg-add-passphrase-to-cache
+ (or key
+ (progn
+ (goto-char (point-min))
+ (if (re-search-forward
+ "^\\[GNUPG:] NEED_PASSPHRASE\\(_PIN\\)? \\w+ ?\\w*" nil t)
+ (substring (match-string 0) -8))))
+ passphrase
+ notruncate)))
+
+(defvar pgg-gpg-all-secret-keys 'unknown)
+
+(defun pgg-gpg-lookup-all-secret-keys ()
+ "Return all secret keys present in secret key ring."
+ (when (eq pgg-gpg-all-secret-keys 'unknown)
+ (setq pgg-gpg-all-secret-keys '())
+ (let ((args (list "--with-colons" "--no-greeting" "--batch"
+ "--list-secret-keys")))
+ (with-temp-buffer
+ (apply #'call-process pgg-gpg-program nil t nil args)