* epa.el (epa-display-info): Delete "*Info*" window.
[elisp/epg.git] / epg-pgp50i.el
index 08f0c04..2341670 100644 (file)
@@ -22,8 +22,6 @@
     ("Signature by unknown keyid: " .
      "UNKNOWN_SIGNATURE")))
 
-(defvar epg-pgp50i-status nil)
-
 (defun epg-pgp50i--start (context program args)
   (let ((args (append '("--headers" "--language=us")
                      (if (epg-context-armor context) '("--armor"))
     (with-current-buffer buffer
       (make-local-variable 'epg-read-point)
       (setq epg-read-point (point-min))
+      (make-local-variable 'epg-process-filter-running)
+      (setq epg-process-filter-running nil)
       (make-local-variable 'epg-pending-status-list)
       (setq epg-pending-status-list nil)
       (make-local-variable 'epg-key-id)
       (setq epg-key-id nil)
       (make-local-variable 'epg-context)
-      (setq epg-context context)
-      (make-local-variable 'epg-pgp50i-status)
-      (setq epg-pgp50i-status nil))
+      (setq epg-context context))
     (unwind-protect
        (progn
          (set-default-file-modes 448)
        (set-buffer (process-buffer process))
        (goto-char (point-max))
        (insert input)
-       (unless epg-pgp50i-status
-         (goto-char epg-read-point)
-         (while (not (eobp))
-           (save-excursion
-             (if (looking-at
-                  "\\(PRI\\|INF\\|QRY\\|STA\\|WRN\\|ERR\\):  \\(.*\\)")
-                 (let ((message (match-string 2))
-                       (pointer epg-pgp50i-message-alist)
-                       status symbol)
-                   (while pointer
-                     (if (string-match (car (car pointer)) message)
-                         (setq status (cdr (car pointer))
-                               pointer nil))
-                     (setq pointer (cdr pointer)))
-                   (when status
-                     (unless (looking-at ".*\n")
-                       (end-of-line)
-                       (insert "\n"))
-                     (if (member status epg-pending-status-list)
-                         (setq epg-pending-status-list nil))
-                     (setq symbol (intern-soft (concat "epg-pgp50i--status-"
-                                                       status)))
-                     (if (and symbol
-                              (fboundp symbol))
-                         (unwind-protect
-                             (progn
-                               (setq epg-pgp50i-status status)
-                               (funcall symbol epg-context message))
-                           (setq epg-pgp50i-status nil)))))))
-           (forward-line)
-           (setq epg-read-point (point)))))))
-
-(defun epg-pgp50i--wait-for-line (context)
+       (unless epg-process-filter-running
+         (unwind-protect
+             (progn
+               (setq epg-process-filter-running t)
+               (goto-char epg-read-point)
+               (while (not (eobp))
+                 (if (looking-at
+                      "^\\(PRI\\|INF\\|QRY\\|STA\\|WRN\\|ERR\\):  \\(.*\\)")
+                     (let ((message (match-string 2))
+                           (pointer epg-pgp50i-message-alist)
+                           status symbol)
+                       (while pointer
+                         (if (string-match (car (car pointer)) message)
+                             (setq status (cdr (car pointer))
+                                   pointer nil))
+                         (setq pointer (cdr pointer)))
+                       (when status
+                         (unless (looking-at ".*\n")
+                           (end-of-line)
+                           (insert "\n"))
+                         (if (member status epg-pending-status-list)
+                             (setq epg-pending-status-list nil))
+                         (setq symbol (intern-soft (concat
+                                                    "epg-pgp50i--status-"
+                                                    status)))
+                         (if (and symbol
+                                  (fboundp symbol))
+                             (funcall symbol epg-context message)))))
+                 (forward-line)
+                 (setq epg-read-point (point))))
+           (setq epg-process-filter-running nil))))))
+
+(defun epg-pgp50i--read-line (context)
   (if (eq (process-status (epg-context-process context)) 'run)
       (save-excursion
        (set-buffer (process-buffer (epg-context-process context)))
+       (forward-line)
        (goto-char epg-read-point)
-       (beginning-of-line 2)
-       (while (and (eq (process-status (epg-context-process context)) 'run)
-                   (not (if (looking-at ".*\n")
-                            (setq epg-read-point (point)))))
-         (accept-process-output (epg-context-process context) 1))
-       (buffer-substring (point) (progn (end-of-line) (point))))))
+       (if (looking-at ".*\n")
+           (buffer-substring (point) (progn (end-of-line) (point)))))))
 
 (defun epg-pgp50i--status-ENTER_PASSPHRASE (context message)
   (epg--status-GET_HIDDEN context "passphrase."))
 
 (defun epg-pgp50i--read-key (context)
-  (let ((line (epg-pgp50i--wait-for-line context))
+  (let ((line (epg-pgp50i--read-line context))
        key-id user-id-list)
     (when (and line
               (string-match "[ 0-9]+ bits, Key ID \\([0-9A-F]+\\)" line))
       (setq key-id (match-string 1 line))
-      (when (and (setq line (epg-pgp50i--wait-for-line context))
-                (string-match "\"\\([^\"]+\\)\"" line))
+      (while (and (setq line (epg-pgp50i--read-line context))
+                 (string-match "\"\\([^\"]+\\)\"" line))
        (setq user-id-list (cons (match-string 1 line) user-id-list)))
       (cons key-id user-id-list))))
 
                                    epg-user-id-alist)))
     (setq epg-key-id (car key))))
 
+(defun epg-pgp50i--status-CANNOT_DECRYPT (context message)
+  (epg-context-set-result-for
+   context 'error
+   (cons (cons 'decryption-failed
+              (epg-pgp50i--read-key context))
+        (epg-context-result-for context 'error))))
+
+(defun epg-pgp50i--parse-time (string)
+  (if (string-match "\\`\\([0-9]+\\)-\\([0-9]+\\)-\\([0-9]+\\) \
+\\([0-9][0-9]\\):\\([0-9][0-9]\\) GMT\\'" string)
+      (encode-time 0
+                  (string-to-number (match-string 5 string))
+                  (string-to-number (match-string 4 string))
+                  (string-to-number (match-string 3 string))
+                  (string-to-number (match-string 2 string))
+                  (string-to-number (match-string 1 string))
+                  0)))
+
 (defun epg-pgp50i--status-GOOD_SIGNATURE (context message)
-  (let ((key (epg-pgp50i--read-key context)))
-    (epg--status-*SIG context 'good (concat (car key) " " (car (cdr key))))))
+  (if (string-match "Good signature made \\(.*\\) by key:" message)
+      (let ((time (epg-pgp50i--parse-time (match-string 1 message)))
+           (key (epg-pgp50i--read-key context)))
+       (epg--status-*SIG context 'good (concat (car key) " " (car (cdr key))))
+       (epg-signature-set-creation-time
+        (car (epg-context-result-for context 'verify))
+        time))))
+
+(defun epg-pgp50i--status-BAD_SIGNATURE (context message)
+  (if (string-match "BAD signature made \\(.*\\) by key:" message)
+      (let ((time (epg-pgp50i--parse-time (match-string 1 message)))
+           (key (epg-pgp50i--read-key context)))
+       (epg--status-*SIG context 'good (concat (car key) " " (car (cdr key))))
+       (epg-signature-set-creation-time
+        (car (epg-context-result-for context 'verify))
+        time))))
 
 (defadvice epg-start-decrypt
   (around epg-pgp50i activate)