From f41097adf3e7155f9c0db6d90de0aa1623d89232 Mon Sep 17 00:00:00 2001
From: Michael Albinus <michael.albinus@gmx.de>
Date: Wed, 7 Dec 2016 17:16:57 +0100
Subject: [PATCH] Fix problems in quoting Tramp file names

* lisp/net/tramp.el (tramp-get-remote-tmpdir): Add also hop to result.
(tramp-unquote-shell-quote-argument): New defun.
(tramp-shell-quote-argument):
* lisp/net/tramp-sh.el (tramp-do-copy-or-rename-file-out-of-band)
(tramp-make-copy-program-file-name):
* lisp/net/tramp-smb.el (tramp-smb-handle-copy-directory)
(tramp-smb-handle-file-acl, tramp-smb-handle-set-file-acl)
(tramp-smb-shell-quote-argument): Use it.
---
 lisp/net/tramp-sh.el  |  9 +++++----
 lisp/net/tramp-smb.el | 19 ++++++++++++-------
 lisp/net/tramp.el     | 23 ++++++++++++++---------
 3 files changed, 31 insertions(+), 20 deletions(-)

diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el
index c87b4068630..a2949f1f204 100644
--- a/lisp/net/tramp-sh.el
+++ b/lisp/net/tramp-sh.el
@@ -2415,10 +2415,10 @@ The method used must be an out-of-band method."
 			'identity)
 		      (if t1
 			  (tramp-make-copy-program-file-name v)
-			(shell-quote-argument filename)))
+			(tramp-unquote-shell-quote-argument filename)))
 	      target (if t2
 			 (tramp-make-copy-program-file-name v)
-		       (shell-quote-argument newname)))
+		       (tramp-unquote-shell-quote-argument newname)))
 
 	;; Check for host and port number.  We cannot use
 	;; `tramp-file-name-port', because this returns also
@@ -5175,8 +5175,9 @@ Return ATTR."
      ((tramp-get-method-parameter vec 'tramp-remote-copy-program)
       localname)
      ((not (zerop (length user)))
-      (shell-quote-argument (format "%s@%s:%s" user host localname)))
-     (t (shell-quote-argument (format "%s:%s" host localname))))))
+      (tramp-unquote-shell-quote-argument
+       (format "%s@%s:%s" user host localname)))
+     (t (tramp-unquote-shell-quote-argument (format "%s:%s" host localname))))))
 
 (defun tramp-method-out-of-band-p (vec size)
   "Return t if this is an out-of-band method, nil otherwise."
diff --git a/lisp/net/tramp-smb.el b/lisp/net/tramp-smb.el
index e52296faaf7..d6d4669c912 100644
--- a/lisp/net/tramp-smb.el
+++ b/lisp/net/tramp-smb.el
@@ -478,15 +478,19 @@ pass to the OPERATION."
 		    (if t1
 			;; Source is remote.
 			(append args
-				(list "-D" (shell-quote-argument localname)
+				(list "-D" (tramp-unquote-shell-quote-argument
+					    localname)
 				      "-c" (shell-quote-argument "tar qc - *")
 				      "|" "tar" "xfC" "-"
-				      (shell-quote-argument tmpdir)))
+				      (tramp-unquote-shell-quote-argument
+				       tmpdir)))
 		      ;; Target is remote.
 		      (append (list "tar" "cfC" "-"
-				    (shell-quote-argument dirname) "." "|")
+				    (tramp-unquote-shell-quote-argument dirname)
+				    "." "|")
 			      args
-			      (list "-D" (shell-quote-argument localname)
+			      (list "-D" (tramp-unquote-shell-quote-argument
+					  localname)
 				    "-c" (shell-quote-argument "tar qx -")))))
 
 	      (unwind-protect
@@ -760,7 +764,8 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored."
 	    (setq args (append args (list "-s" tramp-smb-conf))))
 	  (setq
 	   args
-	   (append args (list (shell-quote-argument localname) "2>/dev/null")))
+	   (append args (list (tramp-unquote-shell-quote-argument localname)
+			      "2>/dev/null")))
 
 	  (unwind-protect
 	      (with-temp-buffer
@@ -1354,7 +1359,7 @@ target of the symlink differ."
 	    (setq args (append args (list "-s" tramp-smb-conf))))
 	  (setq
 	   args
-	   (append args (list (shell-quote-argument localname)
+	   (append args (list (tramp-unquote-shell-quote-argument localname)
 			      "&&" "echo" "tramp_exit_status" "0"
 			      "||" "echo" "tramp_exit_status" "1")))
 
@@ -2038,7 +2043,7 @@ Returns nil if an error message has appeared."
 (defun tramp-smb-shell-quote-argument (s)
   "Similar to `shell-quote-argument', but uses windows cmd syntax."
   (let ((system-type 'ms-dos))
-    (shell-quote-argument s)))
+    (tramp-unquote-shell-quote-argument s)))
 
 (add-hook 'tramp-unload-hook
 	  (lambda ()
diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el
index 1eb66cf59ef..48ae6e06000 100644
--- a/lisp/net/tramp.el
+++ b/lisp/net/tramp.el
@@ -4033,16 +4033,17 @@ be granted."
 
 (defun tramp-get-remote-tmpdir (vec)
   "Return directory for temporary files on the remote host identified by VEC."
-  (let ((dir (tramp-make-tramp-file-name
-	      (tramp-file-name-method vec)
-	      (tramp-file-name-user vec)
-	      (tramp-file-name-host vec)
-	      (or (tramp-get-method-parameter vec 'tramp-tmpdir) "/tmp"))))
-    (with-tramp-connection-property vec "tmpdir"
+  (with-tramp-connection-property vec "tmpdir"
+    (let ((dir (tramp-make-tramp-file-name
+		(tramp-file-name-method vec)
+		(tramp-file-name-user vec)
+		(tramp-file-name-host vec)
+		(or (tramp-get-method-parameter vec 'tramp-tmpdir) "/tmp")
+		(tramp-file-name-hop vec))))
       (or (and (file-directory-p dir) (file-writable-p dir)
 	       (file-remote-p dir 'localname))
-	  (tramp-error vec 'file-error "Directory %s not accessible" dir)))
-    dir))
+	  (tramp-error vec 'file-error "Directory %s not accessible" dir))
+      dir)))
 
 ;;;###tramp-autoload
 (defun tramp-make-tramp-temp-file (vec)
@@ -4304,6 +4305,10 @@ T1 and T2 are time values (as returned by `current-time' for example)."
   ;; Starting with Emacs 25.1, we could change this to use `time-subtract'.
   (float-time (tramp-compat-funcall 'subtract-time t1 t2)))
 
+(defun tramp-unquote-shell-quote-argument (s)
+  "Remove quotation prefix \"/:\" from string S, and quote it then for shell."
+  (shell-quote-argument (tramp-unquote-name s)))
+
 ;; Currently (as of Emacs 20.5), the function `shell-quote-argument'
 ;; does not deal well with newline characters.  Newline is replaced by
 ;; backslash newline.  But if, say, the string `a backslash newline b'
@@ -4335,7 +4340,7 @@ T1 and T2 are time values (as returned by `current-time' for example)."
 Only works for Bourne-like shells."
   (let ((system-type 'not-windows))
     (save-match-data
-      (let ((result (shell-quote-argument (tramp-unquote-name s)))
+      (let ((result (tramp-unquote-shell-quote-argument s))
 	    (nl (regexp-quote (format "\\%s" tramp-rsh-end-of-line))))
 	(when (and (>= (length result) 2)
 		   (string= (substring result 0 2) "\\~"))
-- 
2.39.5