aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Albinus2018-01-31 15:02:46 +0100
committerMichael Albinus2018-01-31 15:02:46 +0100
commit84d066a73fc4191a675c87c81ec1a4f531375e95 (patch)
tree8afdbd551f972a149e69c999f9f0e088994cf229
parent843f3d4f34c2f54fac19d97c32399671f98ccc51 (diff)
downloademacs-84d066a73fc4191a675c87c81ec1a4f531375e95.tar.gz
emacs-84d066a73fc4191a675c87c81ec1a4f531375e95.zip
Fix Bug#30293
* lisp/net/tramp-archive.el (tramp-archive-file-name-for-operation): New defsubst. (tramp-archive-file-name-archive, tramp-archive-file-name-localname): New defuns. (tramp-archive-file-name-handler, tramp-archive-dissect-file-name) (tramp-archive-handle-not-implemented): Use them. (Bug#30293) * test/lisp/net/tramp-archive-tests.el (tramp-archive-test-directory): New defconst. (tramp-archive-test01-file-name-syntax): Extend test. (tramp-archive-test05-expand-file-name-non-archive-directory): New test. (Bug#30293) * test/lisp/net/tramp-archive-resources/foo.iso/foo: New file.
-rw-r--r--lisp/net/tramp-archive.el49
-rw-r--r--test/lisp/net/tramp-archive-resources/foo.iso/foo1
-rw-r--r--test/lisp/net/tramp-archive-tests.el59
3 files changed, 94 insertions, 15 deletions
diff --git a/lisp/net/tramp-archive.el b/lisp/net/tramp-archive.el
index 51ee18fac7a..8d292e16023 100644
--- a/lisp/net/tramp-archive.el
+++ b/lisp/net/tramp-archive.el
@@ -253,21 +253,33 @@ It must be supported by libarchive(3).")
253 "Alist of handler functions for GVFS archive method. 253 "Alist of handler functions for GVFS archive method.
254Operations not mentioned here will be handled by the default Emacs primitives.") 254Operations not mentioned here will be handled by the default Emacs primitives.")
255 255
256(defsubst tramp-archive-file-name-for-operation (operation &rest args)
257 "Like `tramp-file-name-for-operation', but for archive file name syntax."
258 (cl-letf (((symbol-function 'tramp-tramp-file-p) 'tramp-archive-file-name-p))
259 (apply 'tramp-file-name-for-operation operation args)))
260
256;;;###tramp-autoload 261;;;###tramp-autoload
257(defun tramp-archive-file-name-handler (operation &rest args) 262(defun tramp-archive-file-name-handler (operation &rest args)
258 "Invoke the GVFS archive related OPERATION. 263 "Invoke the GVFS archive related OPERATION.
259First arg specifies the OPERATION, second arg is a list of arguments to 264First arg specifies the OPERATION, second arg is a list of arguments to
260pass to the OPERATION." 265pass to the OPERATION."
261 (unless tramp-gvfs-enabled 266 (let* ((filename (apply 'tramp-archive-file-name-for-operation
262 (tramp-compat-user-error nil "Package `tramp-archive' not supported")) 267 operation args))
263 (let ((tramp-methods (cons `(,tramp-archive-method) tramp-methods)) 268 (archive (tramp-archive-file-name-archive filename)))
264 (tramp-gvfs-methods tramp-archive-all-gvfs-methods) 269 ;; The file archive could be a directory, see Bug#30293.
265 (fn (assoc operation tramp-archive-file-name-handler-alist))) 270 (if (file-directory-p archive)
266 (when (eq (cdr fn) 'tramp-archive-handle-not-implemented) 271 (tramp-run-real-handler operation args)
267 (setq args (cons operation args))) 272 ;; Now run the handler.
268 (if fn 273 (unless tramp-gvfs-enabled
269 (save-match-data (apply (cdr fn) args)) 274 (tramp-compat-user-error nil "Package `tramp-archive' not supported"))
270 (tramp-run-real-handler operation args)))) 275 (let ((tramp-methods (cons `(,tramp-archive-method) tramp-methods))
276 (tramp-gvfs-methods tramp-archive-all-gvfs-methods)
277 (fn (assoc operation tramp-archive-file-name-handler-alist)))
278 (when (eq (cdr fn) 'tramp-archive-handle-not-implemented)
279 (setq args (cons operation args)))
280 (if fn
281 (save-match-data (apply (cdr fn) args))
282 (tramp-run-real-handler operation args))))))
271 283
272;; Mark `operations' the handler is responsible for. 284;; Mark `operations' the handler is responsible for.
273(put 'tramp-archive-file-name-handler 'operations 285(put 'tramp-archive-file-name-handler 'operations
@@ -300,6 +312,16 @@ pass to the OPERATION."
300 (string-match tramp-archive-file-name-regexp name) 312 (string-match tramp-archive-file-name-regexp name)
301 t)) 313 t))
302 314
315(defun tramp-archive-file-name-archive (name)
316 "Return archive part of NAME."
317 (and (tramp-archive-file-name-p name)
318 (match-string 1 name)))
319
320(defun tramp-archive-file-name-localname (name)
321 "Return localname part of NAME."
322 (and (tramp-archive-file-name-p name)
323 (match-string 2 name)))
324
303(defvar tramp-archive-hash (make-hash-table :test 'equal) 325(defvar tramp-archive-hash (make-hash-table :test 'equal)
304 "Hash table for archive local copies. 326 "Hash table for archive local copies.
305The hash key is the archive name. The value is a cons of the 327The hash key is the archive name. The value is a cons of the
@@ -314,9 +336,8 @@ name is kept in slot `hop'"
314 (save-match-data 336 (save-match-data
315 (unless (tramp-archive-file-name-p name) 337 (unless (tramp-archive-file-name-p name)
316 (tramp-compat-user-error nil "Not an archive file name: \"%s\"" name)) 338 (tramp-compat-user-error nil "Not an archive file name: \"%s\"" name))
317 ;; The `string-match' happened in `tramp-archive-file-name-p'. 339 (let* ((localname (tramp-archive-file-name-localname name))
318 (let* ((localname (match-string 2 name)) 340 (archive (file-truename (tramp-archive-file-name-archive name)))
319 (archive (file-truename (match-string 1 name)))
320 (vec (make-tramp-file-name 341 (vec (make-tramp-file-name
321 :method tramp-archive-method :hop archive))) 342 :method tramp-archive-method :hop archive)))
322 343
@@ -535,7 +556,7 @@ offered."
535 "Generic handler for operations not implemented for file archives." 556 "Generic handler for operations not implemented for file archives."
536 (let ((v (ignore-errors 557 (let ((v (ignore-errors
537 (tramp-archive-dissect-file-name 558 (tramp-archive-dissect-file-name
538 (apply 'tramp-file-name-for-operation operation args))))) 559 (apply 'tramp-archive-file-name-for-operation operation args)))))
539 (tramp-message v 10 "%s" (cons operation args)) 560 (tramp-message v 10 "%s" (cons operation args))
540 (tramp-error 561 (tramp-error
541 v 'file-error 562 v 'file-error
diff --git a/test/lisp/net/tramp-archive-resources/foo.iso/foo b/test/lisp/net/tramp-archive-resources/foo.iso/foo
new file mode 100644
index 00000000000..257cc5642cb
--- /dev/null
+++ b/test/lisp/net/tramp-archive-resources/foo.iso/foo
@@ -0,0 +1 @@
foo
diff --git a/test/lisp/net/tramp-archive-tests.el b/test/lisp/net/tramp-archive-tests.el
index ecfee0c556c..96c6a71097c 100644
--- a/test/lisp/net/tramp-archive-tests.el
+++ b/test/lisp/net/tramp-archive-tests.el
@@ -46,6 +46,11 @@
46 (file-name-as-directory tramp-archive-test-file-archive) 46 (file-name-as-directory tramp-archive-test-file-archive)
47 "The test archive.") 47 "The test archive.")
48 48
49(defconst tramp-archive-test-directory
50 (file-truename
51 (expand-file-name "foo.iso" tramp-archive-test-resource-directory))
52 "A directory file name, which looks like an archive.")
53
49(setq password-cache-expiry nil 54(setq password-cache-expiry nil
50 tramp-verbose 0 55 tramp-verbose 0
51 tramp-cache-read-persistent-data t ;; For auth-sources. 56 tramp-cache-read-persistent-data t ;; For auth-sources.
@@ -94,14 +99,51 @@ variables, so we check the Emacs version directly."
94 "Check archive file name syntax." 99 "Check archive file name syntax."
95 (should-not (tramp-archive-file-name-p tramp-archive-test-file-archive)) 100 (should-not (tramp-archive-file-name-p tramp-archive-test-file-archive))
96 (should (tramp-archive-file-name-p tramp-archive-test-archive)) 101 (should (tramp-archive-file-name-p tramp-archive-test-archive))
102 (should
103 (string-equal
104 (tramp-archive-file-name-archive tramp-archive-test-archive)
105 tramp-archive-test-file-archive))
106 (should
107 (string-equal
108 (tramp-archive-file-name-localname tramp-archive-test-archive) "/"))
97 (should (tramp-archive-file-name-p (concat tramp-archive-test-archive "foo"))) 109 (should (tramp-archive-file-name-p (concat tramp-archive-test-archive "foo")))
98 (should 110 (should
111 (string-equal
112 (tramp-archive-file-name-localname
113 (concat tramp-archive-test-archive "foo"))
114 "/foo"))
115 (should
99 (tramp-archive-file-name-p (concat tramp-archive-test-archive "foo/bar"))) 116 (tramp-archive-file-name-p (concat tramp-archive-test-archive "foo/bar")))
117 (should
118 (string-equal
119 (tramp-archive-file-name-localname
120 (concat tramp-archive-test-archive "foo/bar"))
121 "/foo/bar"))
100 ;; A file archive inside a file archive. 122 ;; A file archive inside a file archive.
101 (should 123 (should
102 (tramp-archive-file-name-p (concat tramp-archive-test-archive "baz.tar"))) 124 (tramp-archive-file-name-p (concat tramp-archive-test-archive "baz.tar")))
103 (should 125 (should
104 (tramp-archive-file-name-p (concat tramp-archive-test-archive "baz.tar/")))) 126 (string-equal
127 (tramp-archive-file-name-archive
128 (concat tramp-archive-test-archive "baz.tar"))
129 tramp-archive-test-file-archive))
130 (should
131 (string-equal
132 (tramp-archive-file-name-localname
133 (concat tramp-archive-test-archive "baz.tar"))
134 "/baz.tar"))
135 (should
136 (tramp-archive-file-name-p (concat tramp-archive-test-archive "baz.tar/")))
137 (should
138 (string-equal
139 (tramp-archive-file-name-archive
140 (concat tramp-archive-test-archive "baz.tar/"))
141 (concat tramp-archive-test-archive "baz.tar")))
142 (should
143 (string-equal
144 (tramp-archive-file-name-localname
145 (concat tramp-archive-test-archive "baz.tar/"))
146 "/")))
105 147
106(ert-deftest tramp-archive-test02-file-name-dissect () 148(ert-deftest tramp-archive-test02-file-name-dissect ()
107 "Check archive file name components." 149 "Check archive file name components."
@@ -205,6 +247,21 @@ variables, so we check the Emacs version directly."
205 (should (string-equal (expand-file-name "/foo.tar/./file") "/foo.tar/file")) 247 (should (string-equal (expand-file-name "/foo.tar/./file") "/foo.tar/file"))
206 (should (string-equal (expand-file-name "/foo.tar/../file") "/file"))) 248 (should (string-equal (expand-file-name "/foo.tar/../file") "/file")))
207 249
250;; This test is inspired by Bug#30293.
251(ert-deftest tramp-archive-test05-expand-file-name-non-archive-directory ()
252 "Check existing directories with archive file name syntax.
253They shall still be supported"
254 (should (file-directory-p tramp-archive-test-directory))
255 ;; `tramp-archive-file-name-p' tests only for file name syntax. It
256 ;; doesn't test, whether it is really a file archive.
257 (should
258 (tramp-archive-file-name-p
259 (file-name-as-directory tramp-archive-test-directory)))
260 (should
261 (file-directory-p (file-name-as-directory tramp-archive-test-directory)))
262 (should
263 (file-exists-p (expand-file-name "foo" tramp-archive-test-directory))))
264
208(ert-deftest tramp-archive-test06-directory-file-name () 265(ert-deftest tramp-archive-test06-directory-file-name ()
209 "Check `directory-file-name'. 266 "Check `directory-file-name'.
210This checks also `file-name-as-directory', `file-name-directory', 267This checks also `file-name-as-directory', `file-name-directory',