Added 0.0.10 changes.
[elisp/epg.git] / epa-file.el
index b1743ee..1f939c1 100644 (file)
   :type 'regexp
   :group 'epa-file)
 
   :type 'regexp
   :group 'epa-file)
 
+(defcustom epa-file-cache-passphrase-for-symmetric-encryption nil
+  "If t, cache passphrase for symmetric encryption."
+  :type 'boolean
+  :group 'epa-file)
+
+(defvar epa-file-encrypt-to nil
+  "*Recipient(s) used for encrypting files.
+May either be a string or a list of strings.")
+
+;;;###autoload
+(put 'epa-file-encrypt-to 'safe-local-variable
+     (lambda (val)
+       (or (stringp val)
+          (and (listp val)
+               (catch 'safe
+                 (mapc (lambda (elt)
+                         (unless (stringp elt)
+                           (throw 'safe nil)))
+                       val)
+                 t)))))
+
 (defvar epa-file-handler
   (cons epa-file-name-regexp 'epa-file-handler))
 (defvar epa-file-handler
   (cons epa-file-name-regexp 'epa-file-handler))
-  
+
 (defvar epa-file-passphrase-alist nil)
 
 (defvar epa-file-passphrase-alist nil)
 
+(if (fboundp 'encode-coding-string)
+    (defalias 'epa-file--encode-coding-string 'encode-coding-string)
+  (defalias 'epa-file--encode-coding-string 'identity))
+
+(if (fboundp 'decode-coding-string)
+    (defalias 'epa-file--decode-coding-string 'decode-coding-string)
+  (defalias 'epa-file--decode-coding-string 'identity))
+
 (defun epa-file-passphrase-callback-function (context key-id file)
 (defun epa-file-passphrase-callback-function (context key-id file)
-  (if (eq key-id 'SYM)
+  (if (and epa-file-cache-passphrase-for-symmetric-encryption
+          (eq key-id 'SYM))
       (let ((entry (assoc file epa-file-passphrase-alist))
            passphrase)
        (or (copy-sequence (cdr entry))
       (let ((entry (assoc file epa-file-passphrase-alist))
            passphrase)
        (or (copy-sequence (cdr entry))
                (setq entry (list file)
                      epa-file-passphrase-alist (cons entry
                                                 epa-file-passphrase-alist)))
                (setq entry (list file)
                      epa-file-passphrase-alist (cons entry
                                                 epa-file-passphrase-alist)))
-             (setq passphrase (epg-passphrase-callback-function context
+             (setq passphrase (epa-passphrase-callback-function context
                                                                 key-id nil))
              (setcdr entry (copy-sequence passphrase))
              passphrase)))
                                                                 key-id nil))
              (setcdr entry (copy-sequence passphrase))
              passphrase)))
-    (epg-passphrase-callback-function context key-id nil)))
+    (epa-passphrase-callback-function context key-id nil)))
 
 (defun epa-file-handler (operation &rest args)
   (save-match-data
 
 (defun epa-file-handler (operation &rest args)
   (save-match-data
        (inhibit-file-name-operation operation))
     (apply operation args)))
 
        (inhibit-file-name-operation operation))
     (apply operation args)))
 
+(defun epa-file-decode-and-insert (string file visit beg end replace)
+  (if (fboundp 'decode-coding-inserted-region)
+      (save-restriction
+       (narrow-to-region (point) (point))
+       (let ((multibyte enable-multibyte-characters))
+         (set-buffer-multibyte nil)
+         (insert string)
+         (set-buffer-multibyte multibyte)
+         (decode-coding-inserted-region
+          (point-min) (point-max)
+          (substring file 0 (string-match epa-file-name-regexp file))
+          visit beg end replace)))
+    (insert (epa-file--decode-coding-string string (or coding-system-for-read
+                                                      'undecided)))))
+
 (defvar last-coding-system-used)
 (defun epa-file-insert-file-contents (file &optional visit beg end replace)
   (barf-if-buffer-read-only)
 (defvar last-coding-system-used)
 (defun epa-file-insert-file-contents (file &optional visit beg end replace)
   (barf-if-buffer-read-only)
      context
      (cons #'epa-file-passphrase-callback-function
           file))
      context
      (cons #'epa-file-passphrase-callback-function
           file))
+    (epg-context-set-progress-callback context
+                                      #'epa-progress-callback-function)
     (unwind-protect
        (progn
          (if replace
     (unwind-protect
        (progn
          (if replace
                     (cons "Opening input file" (cdr error)))))
          (if (or beg end)
              (setq string (substring string (or beg 0) end)))
                     (cons "Opening input file" (cdr error)))))
          (if (or beg end)
              (setq string (substring string (or beg 0) end)))
-         (if (boundp 'last-coding-system-used)
-             (set-buffer-file-coding-system last-coding-system-used)
-           (set-buffer-file-coding-system default-buffer-file-coding-system))
          (save-excursion
          (save-excursion
-           (if (and (null coding-system-for-read)
-                    (fboundp 'decode-coding-inserted-region))
-               (save-restriction
-                 (narrow-to-region (point) (point))
-                 (insert string)
-                 (decode-coding-inserted-region
-                  (point-min) (point-max)
-                  (substring file 0 (string-match epa-file-name-regexp file))
-                  visit beg end replace)
-                 (setq length (- (point-max) (point-min))))
-             (setq string (decode-coding-string string
-                                                (or coding-system-for-read
-                                                    'undecided))
-                   length (length string))
-             (insert string))
+           (save-restriction
+             (narrow-to-region (point) (point))
+             (epa-file-decode-and-insert string file visit beg end replace)
+             (setq length (- (point-max) (point-min))))
            (if replace
                (delete-region (point) (point-max)))))
       (if (and local-copy
            (if replace
                (delete-region (point) (point-max)))))
       (if (and local-copy
       (error "Can't append to the file."))
   (setq file (expand-file-name file))
   (let* ((coding-system (or coding-system-for-write
       (error "Can't append to the file."))
   (setq file (expand-file-name file))
   (let* ((coding-system (or coding-system-for-write
-                           (if (boundp 'last-coding-system-used)
-                               (condition-case nil
-                                   (write-region (point-min) (point-max) "/")
-                                 (error last-coding-system-used))
+                           (if (fboundp 'select-safe-coding-system)
+                               (select-safe-coding-system
+                                (point-min) (point-max))
                              buffer-file-coding-system)))
         (context (epg-make-context))
         (coding-system-for-write 'binary)
                              buffer-file-coding-system)))
         (context (epg-make-context))
         (coding-system-for-write 'binary)
      context
      (cons #'epa-file-passphrase-callback-function
           file))
      context
      (cons #'epa-file-passphrase-callback-function
           file))
+    (epg-context-set-progress-callback context
+                                      #'epa-progress-callback-function)
     (condition-case error
        (setq string
              (epg-encrypt-string
               context
               (if (stringp start)
     (condition-case error
        (setq string
              (epg-encrypt-string
               context
               (if (stringp start)
-                  (encode-coding-string start coding-system)
-                (encode-coding-string (buffer-substring start end)
-                                      coding-system))
+                  (epa-file--encode-coding-string start coding-system)
+                (epa-file--encode-coding-string (buffer-substring start end)
+                                                coding-system))
               (unless (assoc file epa-file-passphrase-alist)
                 (epa-select-keys
                  context
                  "Select recipents for encryption.
               (unless (assoc file epa-file-passphrase-alist)
                 (epa-select-keys
                  context
                  "Select recipents for encryption.
-If no one is selected, symmetric encryption will be performed.  "))))
+If no one is selected, symmetric encryption will be performed.  "
+                 (cond
+                  ((listp epa-file-encrypt-to) epa-file-encrypt-to)
+                  ((stringp epa-file-encrypt-to) (list epa-file-encrypt-to)))))))
       (error
        (if (setq entry (assoc file epa-file-passphrase-alist))
           (setcdr entry nil))
       (error
        (if (setq entry (assoc file epa-file-passphrase-alist))
           (setcdr entry nil))