]> code.delx.au - gnu-emacs/blobdiff - lisp/net/tramp-sh.el
* tramp-sh.el (tramp-sh-handle-file-acl): Do not redirect stderr
[gnu-emacs] / lisp / net / tramp-sh.el
index f3fdb63bb9ee3f66c62187b72ce708d15c90646a..7f7558e93b5935cf45a1e4756c454fd47a5ec5c9 100644 (file)
@@ -40,6 +40,7 @@
 (defvar vc-git-program)
 (defvar vc-hg-program)
 
+;;;###tramp-autoload
 (defcustom tramp-inline-compress-start-size 4096
   "The minimum size of compressing where inline transfer.
 When inline transfer, compress transferred data of file
@@ -48,6 +49,7 @@ If it is nil, no compression at all will be applied."
   :group 'tramp
   :type '(choice (const nil) integer))
 
+;;;###tramp-autoload
 (defcustom tramp-copy-size-limit 10240
   "The maximum file size where inline copying is preferred over an \
 out-of-the-band copy.
@@ -65,7 +67,7 @@ files conditionalize this setup based on the TERM environment variable."
   :type 'string)
 
 ;;;###tramp-autoload
-(defcustom tramp-histfile-override t
+(defcustom tramp-histfile-override ".tramp_history"
   "When invoking a shell, override the HISTFILE with this value.
 When setting to a string, it redirects the shell history to that
 file.  Be careful when setting to \"/dev/null\"; this might
@@ -105,6 +107,27 @@ detected as prompt when being sent on echoing hosts, therefore.")
 (defconst tramp-end-of-heredoc (md5 tramp-end-of-output)
   "String used to recognize end of heredoc strings.")
 
+;;;###tramp-autoload
+(defcustom tramp-use-ssh-controlmaster-options t
+  "Whether to use `tramp-ssh-controlmaster-options'."
+  :group 'tramp
+  :version "24.4"
+  :type 'boolean)
+
+(defvar tramp-ssh-controlmaster-options nil
+  "Which ssh Control* arguments to use.
+
+If it is a string, it should have the form
+\"-o ControlMaster=auto -o ControlPath='tramp.%%r@%%h:%%p'
+-o ControlPersist=no\".  Percent characters in the ControlPath
+spec must be doubled, because the string is used as format string.
+
+Otherwise, it will be auto-detected by Tramp, if
+`tramp-use-ssh-controlmaster-options' is non-nil.  The value
+depends on the installed local ssh version.
+
+The string is used in `tramp-methods'.")
+
 ;; Initialize `tramp-methods' with the supported methods.
 ;;;###tramp-autoload
 (add-to-list 'tramp-methods
@@ -112,6 +135,7 @@ detected as prompt when being sent on echoing hosts, therefore.")
     (tramp-login-program        "rsh")
     (tramp-login-args           (("%h") ("-l" "%u")))
     (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-login   ("-l"))
     (tramp-remote-shell-args    ("-c"))
     (tramp-copy-program         "rcp")
     (tramp-copy-args            (("-p" "%k") ("-r")))
@@ -123,6 +147,7 @@ detected as prompt when being sent on echoing hosts, therefore.")
     (tramp-login-program        "remsh")
     (tramp-login-args           (("%h") ("-l" "%u")))
     (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-login   ("-l"))
     (tramp-remote-shell-args    ("-c"))
     (tramp-copy-program         "rcp")
     (tramp-copy-args            (("-p" "%k")))
@@ -135,6 +160,7 @@ detected as prompt when being sent on echoing hosts, therefore.")
                                 ("-e" "none") ("%h")))
     (tramp-async-args           (("-q")))
     (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-login   ("-l"))
     (tramp-remote-shell-args    ("-c"))
     (tramp-copy-program         "scp")
     (tramp-copy-args            (("-P" "%p") ("-p" "%k") ("-q") ("-r") ("%c")))
@@ -152,6 +178,7 @@ detected as prompt when being sent on echoing hosts, therefore.")
                                 ("-e" "none") ("-t" "-t") ("%h") ("/bin/sh")))
     (tramp-async-args           (("-q")))
     (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-login   ("-l"))
     (tramp-remote-shell-args    ("-c"))
     (tramp-copy-program         "scp")
     (tramp-copy-args            (("-P" "%p") ("-p" "%k")
@@ -170,6 +197,7 @@ detected as prompt when being sent on echoing hosts, therefore.")
                                 ("-e" "none") ("%h")))
     (tramp-async-args           (("-q")))
     (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-login   ("-l"))
     (tramp-remote-shell-args    ("-c"))
     (tramp-copy-program         "rsync")
     (tramp-copy-args            (("-t" "%k") ("-r")))
@@ -183,6 +211,7 @@ detected as prompt when being sent on echoing hosts, therefore.")
     (tramp-login-program        "rsh")
     (tramp-login-args           (("%h") ("-l" "%u")))
     (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-login   ("-l"))
     (tramp-remote-shell-args    ("-c"))))
 ;;;###tramp-autoload
 (add-to-list 'tramp-methods
@@ -190,6 +219,7 @@ detected as prompt when being sent on echoing hosts, therefore.")
     (tramp-login-program        "remsh")
     (tramp-login-args           (("%h") ("-l" "%u")))
     (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-login   ("-l"))
     (tramp-remote-shell-args    ("-c"))))
 ;;;###tramp-autoload
 (add-to-list 'tramp-methods
@@ -199,6 +229,7 @@ detected as prompt when being sent on echoing hosts, therefore.")
                                 ("-e" "none") ("%h")))
     (tramp-async-args           (("-q")))
     (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-login   ("-l"))
     (tramp-remote-shell-args    ("-c"))
     (tramp-gw-args              (("-o" "GlobalKnownHostsFile=/dev/null")
                                 ("-o" "UserKnownHostsFile=/dev/null")
@@ -212,6 +243,7 @@ detected as prompt when being sent on echoing hosts, therefore.")
                                 ("-e" "none") ("-t" "-t") ("%h") ("/bin/sh")))
     (tramp-async-args           (("-q")))
     (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-login   ("-l"))
     (tramp-remote-shell-args    ("-c"))
     (tramp-gw-args              (("-o" "GlobalKnownHostsFile=/dev/null")
                                 ("-o" "UserKnownHostsFile=/dev/null")
@@ -223,6 +255,7 @@ detected as prompt when being sent on echoing hosts, therefore.")
     (tramp-login-program        "telnet")
     (tramp-login-args           (("%h") ("%p") ("2>/dev/null")))
     (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-login   ("-l"))
     (tramp-remote-shell-args    ("-c"))
     (tramp-default-port         23)))
 ;;;###tramp-autoload
@@ -231,6 +264,7 @@ detected as prompt when being sent on echoing hosts, therefore.")
     (tramp-login-program        "telnet")
     (tramp-login-args           (("%h") ("%p") ("2>/dev/null")))
     (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-login   ("-l"))
     (tramp-remote-shell-args    ("-c"))
     (tramp-copy-program         "nc")
     ;; We use "-v" for better error tracking.
@@ -239,7 +273,7 @@ detected as prompt when being sent on echoing hosts, therefore.")
     ;; 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
@@ -247,6 +281,7 @@ detected as prompt when being sent on echoing hosts, therefore.")
     (tramp-login-program        "su")
     (tramp-login-args           (("-") ("%u")))
     (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-login   ("-l"))
     (tramp-remote-shell-args    ("-c"))
     (tramp-connection-timeout   10)))
 ;;;###tramp-autoload
@@ -257,6 +292,7 @@ detected as prompt when being sent on echoing hosts, therefore.")
     ;; Local $SHELL could be a nasty one, like zsh or fish.  Let's override it.
     (tramp-login-env            (("SHELL") ("/bin/sh")))
     (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-login   ("-l"))
     (tramp-remote-shell-args    ("-c"))
     (tramp-connection-timeout   10)))
 ;;;###tramp-autoload
@@ -265,6 +301,7 @@ detected as prompt when being sent on echoing hosts, therefore.")
     (tramp-login-program        "ksu")
     (tramp-login-args           (("%u") ("-q")))
     (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-login   ("-l"))
     (tramp-remote-shell-args    ("-c"))
     (tramp-connection-timeout   10)))
 ;;;###tramp-autoload
@@ -273,6 +310,7 @@ detected as prompt when being sent on echoing hosts, therefore.")
     (tramp-login-program        "krlogin")
     (tramp-login-args           (("%h") ("-l" "%u") ("-x")))
     (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-login   ("-l"))
     (tramp-remote-shell-args    ("-c"))))
 ;;;###tramp-autoload
 (add-to-list 'tramp-methods
@@ -287,6 +325,7 @@ detected as prompt when being sent on echoing hosts, therefore.")
                                    tramp-initial-end-of-output))
                                 ("/bin/sh") ("\"")))
     (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-login   ("-l"))
     (tramp-remote-shell-args    ("-c"))
     (tramp-default-port         22)))
 ;;;###tramp-autoload
@@ -300,6 +339,7 @@ detected as prompt when being sent on echoing hosts, therefore.")
                                    tramp-initial-end-of-output))
                                 ("/bin/sh") ("\"")))
     (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-login   ("-l"))
     (tramp-remote-shell-args    ("-c"))))
 ;;;###tramp-autoload
 (add-to-list 'tramp-methods
@@ -313,6 +353,7 @@ detected as prompt when being sent on echoing hosts, therefore.")
                                    tramp-initial-end-of-output))
                                 ("/bin/sh") ("\"")))
     (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-login   ("-l"))
     (tramp-remote-shell-args    ("-c"))
     (tramp-copy-program         "pscp")
     (tramp-copy-args            (("-l" "%u") ("-P" "%p") ("-scp") ("-p" "%k")
@@ -332,6 +373,7 @@ detected as prompt when being sent on echoing hosts, therefore.")
                                    tramp-initial-end-of-output))
                                 ("/bin/sh") ("\"")))
     (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-login   ("-l"))
     (tramp-remote-shell-args    ("-c"))
     (tramp-copy-program         "pscp")
     (tramp-copy-args            (("-l" "%u") ("-P" "%p") ("-sftp") ("-p" "%k")
@@ -344,6 +386,7 @@ detected as prompt when being sent on echoing hosts, therefore.")
     (tramp-login-program        "fsh")
     (tramp-login-args           (("%h") ("-l" "%u") ("sh" "-i")))
     (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-login   ("-l"))
     (tramp-remote-shell-args    ("-i") ("-c"))
     (tramp-copy-program         "fcp")
     (tramp-copy-args            (("-p" "%k")))
@@ -473,7 +516,6 @@ as given in your `~/.profile'."
 (defcustom tramp-remote-process-environment
   `("TMOUT=0" "LC_CTYPE=''"
     ,(format "TERM=%s" tramp-terminal-type)
-    "EMACS=t" ;; Deprecated.
     ,(format "INSIDE_EMACS='%s,tramp:%s'" emacs-version tramp-version)
     "CDPATH=" "HISTORY=" "MAIL=" "MAILCHECK=" "MAILPATH=" "PAGER=cat"
     "autocorrect=" "correct=")
@@ -489,6 +531,7 @@ not be set here. Instead, it should be set via `tramp-remote-path'."
   :version "24.4"
   :type '(repeat string))
 
+;;;###tramp-autoload
 (defcustom tramp-sh-extra-args '(("/bash\\'" . "-norc -noprofile"))
   "Alist specifying extra arguments to pass to the remote shell.
 Entries are (REGEXP . ARGS) where REGEXP is a regular expression
@@ -631,6 +674,7 @@ if (!@stat) {
 if (($stat[2] & 0170000) == 0120000)
 {
     $type = readlink($ARGV[0]);
+    $type =~ s/\"/\\\\\"/g;
     $type = \"\\\"$type\\\"\";
 }
 elsif (($stat[2] & 0170000) == 040000)
@@ -680,6 +724,7 @@ for($i = 0; $i < $n; $i++)
     if (($stat[2] & 0170000) == 0120000)
     {
         $type = readlink($filename);
+        $type =~ s/\"/\\\\\"/g;
         $type = \"\\\"$type\\\"\";
     }
     elsif (($stat[2] & 0170000) == 040000)
@@ -692,6 +737,7 @@ for($i = 0; $i < $n; $i++)
     };
     $uid = ($ARGV[1] eq \"integer\") ? $stat[4] : \"\\\"\" . getpwuid($stat[4]) . \"\\\"\";
     $gid = ($ARGV[1] eq \"integer\") ? $stat[5] : \"\\\"\" . getgrgid($stat[5]) . \"\\\"\";
+    $filename =~ s/\"/\\\\\"/g;
     printf(
         \"(\\\"%%s\\\" %%s %%u %%s %%s (%%u %%u) (%%u %%u) (%%u %%u) %%u.0 %%u t (%%u . %%u) (%%u . %%u))\\n\",
         $filename,
@@ -1148,15 +1194,19 @@ target of the symlink differ."
     (tramp-message vec 5 "file attributes with ls: %s" localname)
     (tramp-send-command
      vec
-     (format "(%s %s || %s -h %s) && %s %s %s"
+     (format "(%s %s || %s -h %s) && %s %s %s %s"
             (tramp-get-file-exists-command vec)
             (tramp-shell-quote-argument localname)
             (tramp-get-test-command vec)
             (tramp-shell-quote-argument localname)
             (tramp-get-ls-command vec)
+            ;; On systems which have no quoting style, file names
+            ;; with special characters could fail.
+            (if (tramp-get-ls-command-with-quoting-style vec)
+                "--quoting-style=c" "")
             (if (eq id-format 'integer) "-ildn" "-ild")
             (tramp-shell-quote-argument localname)))
-    ;; parse `ls -l' output ...
+    ;; Parse `ls -l' output ...
     (with-current-buffer (tramp-get-buffer vec)
       (when (> (buffer-size) 0)
         (goto-char (point-min))
@@ -1195,11 +1245,14 @@ target of the symlink differ."
         ;; From the file modes, figure out other stuff.
         (setq symlinkp (eq ?l (aref res-filemodes 0)))
         (setq dirp (eq ?d (aref res-filemodes 0)))
-        ;; if symlink, find out file name pointed to
+        ;; If symlink, find out file name pointed to.
         (when symlinkp
           (search-forward "-> ")
-          (setq res-symlink-target (buffer-substring (point) (point-at-eol))))
-        ;; return data gathered
+          (setq res-symlink-target
+               (if (tramp-get-ls-command-with-quoting-style vec)
+                   (read (current-buffer))
+                 (buffer-substring (point) (point-at-eol)))))
+        ;; Return data gathered.
         (list
          ;; 0. t for directory, string (name linked to) for symbolic
          ;; link, or nil.
@@ -1222,9 +1275,9 @@ target of the symlink differ."
          ;; 8. File modes, as a string of ten letters or dashes as in ls -l.
          res-filemodes
          ;; 9. t if file's gid would change if file were deleted and
-         ;; recreated.  Will be set in `tramp-convert-file-attributes'
+         ;; recreated.  Will be set in `tramp-convert-file-attributes'.
          t
-         ;; 10. inode number.
+         ;; 10. Inode number.
          res-inode
          ;; 11. Device number.  Will be replaced by a virtual device number.
          -1
@@ -1248,16 +1301,21 @@ target of the symlink differ."
   (tramp-send-command-and-read
    vec
    (format
-    ;; On Opsware, pdksh (which is the true name of ksh there) doesn't
-    ;; parse correctly the sequence "((".  Therefore, we add a space.
-    "( (%s %s || %s -h %s) && %s -c '((\"%%N\") %%h %s %s %%Xe0 %%Ye0 %%Ze0 %%se0 \"%%A\" t %%ie0 -1)' %s || echo nil)"
+    (concat
+     ;; On Opsware, pdksh (which is the true name of ksh there)
+     ;; doesn't parse correctly the sequence "((".  Therefore, we add
+     ;; a space.  Apostrophes in the stat output are masked as "//",
+     ;; in order to make a proper shell escape of them in file names.
+     "( (%s %s || %s -h %s) && (%s -c "
+     "'((//%%N//) %%h %s %s %%Xe0 %%Ye0 %%Ze0 %%se0 //%%A// t %%ie0 -1)' "
+     "%s | sed -e 's/\"/\\\\\"/g' -e 's/\\/\\//\"/g') || echo nil)")
     (tramp-get-file-exists-command vec)
     (tramp-shell-quote-argument localname)
     (tramp-get-test-command vec)
     (tramp-shell-quote-argument localname)
     (tramp-get-remote-stat vec)
-    (if (eq id-format 'integer) "%ue0" "\"%U\"")
-    (if (eq id-format 'integer) "%ge0" "\"%G\"")
+    (if (eq id-format 'integer) "%ue0" "//%U//")
+    (if (eq id-format 'integer) "%ge0" "//%G//")
     (tramp-shell-quote-argument localname))))
 
 (defun tramp-sh-handle-set-visited-file-modtime (&optional time-list)
@@ -1349,6 +1407,7 @@ of."
 (defun tramp-sh-handle-set-file-modes (filename mode)
   "Like `set-file-modes' for Tramp files."
   (with-parsed-tramp-file-name filename nil
+    (tramp-flush-file-property v (file-name-directory localname))
     (tramp-flush-file-property v localname)
     ;; FIXME: extract the proper text from chmod's stderr.
     (tramp-barf-unless-okay
@@ -1363,6 +1422,7 @@ of."
   (if (tramp-tramp-file-p filename)
       (with-parsed-tramp-file-name filename nil
        (when (tramp-get-remote-touch v)
+         (tramp-flush-file-property v (file-name-directory localname))
          (tramp-flush-file-property v localname)
          (let ((time (if (or (null time) (equal time '(0 0)))
                          (current-time)
@@ -1421,12 +1481,14 @@ be non-negative integers."
                  (tramp-shell-quote-argument localname))))))
 
       ;; We handle also the local part, because there doesn't exist
-      ;; `set-file-uid-gid'.  On W32 "chown" might not work.
-      (let ((uid (or (and (natnump uid) uid) (tramp-get-local-uid 'integer)))
-           (gid (or (and (natnump gid) gid) (tramp-get-local-gid 'integer))))
-       (tramp-call-process
-        nil "chown" nil nil nil
-         (format "%d:%d" uid gid) (tramp-shell-quote-argument filename))))))
+      ;; `set-file-uid-gid'.  On W32 "chown" might not work.  We add a
+      ;; timeout for this.
+      (with-timeout (5 nil)
+       (let ((uid (or (and (natnump uid) uid) (tramp-get-local-uid 'integer)))
+             (gid (or (and (natnump gid) gid) (tramp-get-local-gid 'integer))))
+         (tramp-call-process
+          nil "chown" nil nil nil
+          (format "%d:%d" uid gid) (tramp-shell-quote-argument filename)))))))
 
 (defun tramp-remote-selinux-p (vec)
   "Check, whether SELINUX is enabled on the remote host."
@@ -1495,7 +1557,7 @@ be non-negative integers."
       (when (and (tramp-remote-acl-p v)
                 (tramp-send-command-and-check
                  v (format
-                    "getfacl -ac %s 2>/dev/null"
+                    "getfacl -ac %s"
                     (tramp-shell-quote-argument localname))))
        (with-current-buffer (tramp-get-connection-buffer v)
          (goto-char (point-max))
@@ -1520,7 +1582,7 @@ be non-negative integers."
        (progn
          (tramp-set-file-property v localname "file-acl" acl-string)
          t)
-      ;; In case of errors, we return `nil'.
+      ;; In case of errors, we return nil.
       (tramp-set-file-property v localname "file-acl-string" 'undef)
       nil)))
 
@@ -1626,45 +1688,44 @@ be non-negative integers."
 (defun tramp-sh-handle-directory-files-and-attributes
   (directory &optional full match nosort id-format)
   "Like `directory-files-and-attributes' for Tramp files."
-  (if (with-parsed-tramp-file-name directory nil
-       (not (or (tramp-get-remote-stat v) (tramp-get-remote-perl v))))
-      (tramp-handle-directory-files-and-attributes
-       directory full match nosort id-format)
-
-    ;; Do it directly.
-    (unless id-format (setq id-format 'integer))
-    (when (file-directory-p directory)
-      (setq directory (expand-file-name directory))
-      (let* ((temp
-             (copy-tree
-              (with-parsed-tramp-file-name directory nil
-                (with-tramp-file-property
-                    v localname
-                    (format "directory-files-and-attributes-%s" id-format)
-                  (save-excursion
-                    (mapcar
-                     (lambda (x)
-                       (cons (car x)
-                             (tramp-convert-file-attributes v (cdr x))))
-                     (cond
-                      ((tramp-get-remote-stat v)
-                       (tramp-do-directory-files-and-attributes-with-stat
-                        v localname id-format))
-                      ((tramp-get-remote-perl v)
-                       (tramp-do-directory-files-and-attributes-with-perl
-                        v localname id-format)))))))))
-            result item)
-
-       (while temp
-         (setq item (pop temp))
-         (when (or (null match) (string-match match (car item)))
-           (when full
-             (setcar item (expand-file-name (car item) directory)))
-           (push item result)))
-
-       (if nosort
-           result
-         (sort result (lambda (x y) (string< (car x) (car y)))))))))
+  (unless id-format (setq id-format 'integer))
+  (when (file-directory-p directory)
+    (setq directory (expand-file-name directory))
+    (let* ((temp
+           (copy-tree
+            (with-parsed-tramp-file-name directory nil
+              (with-tramp-file-property
+                  v localname
+                  (format "directory-files-and-attributes-%s" id-format)
+                (save-excursion
+                  (mapcar
+                   (lambda (x)
+                     (cons (car x)
+                           (tramp-convert-file-attributes v (cdr x))))
+                   (or
+                    (cond
+                     ((tramp-get-remote-stat v)
+                      (tramp-do-directory-files-and-attributes-with-stat
+                       v localname id-format))
+                     ((tramp-get-remote-perl v)
+                      (tramp-do-directory-files-and-attributes-with-perl
+                       v localname id-format))
+                     (t nil)))))))))
+          result item)
+
+      (while temp
+       (setq item (pop temp))
+       (when (or (null match) (string-match match (car item)))
+         (when full
+           (setcar item (expand-file-name (car item) directory)))
+         (push item result)))
+
+      (or (if nosort
+             result
+           (sort result (lambda (x y) (string< (car x) (car y)))))
+         ;; The scripts could fail, for example with huge file size.
+         (tramp-handle-directory-files-and-attributes
+          directory full match nosort id-format)))))
 
 (defun tramp-do-directory-files-and-attributes-with-perl
   (vec localname &optional id-format)
@@ -1691,17 +1752,22 @@ be non-negative integers."
     (concat
      ;; We must care about file names with spaces, or starting with
      ;; "-"; this would confuse xargs.  "ls -aQ" might be a solution,
-     ;; but it does not work on all remote systems.  Therefore, we
-     ;; quote the file names via sed.
-     "cd %s; echo \"(\"; (%s -a | sed -e s/\\$/\\\"/g -e s/^/\\\"/g | "
+     ;; but it does not work on all remote systems.  Apostrophes in
+     ;; the stat output are masked as "//", in order to make a proper
+     ;; shell escape of them in file names.
+     "cd %s && echo \"(\"; (%s %s -a | "
      "xargs %s -c "
-     "'(\"%%n\" (\"%%N\") %%h %s %s %%Xe0 %%Ye0 %%Ze0 %%se0 \"%%A\" t %%ie0 -1)'"
-     " 2>/dev/null); echo \")\"")
+     "'(//%%n// (//%%N//) %%h %s %s %%Xe0 %%Ye0 %%Ze0 %%se0 //%%A// t %%ie0 -1)' "
+     "-- 2>/dev/null | sed -e 's/\"/\\\\\"/g' -e 's/\\/\\//\"/g'); echo \")\"")
     (tramp-shell-quote-argument localname)
     (tramp-get-ls-command vec)
+    ;; On systems which have no quoting style, file names with
+    ;; special characters could fail.
+    (if (tramp-get-ls-command-with-quoting-style vec)
+       "--quoting-style=shell" "")
     (tramp-get-remote-stat vec)
-    (if (eq id-format 'integer) "%ue0" "\"%U\"")
-    (if (eq id-format 'integer) "%ge0" "\"%G\""))))
+    (if (eq id-format 'integer) "%ue0" "//%U//")
+    (if (eq id-format 'integer) "%ge0" "//%G//"))))
 
 ;; This function should return "foo/" for directories and "bar" for
 ;; files.
@@ -1772,7 +1838,7 @@ be non-negative integers."
                              1 0)))
 
               (format (concat
-                       "(\\cd %s 2>&1 && (%s %s -a 2>/dev/null"
+                       "(cd %s 2>&1 && (%s -a %s 2>/dev/null"
                        ;; `ls' with wildcard might fail with `Argument
                        ;; list too long' error in some corner cases; if
                        ;; `ls' fails after `cd' succeeded, chances are
@@ -1796,7 +1862,7 @@ be non-negative integers."
                       ;; sub-directories.
                       (if (zerop (length filename))
                           "."
-                        (concat (tramp-shell-quote-argument filename) "* -d"))
+                        (format "-d %s*" (tramp-shell-quote-argument filename)))
                       (tramp-get-ls-command v)
                       (tramp-get-test-command v))))
 
@@ -1913,7 +1979,7 @@ tramp-sh-handle-file-name-all-completions: internal error accessing `%s': `%s'"
        (t2 (tramp-tramp-file-p newname)))
     (with-parsed-tramp-file-name (if t1 dirname newname) nil
       (if (and (not copy-contents)
-              (tramp-get-method-parameter method 'tramp-copy-recursive)
+              (tramp-get-method-parameter v 'tramp-copy-recursive)
               ;; When DIRNAME and NEWNAME are remote, they must have
               ;; the same method.
               (or (null t1) (null t2)
@@ -2078,23 +2144,22 @@ file names."
 First arg OP is either `copy' or `rename' and indicates the operation.
 FILENAME is the source file, NEWNAME the target file.
 KEEP-DATE is non-nil if NEWNAME should have the same timestamp as FILENAME."
-  (with-temp-buffer
-    ;; We must disable multibyte, because binary data shall not be
-    ;; converted.  We remove `tramp-file-name-handler' from
-    ;; `inhibit-file-name-handlers'; otherwise the file name handler
-    ;; for `insert-file-contents' might be deactivated in some corner
-    ;; cases.
-    (set-buffer-multibyte nil)
-    (let ((coding-system-for-read 'binary)
-         (jka-compr-inhibit t)
-         (inhibit-file-name-handlers
-          (remq 'tramp-file-name-handler inhibit-file-name-handlers)))
-      (insert-file-contents-literally filename))
-    ;; We don't want the target file to be compressed, so we let-bind
-    ;; `jka-compr-inhibit' to t.
-    (let ((coding-system-for-write 'binary)
-         (jka-compr-inhibit t))
-      (write-region (point-min) (point-max) newname nil 'no-message)))
+  ;; We must disable multibyte, because binary data shall not be
+  ;; converted.  We don't want the target file to be compressed, so we
+  ;; let-bind `jka-compr-inhibit' to t.  `epa-file-handler' shall not
+  ;; be called either.  We remove `tramp-file-name-handler' from
+  ;; `inhibit-file-name-handlers'; otherwise the file name handler for
+  ;; `insert-file-contents' might be deactivated in some corner cases.
+  (let ((coding-system-for-read 'binary)
+       (coding-system-for-write 'binary)
+       (jka-compr-inhibit t)
+       (inhibit-file-name-operation 'write-region)
+       (inhibit-file-name-handlers
+        (cons 'epa-file-handler
+              (remq 'tramp-file-name-handler inhibit-file-name-handlers))))
+    (with-temp-file newname
+      (set-buffer-multibyte nil)
+      (insert-file-contents-literally filename)))
   ;; KEEP-DATE handling.
   (when keep-date (set-file-times newname (nth 5 (file-attributes filename))))
   ;; Set the mode.
@@ -2336,7 +2401,7 @@ The method used must be an out-of-band method."
                       (tramp-get-connection-property v "login-as" nil)))
 
        ;; Check for listener port.
-       (when (tramp-get-method-parameter method 'tramp-remote-copy-args)
+       (when (tramp-get-method-parameter v 'tramp-remote-copy-args)
          (setq listener (number-to-string (+ 50000 (random 10000))))
          (while
              (zerop (tramp-call-process v "nc" nil nil nil "-z" host listener))
@@ -2349,17 +2414,13 @@ The method used must be an out-of-band method."
              spec (format-spec-make
                    ?t (tramp-get-connection-property
                        (tramp-get-connection-process v) "temp-file" ""))
-             options (format-spec
-                      (if tramp-use-ssh-controlmaster-options
-                          tramp-ssh-controlmaster-options "")
-                      spec)
+             options (format-spec (tramp-ssh-controlmaster-options v) spec)
              spec (format-spec-make
                    ?h host ?u user ?p port ?r listener ?c options
                    ?k (if keep-date " " ""))
-             copy-program (tramp-get-method-parameter
-                           method 'tramp-copy-program)
+             copy-program (tramp-get-method-parameter v 'tramp-copy-program)
              copy-keep-date (tramp-get-method-parameter
-                             method 'tramp-copy-keep-date)
+                             v 'tramp-copy-keep-date)
 
              copy-args
              (delete
@@ -2368,9 +2429,7 @@ The method used must be an out-of-band method."
               ;; for the whole keep-date sublist.
               " "
               (dolist
-                  (x
-                   (tramp-get-method-parameter method 'tramp-copy-args)
-                   copy-args)
+                  (x (tramp-get-method-parameter v 'tramp-copy-args) copy-args)
                 (setq copy-args
                       (append
                        copy-args
@@ -2384,16 +2443,12 @@ The method used must be an out-of-band method."
                (lambda (x)
                  (setq x (mapcar (lambda (y) (format-spec y spec)) x))
                  (unless (member "" x) (mapconcat 'identity x " ")))
-               (tramp-get-method-parameter method 'tramp-copy-env)))
+               (tramp-get-method-parameter v 'tramp-copy-env)))
 
              remote-copy-program
-             (tramp-get-method-parameter method 'tramp-remote-copy-program))
+             (tramp-get-method-parameter v 'tramp-remote-copy-program))
 
-       (dolist
-           (x
-            (or
-             (tramp-get-connection-property v "remote-copy-args" nil)
-             (tramp-get-method-parameter method 'tramp-remote-copy-args)))
+       (dolist (x (tramp-get-method-parameter v 'tramp-remote-copy-args))
          (setq remote-copy-args
                (append
                 remote-copy-args
@@ -2424,10 +2479,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
@@ -2541,7 +2596,7 @@ The method used must be an out-of-band method."
     (tramp-flush-file-property v (file-name-directory localname))
     (tramp-flush-directory-property v localname)
     (tramp-barf-unless-okay
-     v (format "%s %s"
+     v (format "cd / && %s %s"
               (if recursive "rm -rf" "rmdir")
               (tramp-shell-quote-argument localname))
      "Couldn't delete %s" directory)))
@@ -2799,7 +2854,7 @@ the result will be a local, non-Tramp, file name."
          (setq uname
                (with-tramp-connection-property v uname
                  (tramp-send-command
-                  v (format "cd %s; pwd" (tramp-shell-quote-argument uname)))
+                  v (format "cd %s && pwd" (tramp-shell-quote-argument uname)))
                  (with-current-buffer (tramp-get-buffer v)
                    (goto-char (point-min))
                    (buffer-substring (point) (point-at-eol)))))
@@ -2858,10 +2913,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
@@ -3037,7 +3097,7 @@ the result will be a local, non-Tramp, file name."
          (unwind-protect
               (setq ret
                    (if (tramp-send-command-and-check
-                        v (format "\\cd %s; %s"
+                        v (format "cd %s && %s"
                                   (tramp-shell-quote-argument localname)
                                   command)
                         t t)
@@ -3067,9 +3127,9 @@ the result will be a local, non-Tramp, file name."
       (when tmpinput (delete-file tmpinput))
 
       ;; `process-file-side-effects' has been introduced with GNU
-      ;; Emacs 23.2.  If set to `nil', no remote file will be changed
+      ;; Emacs 23.2.  If set to nil, no remote file will be changed
       ;; by `program'.  If it doesn't exist, we assume its default
-      ;; value `t'.
+      ;; value t.
       (unless (and (boundp 'process-file-side-effects)
                   (not (symbol-value 'process-file-side-effects)))
         (tramp-flush-directory-property v ""))
@@ -3116,17 +3176,14 @@ the result will be a local, non-Tramp, file name."
                    ;; If local decoding is a function, we call it.
                    ;; We must disable multibyte, because
                    ;; `uudecode-decode-region' doesn't handle it
-                   ;; correctly.
-                   (with-temp-buffer
-                     (set-buffer-multibyte nil)
-                     (insert-buffer-substring (tramp-get-buffer v))
-                     (funcall loc-dec (point-min) (point-max))
-                     ;; Unset `file-name-handler-alist'.  Otherwise,
-                     ;; epa-file gets confused.
-                     (let (file-name-handler-alist
-                           (coding-system-for-write 'binary))
-                       (write-region
-                        (point-min) (point-max) tmpfile nil 'no-message)))
+                   ;; correctly.  Unset `file-name-handler-alist'.
+                   ;; Otherwise, epa-file gets confused.
+                   (let (file-name-handler-alist
+                         (coding-system-for-write 'binary))
+                     (with-temp-file tmpfile
+                       (set-buffer-multibyte nil)
+                       (insert-buffer-substring (tramp-get-buffer v))
+                       (funcall loc-dec (point-min) (point-max))))
 
                  ;; If tramp-decoding-function is not defined for this
                  ;; method, we invoke tramp-decoding-command instead.
@@ -3172,7 +3229,8 @@ the result will be a local, non-Tramp, file name."
         (if (fboundp 'find-buffer-file-type)
             (symbol-function 'find-buffer-file-type)
           nil))
-       (inhibit-file-name-handlers '(jka-compr-handler image-file-handler))
+       (inhibit-file-name-handlers
+        '(epa-file-handler image-file-handler jka-compr-handler))
        (inhibit-file-name-operation 'insert-file-contents))
     (unwind-protect
        (progn
@@ -3295,8 +3353,7 @@ the result will be a local, non-Tramp, file name."
              (if (and (not (stringp start))
                       (= (or end (point-max)) (point-max))
                       (= (or start (point-min)) (point-min))
-                      (tramp-get-method-parameter
-                       method 'tramp-copy-keep-tmpfile))
+                      (tramp-get-method-parameter v 'tramp-copy-keep-tmpfile))
                  (progn
                    (setq tramp-temp-buffer-file-name tmpfile)
                    (condition-case err
@@ -3702,29 +3759,22 @@ Only send the definition if it has not already been done."
                  (tramp-get-connection-process vec) "scripts" nil)))
     (unless (member name scripts)
       (with-tramp-progress-reporter vec 5 (format "Sending script `%s'" name)
+       ;; In bash, leading TABs like in `tramp-vc-registered-read-file-names'
+       ;; could result in unwanted command expansion.  Avoid this.
+       (setq script (tramp-compat-replace-regexp-in-string
+                     (make-string 1 ?\t) (make-string 8 ? ) script))
        ;; The script could contain a call of Perl.  This is masked with `%s'.
        (when (and (string-match "%s" script)
                   (not (tramp-get-remote-perl vec)))
          (tramp-error vec 'file-error "No Perl available on remote host"))
        (tramp-barf-unless-okay
         vec
-        (format "%s () {\n%s\n}" name
-                (format script (tramp-get-remote-perl vec)))
+        (format "%s () {\n%s\n}"
+                name (format script (tramp-get-remote-perl vec)))
         "Script %s sending failed" name)
        (tramp-set-connection-property
         (tramp-get-connection-process vec) "scripts" (cons name scripts))))))
 
-(defun tramp-set-auto-save ()
-  (when (and ;; ange-ftp has its own auto-save mechanism
-            (eq (tramp-find-foreign-file-name-handler (buffer-file-name))
-                'tramp-sh-file-name-handler)
-             auto-save-default)
-    (auto-save-mode 1)))
-(add-hook 'find-file-hooks 'tramp-set-auto-save t)
-(add-hook 'tramp-unload-hook
-         (lambda ()
-           (remove-hook 'find-file-hooks 'tramp-set-auto-save)))
-
 (defun tramp-run-test (switch filename)
   "Run `test' on the remote system, given a SWITCH and a FILENAME.
 Returns the exit code of the `test' program."
@@ -3921,12 +3971,7 @@ file exists and nonzero exit status otherwise."
 (defun tramp-find-shell (vec)
   "Opens a shell on the remote host which groks tilde expansion."
   (with-current-buffer (tramp-get-buffer vec)
-    (let ((default-shell
-           (or
-            (tramp-get-connection-property
-             (tramp-get-connection-process vec) "remote-shell" nil)
-            (tramp-get-method-parameter
-             (tramp-file-name-method vec) 'tramp-remote-shell)))
+    (let ((default-shell (tramp-get-method-parameter vec 'tramp-remote-shell))
          shell)
       (setq shell
            (with-tramp-connection-property vec "remote-shell"
@@ -3985,15 +4030,11 @@ seconds.  If not, it produces an error message with the given ERROR-ARGS."
 Mainly sets the prompt and the echo correctly.  PROC is the shell
 process to set up.  VEC specifies the connection."
   (let ((tramp-end-of-output tramp-initial-end-of-output))
-    (tramp-open-shell
-     vec
-     (or (tramp-get-connection-property vec "remote-shell" nil)
-        (tramp-get-method-parameter
-         (tramp-file-name-method vec) 'tramp-remote-shell)))
+    (tramp-open-shell vec (tramp-get-method-parameter vec 'tramp-remote-shell))
 
-    ;; Disable echo.
+    ;; Disable tab and echo expansion.
     (tramp-message vec 5 "Setting up remote shell environment")
-    (tramp-send-command vec "stty -inlcr -echo kill '^U' erase '^H'" t)
+    (tramp-send-command vec "stty tab0 -inlcr -echo kill '^U' erase '^H'" t)
     ;; Check whether the echo has really been disabled.  Some
     ;; implementations, like busybox of embedded GNU/Linux, don't
     ;; support disabling.
@@ -4526,15 +4567,9 @@ Gateway hops are already opened."
     ;; Foreign and out-of-band methods are not supported for multi-hops.
     (when (cdr target-alist)
       (setq choices target-alist)
-      (while choices
-       (setq item (pop choices))
-       (when
-           (or
-            (not
-             (tramp-get-method-parameter
-              (tramp-file-name-method item) 'tramp-login-program))
-            (tramp-get-method-parameter
-             (tramp-file-name-method item) 'tramp-copy-program))
+      (while (setq item (pop choices))
+       (when (or (not (tramp-get-method-parameter item 'tramp-login-program))
+                 (tramp-get-method-parameter item 'tramp-copy-program))
          (tramp-error
           vec 'file-error
           "Method `%s' is not supported for multi-hops."
@@ -4542,7 +4577,7 @@ Gateway hops are already opened."
 
     ;; In case the host name is not used for the remote shell
     ;; command, the user could be misguided by applying a random
-    ;; hostname.
+    ;; host name.
     (let* ((v (car target-alist))
           (method (tramp-file-name-method v))
           (host (tramp-file-name-host v)))
@@ -4551,8 +4586,7 @@ Gateway hops are already opened."
           ;; There are multi-hops.
           (cdr target-alist)
           ;; The host name is used for the remote shell command.
-          (member
-           '("%h") (tramp-get-method-parameter method 'tramp-login-args))
+          (member '("%h") (tramp-get-method-parameter v 'tramp-login-args))
           ;; The host is local.  We cannot use `tramp-local-host-p'
           ;; here, because it opens a connection as well.
           (string-match tramp-local-host-regexp host))
@@ -4564,6 +4598,48 @@ Gateway hops are already opened."
     ;; Result.
     target-alist))
 
+(defun tramp-ssh-controlmaster-options (vec)
+  "Return the Control* arguments of the local ssh."
+  (cond
+   ;; No options to be computed.
+   ((or (null tramp-use-ssh-controlmaster-options)
+       (null (assoc "%c" (tramp-get-method-parameter vec 'tramp-login-args))))
+    "")
+
+   ;; There is already a value to be used.
+   ((stringp tramp-ssh-controlmaster-options) tramp-ssh-controlmaster-options)
+
+   ;; Determine the options.
+   (t (setq tramp-ssh-controlmaster-options "")
+      (let ((case-fold-search t))
+       (ignore-errors
+         (when (executable-find "ssh")
+           (with-temp-buffer
+             (tramp-call-process vec "ssh" nil t nil "-o" "ControlMaster")
+             (goto-char (point-min))
+             (when (search-forward-regexp "missing.+argument" nil t)
+               (setq tramp-ssh-controlmaster-options "-o ControlMaster=auto")))
+           (unless (zerop (length tramp-ssh-controlmaster-options))
+             (with-temp-buffer
+               ;; We use a non-existing IP address, in order to avoid
+               ;; useless connections, and DNS timeouts.
+               (tramp-call-process
+                vec "ssh" nil t nil "-o" "ControlPath=%C" "0.0.0.1")
+               (goto-char (point-min))
+               (setq tramp-ssh-controlmaster-options
+                     (concat tramp-ssh-controlmaster-options
+                             (if (search-forward-regexp "unknown.+key" nil t)
+                                 " -o ControlPath='tramp.%%r@%%h:%%p'"
+                               " -o ControlPath='tramp.%%C'"))))
+             (with-temp-buffer
+               (tramp-call-process vec "ssh" nil t nil "-o" "ControlPersist")
+               (goto-char (point-min))
+               (when (search-forward-regexp "missing.+argument" nil t)
+                 (setq tramp-ssh-controlmaster-options
+                       (concat tramp-ssh-controlmaster-options
+                               " -o ControlPersist=no"))))))))
+      tramp-ssh-controlmaster-options)))
+
 (defun tramp-maybe-open-connection (vec)
   "Maybe open a connection VEC.
 Does not do anything if a connection is already open, but re-opens the
@@ -4645,8 +4721,7 @@ connection if a previous connection has died for some reason."
              (let* ((target-alist (tramp-compute-multi-hops vec))
                     ;; We will apply `tramp-ssh-controlmaster-options'
                     ;; only for the first hop.
-                    (options (if tramp-use-ssh-controlmaster-options
-                                 tramp-ssh-controlmaster-options ""))
+                    (options (tramp-ssh-controlmaster-options vec))
                     (process-connection-type tramp-process-connection-type)
                     (process-adaptive-read-buffering nil)
                     (coding-system-for-read nil)
@@ -4687,22 +4762,18 @@ connection if a previous connection has died for some reason."
                         (l-host (tramp-file-name-host hop))
                         (l-port nil)
                         (login-program
-                         (tramp-get-method-parameter
-                          l-method 'tramp-login-program))
+                         (tramp-get-method-parameter hop 'tramp-login-program))
                         (login-args
-                         (tramp-get-method-parameter
-                          l-method 'tramp-login-args))
+                         (tramp-get-method-parameter hop 'tramp-login-args))
                         (login-env
-                         (tramp-get-method-parameter
-                          l-method 'tramp-login-env))
+                         (tramp-get-method-parameter hop 'tramp-login-env))
                         (async-args
-                         (tramp-get-method-parameter
-                          l-method 'tramp-async-args))
+                         (tramp-get-method-parameter hop 'tramp-async-args))
                         (connection-timeout
                          (tramp-get-method-parameter
-                          l-method 'tramp-connection-timeout))
+                          hop 'tramp-connection-timeout))
                         (gw-args
-                         (tramp-get-method-parameter l-method 'tramp-gw-args))
+                         (tramp-get-method-parameter hop 'tramp-gw-args))
                         (gw (let ((tramp-verbose 0))
                               (tramp-get-file-property hop "" "gateway" nil)))
                         (g-method (and gw (tramp-file-name-method gw)))
@@ -4890,8 +4961,8 @@ function waits for output unless NOOUTPUT is set."
   (vec command &optional subshell dont-suppress-err)
   "Run COMMAND and check its exit status.
 Sends `echo $?' along with the COMMAND for checking the exit status.
-If COMMAND is nil, just sends `echo $?'.  Returns `t' if the exit
-status is 0, and `nil' otherwise.
+If COMMAND is nil, just sends `echo $?'.  Returns t if the exit
+status is 0, and nil otherwise.
 
 If the optional argument SUBSHELL is non-nil, the command is
 executed in a subshell, ie surrounded by parentheses.  If
@@ -5040,14 +5111,17 @@ Return ATTR."
    ""))
 
 (defun tramp-make-copy-program-file-name (vec)
-  "Create a file name suitable to be passed to `scp' or `nc' and workalikes."
+  "Create a file name suitable for `scp', `pscp', or `nc' and workalikes."
   (let ((method (tramp-file-name-method vec))
        (user (tramp-file-name-user vec))
        (host (tramp-file-name-real-host vec))
-       (localname (tramp-shell-quote-argument
-                   (tramp-file-name-localname vec))))
+       (localname (tramp-file-name-localname vec)))
+    (when (string-match tramp-ipv6-regexp host)
+      (setq host (format "[%s]" host)))
+    (unless (string-match "ftp$" method)
+      (setq localname (tramp-shell-quote-argument localname)))
     (cond
-     ((tramp-get-method-parameter method 'tramp-remote-copy-program)
+     ((tramp-get-method-parameter vec 'tramp-remote-copy-program)
       localname)
      ((not (zerop (length user)))
       (shell-quote-argument (format "%s@%s:%s" user host localname)))
@@ -5057,7 +5131,7 @@ Return ATTR."
   "Return t if this is an out-of-band method, nil otherwise."
   (and
    ;; It shall be an out-of-band method.
-   (tramp-get-method-parameter (tramp-file-name-method vec) 'tramp-copy-program)
+   (tramp-get-method-parameter vec 'tramp-copy-program)
    ;; There must be a size, otherwise the file doesn't exist.
    (numberp size)
    ;; Either the file size is large enough, or (in rare cases) there
@@ -5099,13 +5173,15 @@ Return ATTR."
              (tramp-send-command-and-read
               vec
               (format
-               "%s -l %s 'echo %s \\\"$PATH\\\"'"
-               (tramp-get-method-parameter
-                (tramp-file-name-method vec) 'tramp-remote-shell)
+               "%s %s %s 'echo %s \\\"$PATH\\\"'"
+               (tramp-get-method-parameter vec 'tramp-remote-shell)
                (mapconcat
                 'identity
-                (tramp-get-method-parameter
-                 (tramp-file-name-method vec) 'tramp-remote-shell-args)
+                (tramp-get-method-parameter vec 'tramp-remote-shell-login)
+                " ")
+               (mapconcat
+                'identity
+                (tramp-get-method-parameter vec 'tramp-remote-shell-args)
                 " ")
                (tramp-shell-quote-argument tramp-end-of-heredoc))
               nil (regexp-quote tramp-end-of-heredoc)))))
@@ -5157,7 +5233,8 @@ Return ATTR."
       (with-current-buffer (tramp-get-connection-buffer vec)
        (while candidates
          (goto-char (point-min))
-         (if (string-match (concat "^" (car candidates) "$") (buffer-string))
+         (if (string-match (format "^%s\r?$" (regexp-quote (car candidates)))
+                           (buffer-string))
              (setq locale (car candidates)
                    candidates nil)
            (setq candidates (cdr candidates)))))
@@ -5199,6 +5276,17 @@ Return ATTR."
       (tramp-send-command-and-check
        vec (format "%s --dired -al /dev/null" (tramp-get-ls-command vec))))))
 
+(defun tramp-get-ls-command-with-quoting-style (vec)
+  (save-match-data
+    (with-tramp-connection-property vec "ls-quoting-style"
+      (tramp-message vec 5 "Checking, whether `ls --quoting-style=shell' works")
+      ;; Some "ls" versions are sensible wrt the order of arguments,
+      ;; they fail when "-al" is after the "--dired" argument (for
+      ;; example on FreeBSD).
+      (tramp-send-command-and-check
+       vec (format "%s --quoting-style=shell -al /dev/null"
+                  (tramp-get-ls-command vec))))))
+
 (defun tramp-get-test-command (vec)
   (with-tramp-connection-property vec "test"
     (tramp-message vec 5 "Finding a suitable `test' command")
@@ -5456,7 +5544,7 @@ If no corresponding command is found, nil is returned.
 Otherwise, either a string is returned which contains a `%s' mark
 to be used for the respective input or output file; or a Lisp
 function cell is returned to be applied on a buffer."
-  ;; We must catch the errors, because we want to return `nil', when
+  ;; We must catch the errors, because we want to return nil, when
   ;; no inline coding is found.
   (ignore-errors
     (let ((coding
@@ -5486,16 +5574,20 @@ function cell is returned to be applied on a buffer."
              `(lambda (beg end)
                 (,coding beg end)
                 (let ((coding-system-for-write 'binary)
-                      (coding-system-for-read 'binary))
+                      (coding-system-for-read 'binary)
+                      (default-directory
+                        (tramp-compat-temporary-file-directory)))
                   (apply
-                   'call-process-region (point-min) (point-max)
+                   'tramp-call-process-region ,vec (point-min) (point-max)
                    (car (split-string ,compress)) t t nil
                    (cdr (split-string ,compress)))))
            `(lambda (beg end)
               (let ((coding-system-for-write 'binary)
-                    (coding-system-for-read 'binary))
+                    (coding-system-for-read 'binary)
+                    (default-directory
+                      (tramp-compat-temporary-file-directory)))
                 (apply
-                 'call-process-region beg end
+                 'tramp-call-process-region ,vec beg end
                  (car (split-string ,compress)) t t nil
                  (cdr (split-string ,compress))))
               (,coding (point-min) (point-max)))))
@@ -5541,8 +5633,6 @@ function cell is returned to be applied on a buffer."
 ;; * Don't use globbing for directories with many files, as this is
 ;;   likely to produce long command lines, and some shells choke on
 ;;   long command lines.
-;; * Make it work for different encodings, and for different file name
-;;   encodings, too.  (Daniel Pittman)
 ;; * Don't search for perl5 and perl.  Instead, only search for perl and
 ;;   then look if it's the right version (with `perl -v').
 ;; * When editing a remote CVS controlled file as a different user, VC