From: Michael Albinus Date: Wed, 29 Jul 2015 19:07:01 +0000 (+0200) Subject: Fix Tramp problems with multihops, and nc. X-Git-Tag: emacs-25.0.90~1417 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=a53d1d325e0d1c0db6b407a776d6cfd3d12a90e0;p=emacs.git Fix Tramp problems with multihops, and nc. * lisp/net/tramp-cache.el (tramp-get-file-property) (tramp-set-file-property, tramp-flush-file-property) (tramp-get-connection-property, tramp-set-connection-property) (tramp-flush-connection-property): Remove hop from vector. * lisp/net/tramp-gw.el (tramp-gw-process-filter): Ignore errors. * lisp/net/tramp-sh.el (tramp-methods) : Separate STDERR. (tramp-do-copy-or-rename-file-out-of-band): Increase timeout of netstat to 60". (tramp-sh-handle-start-file-process): Do not show hops in prompt. * lisp/net/tramp.el (tramp-handle-file-name-as-directory) (tramp-handle-file-name-directory, tramp-handle-file-remote-p): Keep hop in result. * test/automated/tramp-tests.el (tramp-test02-file-name-dissect): Add hop tests. --- diff --git a/lisp/net/tramp-cache.el b/lisp/net/tramp-cache.el index 279d9f45c95..f777468c1ff 100644 --- a/lisp/net/tramp-cache.el +++ b/lisp/net/tramp-cache.el @@ -121,9 +121,10 @@ matching entries of `tramp-connection-properties'." (defun tramp-get-file-property (key file property default) "Get the PROPERTY of FILE from the cache context of KEY. Returns DEFAULT if not set." - ;; Unify localname. + ;; Unify localname. Remove hop from vector. (setq key (copy-sequence key)) (aset key 3 (tramp-run-real-handler 'directory-file-name (list file))) + (aset key 4 nil) (let* ((hash (tramp-get-hash-table key)) (value (when (hash-table-p hash) (gethash property hash)))) (if @@ -153,9 +154,10 @@ Returns DEFAULT if not set." (defun tramp-set-file-property (key file property value) "Set the PROPERTY of FILE to VALUE, in the cache context of KEY. Returns VALUE." - ;; Unify localname. + ;; Unify localname. Remove hop from vector. (setq key (copy-sequence key)) (aset key 3 (tramp-run-real-handler 'directory-file-name (list file))) +p (aset key 4 nil) (let ((hash (tramp-get-hash-table key))) ;; We put the timestamp there. (puthash property (cons (current-time) value) hash) @@ -176,9 +178,10 @@ Returns VALUE." (when (and (stringp truename) (not (string-equal file (directory-file-name truename)))) (tramp-flush-file-property key truename)) - ;; Unify localname. + ;; Unify localname. Remove hop from vector. (setq key (copy-sequence key)) (aset key 3 file) + (aset key 4 nil) (tramp-message key 8 "%s" file) (remhash key tramp-cache-data))) @@ -240,11 +243,12 @@ This is suppressed for temporary buffers." "Get the named PROPERTY for the connection. KEY identifies the connection, it is either a process or a vector. If the value is not set for the connection, returns DEFAULT." - ;; Unify key by removing localname from vector. Work with a copy in - ;; order to avoid side effects. + ;; Unify key by removing localname and hop from vector. Work with a + ;; copy in order to avoid side effects. (when (vectorp key) (setq key (copy-sequence key)) - (aset key 3 nil)) + (aset key 3 nil) + (aset key 4 nil)) (let* ((hash (tramp-get-hash-table key)) (value (if (hash-table-p hash) (gethash property hash default) @@ -257,11 +261,12 @@ If the value is not set for the connection, returns DEFAULT." "Set the named PROPERTY of a connection to VALUE. KEY identifies the connection, it is either a process or a vector. PROPERTY is set persistent when KEY is a vector." - ;; Unify key by removing localname from vector. Work with a copy in - ;; order to avoid side effects. + ;; Unify key by removing localname and hop from vector. Work with a + ;; copy in order to avoid side effects. (when (vectorp key) (setq key (copy-sequence key)) - (aset key 3 nil)) + (aset key 3 nil) + (aset key 4 nil)) (let ((hash (tramp-get-hash-table key))) (puthash property value hash) (setq tramp-cache-data-changed t) @@ -278,11 +283,12 @@ KEY identifies the connection, it is either a process or a vector." (defun tramp-flush-connection-property (key) "Remove all properties identified by KEY. KEY identifies the connection, it is either a process or a vector." - ;; Unify key by removing localname from vector. Work with a copy in - ;; order to avoid side effects. + ;; Unify key by removing localname and hop from vector. Work with a + ;; copy in order to avoid side effects. (when (vectorp key) (setq key (copy-sequence key)) - (aset key 3 nil)) + (aset key 3 nil) + (aset key 4 nil)) (tramp-message key 7 "%s %s" key (let ((hash (gethash key tramp-cache-data)) diff --git a/lisp/net/tramp-gw.el b/lisp/net/tramp-gw.el index 16eff8ca9e0..5e22f6a3b59 100644 --- a/lisp/net/tramp-gw.el +++ b/lisp/net/tramp-gw.el @@ -126,8 +126,11 @@ (defun tramp-gw-process-filter (proc string) (let ((tramp-verbose 0)) - (process-send-string - (tramp-get-connection-property proc "process" nil) string))) + ;; The other process might have been stopped already. We don't + ;; want to be interrupted then. + (ignore-errors + (process-send-string + (tramp-get-connection-property proc "process" nil) string)))) ;;;###tramp-autoload (defun tramp-gw-open-connection (vec gw-vec target-vec) diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index 670ff4b0cf7..bb939bf2df8 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -273,7 +273,7 @@ The string is used in `tramp-methods'.") ;; We use "-p" as required for newer busyboxes. For older ;; busybox/nc versions, the value must be (("-l") ("%r")). This ;; can be achieved by tweaking `tramp-connection-properties'. - (tramp-remote-copy-args (("-l") ("-p" "%r"))) + (tramp-remote-copy-args (("-l") ("-p" "%r") ("2>/dev/null"))) (tramp-default-port 23))) ;;;###tramp-autoload (add-to-list 'tramp-methods @@ -2477,10 +2477,10 @@ The method used must be an out-of-band method." " ")) (tramp-send-command v remote-copy-program) (with-timeout - (1 (tramp-error - v 'file-error - "Listener process not running on remote host: `%s'" - remote-copy-program)) + (60 (tramp-error + v 'file-error + "Listener process not running on remote host: `%s'" + remote-copy-program)) (tramp-send-command v (format "netstat -l | grep -q :%s" listener)) (while (not (tramp-send-command-and-check v nil)) (tramp-send-command @@ -2911,10 +2911,15 @@ the result will be a local, non-Tramp, file name." (setq i (+ i 250)))) (cdr args))) ;; Use a human-friendly prompt, for example for `shell'. - (prompt (format "PS1=%s" - (format "%s %s" - (file-remote-p default-directory) - tramp-initial-end-of-output))) + ;; We discard hops, if existing, that's why we cannot use + ;; `file-remote-p'. + (prompt (format "PS1=%s %s" + (tramp-make-tramp-file-name + (tramp-file-name-method v) + (tramp-file-name-user v) + (tramp-file-name-host v) + (tramp-file-name-localname v)) + tramp-initial-end-of-output)) ;; We use as environment the difference to toplevel ;; `process-environment'. env diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index beb87f61aaa..e15732182d7 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -2927,7 +2927,8 @@ User is always nil." (tramp-file-name-user v) (tramp-file-name-host v) (tramp-run-real-handler - 'file-name-as-directory (list (or (tramp-file-name-localname v) "")))))) + 'file-name-as-directory (list (or (tramp-file-name-localname v) ""))) + (tramp-file-name-hop v)))) (defun tramp-handle-file-name-completion (filename directory &optional predicate) @@ -2955,7 +2956,8 @@ User is always nil." (tramp-file-name-user v) (tramp-file-name-host v) (tramp-run-real-handler - 'file-name-directory (list (or (tramp-file-name-localname v) "")))))) + 'file-name-directory (list (or (tramp-file-name-localname v) ""))) + (tramp-file-name-hop v)))) (defun tramp-handle-file-name-nondirectory (file) "Like `file-name-nondirectory' but aware of Tramp files." @@ -2992,7 +2994,8 @@ User is always nil." ((eq identification 'user) user) ((eq identification 'host) host) ((eq identification 'localname) localname) - (t (tramp-make-tramp-file-name method user host ""))))))))) + ((eq identification 'hop) hop) + (t (tramp-make-tramp-file-name method user host "" hop))))))))) (defun tramp-handle-file-symlink-p (filename) "Like `file-symlink-p' for Tramp files." diff --git a/test/automated/tramp-tests.el b/test/automated/tramp-tests.el index a03dbf30b18..e6f77e42499 100644 --- a/test/automated/tramp-tests.el +++ b/test/automated/tramp-tests.el @@ -213,6 +213,7 @@ shall not contain a timeout." (should (string-equal (file-remote-p "/method::" 'user) "default-user")) (should (string-equal (file-remote-p "/method::" 'host) "default-host")) (should (string-equal (file-remote-p "/method::" 'localname) "")) + (should (string-equal (file-remote-p "/method::" 'hop) nil)) ;; Expand `tramp-default-method' and `tramp-default-user'. (should (string-equal @@ -222,6 +223,7 @@ shall not contain a timeout." (should (string-equal (file-remote-p "/host:" 'user) "default-user")) (should (string-equal (file-remote-p "/host:" 'host) "host")) (should (string-equal (file-remote-p "/host:" 'localname) "")) + (should (string-equal (file-remote-p "/host:" 'hop) nil)) ;; Expand `tramp-default-method' and `tramp-default-host'. (should (string-equal @@ -231,6 +233,7 @@ shall not contain a timeout." (should (string-equal (file-remote-p "/user@:" 'user) "user")) (should (string-equal (file-remote-p "/user@:" 'host) "default-host")) (should (string-equal (file-remote-p "/user@:" 'localname) "")) + (should (string-equal (file-remote-p "/user@:" 'hop) nil)) ;; Expand `tramp-default-method'. (should (string-equal @@ -241,6 +244,7 @@ shall not contain a timeout." (should (string-equal (file-remote-p "/user@host:" 'user) "user")) (should (string-equal (file-remote-p "/user@host:" 'host) "host")) (should (string-equal (file-remote-p "/user@host:" 'localname) "")) + (should (string-equal (file-remote-p "/user@host:" 'hop) nil)) ;; Expand `tramp-default-user'. (should (string-equal @@ -250,6 +254,7 @@ shall not contain a timeout." (should (string-equal (file-remote-p "/method:host:" 'user) "default-user")) (should (string-equal (file-remote-p "/method:host:" 'host) "host")) (should (string-equal (file-remote-p "/method:host:" 'localname) "")) + (should (string-equal (file-remote-p "/method:host:" 'hop) nil)) ;; Expand `tramp-default-host'. (should (string-equal @@ -260,6 +265,7 @@ shall not contain a timeout." (should (string-equal (file-remote-p "/method:user@:" 'host) "default-host")) (should (string-equal (file-remote-p "/method:user@:" 'localname) "")) + (should (string-equal (file-remote-p "/method:user@:" 'hop) nil)) ;; No expansion. (should (string-equal @@ -270,6 +276,7 @@ shall not contain a timeout." (should (string-equal (file-remote-p "/method:user@host:" 'user) "user")) (should (string-equal (file-remote-p "/method:user@host:" 'host) "host")) (should (string-equal (file-remote-p "/method:user@host:" 'localname) "")) + (should (string-equal (file-remote-p "/method:user@host:" 'hop) nil)) ;; No expansion. (should (string-equal @@ -283,6 +290,8 @@ shall not contain a timeout." (file-remote-p "/method:user@email@host:" 'host) "host")) (should (string-equal (file-remote-p "/method:user@email@host:" 'localname) "")) + (should (string-equal + (file-remote-p "/method:user@email@host:" 'hop) nil)) ;; Expand `tramp-default-method' and `tramp-default-user'. (should (string-equal @@ -293,6 +302,7 @@ shall not contain a timeout." (should (string-equal (file-remote-p "/host#1234:" 'user) "default-user")) (should (string-equal (file-remote-p "/host#1234:" 'host) "host#1234")) (should (string-equal (file-remote-p "/host#1234:" 'localname) "")) + (should (string-equal (file-remote-p "/host#1234:" 'hop) nil)) ;; Expand `tramp-default-method'. (should (string-equal @@ -303,6 +313,7 @@ shall not contain a timeout." (should (string-equal (file-remote-p "/user@host#1234:" 'user) "user")) (should (string-equal (file-remote-p "/user@host#1234:" 'host) "host#1234")) (should (string-equal (file-remote-p "/user@host#1234:" 'localname) "")) + (should (string-equal (file-remote-p "/user@host#1234:" 'hop) nil)) ;; Expand `tramp-default-user'. (should (string-equal @@ -315,6 +326,7 @@ shall not contain a timeout." (should (string-equal (file-remote-p "/method:host#1234:" 'host) "host#1234")) (should (string-equal (file-remote-p "/method:host#1234:" 'localname) "")) + (should (string-equal (file-remote-p "/method:host#1234:" 'hop) nil)) ;; No expansion. (should (string-equal @@ -328,6 +340,8 @@ shall not contain a timeout." (file-remote-p "/method:user@host#1234:" 'host) "host#1234")) (should (string-equal (file-remote-p "/method:user@host#1234:" 'localname) "")) + (should (string-equal + (file-remote-p "/method:user@host#1234:" 'hop) nil)) ;; Expand `tramp-default-method' and `tramp-default-user'. (should (string-equal @@ -337,6 +351,7 @@ shall not contain a timeout." (should (string-equal (file-remote-p "/1.2.3.4:" 'user) "default-user")) (should (string-equal (file-remote-p "/1.2.3.4:" 'host) "1.2.3.4")) (should (string-equal (file-remote-p "/1.2.3.4:" 'localname) "")) + (should (string-equal (file-remote-p "/1.2.3.4:" 'hop) nil)) ;; Expand `tramp-default-method'. (should (string-equal @@ -347,6 +362,7 @@ shall not contain a timeout." (should (string-equal (file-remote-p "/user@1.2.3.4:" 'user) "user")) (should (string-equal (file-remote-p "/user@1.2.3.4:" 'host) "1.2.3.4")) (should (string-equal (file-remote-p "/user@1.2.3.4:" 'localname) "")) + (should (string-equal (file-remote-p "/user@1.2.3.4:" 'hop) nil)) ;; Expand `tramp-default-user'. (should (string-equal @@ -357,6 +373,7 @@ shall not contain a timeout." (file-remote-p "/method:1.2.3.4:" 'user) "default-user")) (should (string-equal (file-remote-p "/method:1.2.3.4:" 'host) "1.2.3.4")) (should (string-equal (file-remote-p "/method:1.2.3.4:" 'localname) "")) + (should (string-equal (file-remote-p "/method:1.2.3.4:" 'hop) nil)) ;; No expansion. (should (string-equal @@ -369,6 +386,8 @@ shall not contain a timeout." (file-remote-p "/method:user@1.2.3.4:" 'host) "1.2.3.4")) (should (string-equal (file-remote-p "/method:user@1.2.3.4:" 'localname) "")) + (should (string-equal + (file-remote-p "/method:user@1.2.3.4:" 'hop) nil)) ;; Expand `tramp-default-method', `tramp-default-user' and ;; `tramp-default-host'. @@ -380,6 +399,7 @@ shall not contain a timeout." (should (string-equal (file-remote-p "/[]:" 'user) "default-user")) (should (string-equal (file-remote-p "/[]:" 'host) "default-host")) (should (string-equal (file-remote-p "/[]:" 'localname) "")) + (should (string-equal (file-remote-p "/[]:" 'hop) nil)) ;; Expand `tramp-default-method' and `tramp-default-user'. (let ((tramp-default-host "::1")) @@ -389,7 +409,8 @@ shall not contain a timeout." (should (string-equal (file-remote-p "/[]:" 'method) "default-method")) (should (string-equal (file-remote-p "/[]:" 'user) "default-user")) (should (string-equal (file-remote-p "/[]:" 'host) "::1")) - (should (string-equal (file-remote-p "/[]:" 'localname) ""))) + (should (string-equal (file-remote-p "/[]:" 'localname) "")) + (should (string-equal (file-remote-p "/[]:" 'hop) nil))) ;; Expand `tramp-default-method' and `tramp-default-user'. (should (string-equal @@ -399,6 +420,7 @@ shall not contain a timeout." (should (string-equal (file-remote-p "/[::1]:" 'user) "default-user")) (should (string-equal (file-remote-p "/[::1]:" 'host) "::1")) (should (string-equal (file-remote-p "/[::1]:" 'localname) "")) + (should (string-equal (file-remote-p "/[::1]:" 'hop) nil)) ;; Expand `tramp-default-method'. (should (string-equal @@ -409,6 +431,7 @@ shall not contain a timeout." (should (string-equal (file-remote-p "/user@[::1]:" 'user) "user")) (should (string-equal (file-remote-p "/user@[::1]:" 'host) "::1")) (should (string-equal (file-remote-p "/user@[::1]:" 'localname) "")) + (should (string-equal (file-remote-p "/user@[::1]:" 'hop) nil)) ;; Expand `tramp-default-user'. (should (string-equal @@ -419,6 +442,7 @@ shall not contain a timeout." (file-remote-p "/method:[::1]:" 'user) "default-user")) (should (string-equal (file-remote-p "/method:[::1]:" 'host) "::1")) (should (string-equal (file-remote-p "/method:[::1]:" 'localname) "")) + (should (string-equal (file-remote-p "/method:[::1]:" 'hop) nil)) ;; No expansion. (should (string-equal @@ -430,6 +454,7 @@ shall not contain a timeout." (should (string-equal (file-remote-p "/method:user@[::1]:" 'host) "::1")) (should (string-equal (file-remote-p "/method:user@[::1]:" 'localname) "")) + (should (string-equal (file-remote-p "/method:user@[::1]:" 'hop) nil)) ;; Local file name part. (should (string-equal (file-remote-p "/host:/:" 'localname) "/:")) @@ -444,7 +469,8 @@ shall not contain a timeout." (should (string-equal (file-remote-p "/method1:user1@host1|method2:user2@host2:/path/to/file") - (format "/%s:%s@%s:" "method2" "user2" "host2"))) + (format "/%s:%s@%s|%s:%s@%s:" + "method1" "user1" "host1" "method2" "user2" "host2"))) (should (string-equal (file-remote-p @@ -465,12 +491,21 @@ shall not contain a timeout." (file-remote-p "/method1:user1@host1|method2:user2@host2:/path/to/file" 'localname) "/path/to/file")) + (should + (string-equal + (file-remote-p + "/method1:user1@host1|method2:user2@host2:/path/to/file" 'hop) + (format "%s:%s@%s|" + "method1" "user1" "host1"))) (should (string-equal (file-remote-p "/method1:user1@host1|method2:user2@host2|method3:user3@host3:/path/to/file") - (format "/%s:%s@%s:" "method3" "user3" "host3"))) + (format "/%s:%s@%s|%s:%s@%s|%s:%s@%s:" + "method1" "user1" "host1" + "method2" "user2" "host2" + "method3" "user3" "host3"))) (should (string-equal (file-remote-p @@ -494,7 +529,14 @@ shall not contain a timeout." (file-remote-p "/method1:user1@host1|method2:user2@host2|method3:user3@host3:/path/to/file" 'localname) - "/path/to/file")))) + "/path/to/file")) + (should + (string-equal + (file-remote-p + "/method1:user1@host1|method2:user2@host2|method3:user3@host3:/path/to/file" + 'hop) + (format "%s:%s@%s|%s:%s@%s|" + "method1" "user1" "host1" "method2" "user2" "host2"))))) (ert-deftest tramp-test03-file-name-defaults () "Check default values for some methods." @@ -2168,11 +2210,7 @@ Since it unloads Tramp, it shall be the last test to run." ;; * Work on skipped tests. Make a comment, when it is impossible. ;; * Fix `tramp-test15-copy-directory' for `smb'. Using tar in a pipe ;; doesn't work well when an interactive password must be provided. -;; * Fix `tramp-test27-start-file-process' for `nc' and on MS -;; Windows (`process-send-eof'?). -;; * Fix `tramp-test31-special-characters' for `nc'. -;; * Fix `tramp-test32-utf8' for `nc'/`telnet' (when target is a dumb -;; busybox). Seems to be in `directory-files'. +;; * Fix `tramp-test27-start-file-process' on MS Windows (`process-send-eof'?). ;; * Fix Bug#16928. Set expected error of `tramp-test33-asynchronous-requests'. ;; * Fix `tramp-test35-unload' (Not all symbols are unbound). Set ;; expected error.