From ac3c5f1e851519e110b8d908d388b48221334e66 Mon Sep 17 00:00:00 2001 From: ueno Date: Mon, 17 Apr 2006 07:39:28 +0000 Subject: [PATCH] * epa-file.el: Rewritten with file-name-handler. --- ChangeLog | 4 ++ epa-file.el | 175 +++++++++++++++++++++++++++++++++++----------------------- epa-setup.el | 10 ++-- 3 files changed, 115 insertions(+), 74 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1a7b25c..126ef3e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2006-04-17 Daiki Ueno + * epa-file.el: Rewritten with file-name-handler. + +2006-04-17 Daiki Ueno + * epa-file.el (epa-passphrase): New variable. (epa-file-passphrase-callback-function): New function. (epa-find-file): Reset buffer-undo-list; set diff --git a/epa-file.el b/epa-file.el index b1b2681..d0d194f 100644 --- a/epa-file.el +++ b/epa-file.el @@ -34,83 +34,120 @@ :type 'regexp :group 'epa-file) -(defvar epa-file nil) -(defvar epa-passphrase nil) +(defvar epa-passphrase-alist nil) (defun epa-file-passphrase-callback-function (key-id buffer) - (save-excursion - (set-buffer buffer) - (if (eq key-id 'SYM) - (or epa-passphrase - (let ((passphrase (epg-passphrase-callback-function - key-id buffer))) - (setq epa-passphrase (copy-sequence passphrase)) - passphrase)) - (epg-passphrase-callback-function key-id buffer)))) + (if (eq key-id 'SYM) + (let ((entry (assoc buffer epa-passphrase-alist)) + passphrase) + (or (cdr entry) + (progn + (unless entry + (setq entry (list buffer) + epa-passphrase-alist (cons entry + epa-passphrase-alist))) + (setq passphrase (epg-passphrase-callback-function key-id nil)) + (setcdr entry (copy-sequence passphrase)) + passphrase))) + (epg-passphrase-callback-function key-id nil))) + +(defun epa-file-handler (operation &rest args) + (save-match-data + (let ((op (get operation 'epa-file))) + (if op + (apply op args) + (epa-file-run-real-handler operation args))))) + +(defun epa-file-run-real-handler (operation args) + (let ((inhibit-file-name-handlers + (cons 'epa-file-handler + (and (eq inhibit-file-name-operation operation) + inhibit-file-name-handlers))) + (inhibit-file-name-operation operation)) + (apply operation args))) (defvar last-coding-system-used) -(defun epa-find-file () - (when (string-match epa-file-name-regexp (buffer-file-name)) - (if (file-exists-p (expand-file-name (buffer-file-name))) - (let ((context (epg-make-context)) - passphrase) - (if (fboundp 'set-buffer-multibyte) - (set-buffer-multibyte t)) - (goto-char (point-min)) - (epg-context-set-passphrase-callback - context - (cons #'epa-file-passphrase-callback-function - (current-buffer))) - (make-local-variable 'epa-passphrase) - (insert (epg-decrypt-file context - (expand-file-name (buffer-file-name)) - nil)) - (setq passphrase epa-passphrase) - (delete-region (point) (point-max)) - (decode-coding-region (point-min) (point-max) 'undecided) +(defun epa-file-insert-file-contents (file &optional visit beg end replace) + (barf-if-buffer-read-only) + (if (or beg end) + (error "Can't read the file partially.")) + (setq file (expand-file-name file)) + (let ((local-copy (epa-file-run-real-handler #'file-local-copy (list file))) + (context (epg-make-context)) + point length entry) + (if visit + (setq buffer-file-name file)) + (epg-context-set-passphrase-callback + context + (cons #'epa-file-passphrase-callback-function + (current-buffer))) + (unwind-protect + (progn + (if replace + (goto-char (point-min))) + (setq point (point)) + (condition-case error + (insert (epg-decrypt-file context file nil)) + (error (signal 'file-error + (cons "Opening input file" + (nthcdr 2 error))))) + (setq length (- (point) point)) + (if replace + (delete-region (point) (point-max))) + (decode-coding-region point (point) 'undecided) (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)) - (set-auto-mode) - (hack-local-variables) - (auto-save-mode nil) - (set-buffer-modified-p nil) - (setq buffer-undo-list nil) - (make-local-variable 'epa-passphrase) - (setq epa-passphrase passphrase))) - (make-local-variable 'epa-passphrase) - (make-local-variable 'epa-file) - (setq epa-file (buffer-file-name)))) - -(defun epa-write-file () - (if epa-file - (let* ((coding-system (if (boundp 'last-coding-system-used) - (condition-case nil - (write-region (point-min) (point-max) "/") - (error last-coding-system-used)) - buffer-file-coding-system)) - (context (epg-make-context)) - (coding-system-for-write 'binary)) - (epg-context-set-passphrase-callback - context - (cons #'epa-file-passphrase-callback-function - (current-buffer))) - (write-region - (epg-encrypt-string - context - (encode-coding-string (buffer-string) coding-system) - (mapcar (lambda (key) - (epg-sub-key-id (car (epg-key-sub-key-list key)))) - (unless epa-passphrase - (epa-select-keys - "Select recipents for encryption. + (goto-char point)) + (if (and local-copy + (file-exists-p local-copy)) + (delete-file local-copy))) + (list file length))) +(put 'insert-file-contents 'epa-file 'epa-file-insert-file-contents) + +(defun epa-file-write-region (start end file &optional append visit lockname + mustbenew) + (if append + (error "Can't append to the file.")) + (setq file (expand-file-name file)) + (let* ((coding-system (if (boundp 'last-coding-system-used) + (condition-case nil + (write-region (point-min) (point-max) "/") + (error last-coding-system-used)) + buffer-file-coding-system)) + (context (epg-make-context)) + (coding-system-for-write 'binary)) + (epg-context-set-passphrase-callback + context + (cons #'epa-file-passphrase-callback-function + (current-buffer))) + (epa-file-run-real-handler + #'write-region + (list (epg-encrypt-string + context + (encode-coding-string (buffer-string) coding-system) + (mapcar (lambda (key) + (epg-sub-key-id (car (epg-key-sub-key-list key)))) + (unless (assoc (current-buffer) epa-passphrase-alist) + (epa-select-keys + "Select recipents for encryption. If no one is selected, symmetric encryption will be performed. ")))) - nil (expand-file-name (buffer-file-name))) - (if (boundp 'last-coding-system-used) - (setq last-coding-system-used coding-system)) - (set-visited-file-modtime) - (set-buffer-modified-p nil) - t))) + nil file append visit lockname mustbenew)) + (if (boundp 'last-coding-system-used) + (setq last-coding-system-used coding-system)) + (if (eq visit t) + (progn + (setq buffer-file-name file) + (set-visited-file-modtime)) + (if (stringp visit) + (progn + (set-visited-file-modtime) + (setq buffer-file-name visit)))) + (if (or (eq visit t) + (eq visit nil) + (stringp visit)) + (message "Wrote %s" buffer-file-name)))) +(put 'write-region 'epa-file 'epa-file-write-region) (provide 'epa-file) diff --git a/epa-setup.el b/epa-setup.el index 5944deb..311e553 100644 --- a/epa-setup.el +++ b/epa-setup.el @@ -1,11 +1,11 @@ (autoload 'epa-dired-mode-hook "epa-dired") (add-hook 'dired-mode-hook 'epa-dired-mode-hook) -(autoload 'epa-find-file "epa-file") -(add-hook 'find-file-hooks 'epa-find-file) - -(autoload 'epa-write-file "epa-file") -(add-hook 'write-file-hooks 'epa-write-file) +(require 'epa-file) +(unless (rassq 'epa-file-handler file-name-handler-alist) + (setq file-name-handler-alist + (cons (cons epa-file-name-regexp 'epa-file-handler) + file-name-handler-alist))) (provide 'epa-setup) -- 1.7.10.4