]> code.delx.au - gnu-emacs/blobdiff - lisp/net/tramp-sh.el
-
[gnu-emacs] / lisp / net / tramp-sh.el
index 580c5d08ecdb56133516f2e7bc797c7c4e4bfd5c..baebb13dd228352d0551a40dc724ed2d8886164b 100644 (file)
@@ -1,6 +1,6 @@
 ;;; tramp-sh.el --- Tramp access functions for (s)sh-like connections
 
-;; Copyright (C) 1998-2015 Free Software Foundation, Inc.
+;; Copyright (C) 1998-2016 Free Software Foundation, Inc.
 
 ;; (copyright statements below in code to be updated with the above notice)
 
@@ -32,7 +32,6 @@
 (eval-when-compile
   (require 'cl)
   (require 'dired))
-(defvar directory-sep-char)
 (defvar tramp-gw-tunnel-method)
 (defvar tramp-gw-socks-method)
 (defvar vc-handled-backends)
@@ -40,6 +39,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 +48,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 +66,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
@@ -95,7 +96,7 @@ e.g. \"$HOME/.sh_history\"."
    "///%s#$"
    (md5 (concat (prin1-to-string process-environment) (current-time-string))))
   "String used to recognize end of output.
-The '$' character at the end is quoted; the string cannot be
+The `$' character at the end is quoted; the string cannot be
 detected as prompt when being sent on echoing hosts, therefore.")
 
 ;;;###tramp-autoload
@@ -105,6 +106,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 +134,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 +146,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 +159,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 +177,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 +196,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 +210,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 +218,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 +228,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 +242,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 +254,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 +263,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 +272,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,16 +280,30 @@ 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
+(add-to-list
+ 'tramp-methods
+ '("sg"
+   (tramp-login-program        "sg")
+   (tramp-login-args           (("-") ("%u")))
+   (tramp-remote-shell         "/bin/sh")
+   (tramp-remote-shell-args    ("-c"))
+   (tramp-connection-timeout   10)))
+;;;###tramp-autoload
 (add-to-list 'tramp-methods
   '("sudo"
     (tramp-login-program        "sudo")
-    (tramp-login-args           (("-u" "%u") ("-s") ("-H") ("-p" "Password:")))
+    ;; The password template must be masked.  Otherwise, it could be
+    ;; interpreted as password prompt if the remote host echoes the command.
+    (tramp-login-args           (("-u" "%u") ("-s") ("-H")
+                                ("-p" "P\"\"a\"\"s\"\"s\"\"w\"\"o\"\"r\"\"d\"\":")))
     ;; 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 +312,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 +321,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 +336,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 +350,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 +364,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,18 +384,19 @@ 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")
-                                ("-q") ("-r")))
-    (tramp-copy-keep-date       t)
-    (tramp-copy-recursive       t)))
+                                ("-q")))
+    (tramp-copy-keep-date       t)))
 ;;;###tramp-autoload
 (add-to-list 'tramp-methods
   '("fcp"
     (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")))
@@ -400,13 +453,18 @@ detected as prompt when being sent on echoing hosts, therefore.")
   '((tramp-parse-passwd "/etc/passwd"))
   "Default list of (FUNCTION FILE) pairs to be examined for su methods.")
 
+;;;###tramp-autoload
+(defconst tramp-completion-function-alist-sg
+  '((tramp-parse-etc-group "/etc/group"))
+  "Default list of (FUNCTION FILE) pairs to be examined for sg methods.")
+
 ;;;###tramp-autoload
 (defconst tramp-completion-function-alist-putty
   `((tramp-parse-putty
      ,(if (memq system-type '(windows-nt))
          "HKEY_CURRENT_USER\\Software\\SimonTatham\\PuTTY\\Sessions"
        "~/.putty/sessions")))
 "Default list of (FUNCTION REGISTRY) pairs to be examined for putty sessions.")
+ "Default list of (FUNCTION REGISTRY) pairs to be examined for putty sessions.")
 
 ;;;###tramp-autoload
 (eval-after-load 'tramp
@@ -426,6 +484,7 @@ detected as prompt when being sent on echoing hosts, therefore.")
      (tramp-set-completion-function "su" tramp-completion-function-alist-su)
      (tramp-set-completion-function "sudo" tramp-completion-function-alist-su)
      (tramp-set-completion-function "ksu" tramp-completion-function-alist-su)
+     (tramp-set-completion-function "sg" tramp-completion-function-alist-sg)
      (tramp-set-completion-function
       "krlogin" tramp-completion-function-alist-rsh)
      (tramp-set-completion-function "plink" tramp-completion-function-alist-ssh)
@@ -440,6 +499,7 @@ detected as prompt when being sent on echoing hosts, therefore.")
 ;; Solaris: /usr/xpg4/bin:/usr/ccs/bin:/usr/bin:/opt/SUNWspro/bin
 ;; GNU/Linux (Debian, Suse): /bin:/usr/bin
 ;; FreeBSD: /usr/bin:/bin:/usr/sbin:/sbin: - beware trailing ":"!
+;; Darwin: /usr/bin:/bin:/usr/sbin:/sbin
 ;; IRIX64: /usr/bin
 ;;;###tramp-autoload
 (defcustom tramp-remote-path
@@ -473,7 +533,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 +548,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
@@ -551,9 +611,14 @@ we have this shell function.")
 use File::Spec;
 use Cwd \"realpath\";
 
+sub myrealpath {
+    my ($file) = @_;
+    return realpath($file) if -e $file;
+}
+
 sub recursive {
     my ($volume, @dirs) = @_;
-    my $real = realpath(File::Spec->catpath(
+    my $real = myrealpath(File::Spec->catpath(
                    $volume, File::Spec->catdir(@dirs), \"\"));
     if ($real) {
         my ($vol, $dir) = File::Spec->splitpath($real, 1);
@@ -567,7 +632,7 @@ sub recursive {
     }
 }
 
-$result = realpath($ARGV[0]);
+$result = myrealpath($ARGV[0]);
 if (!$result) {
     my ($vol, $dir) = File::Spec->splitpath($ARGV[0], 1);
     ($vol, @dirs) = recursive($vol, File::Spec->splitdir($dir));
@@ -575,10 +640,7 @@ if (!$result) {
     $result = File::Spec->catpath($vol, File::Spec->catdir(@dirs), \"\");
 }
 
-if ($ARGV[0] =~ /\\/$/) {
-    $result = $result . \"/\";
-}
-
+$result =~ s/\"/\\\\\"/g;
 print \"\\\"$result\\\"\\n\";
 ' \"$1\" 2>/dev/null"
   "Perl script to produce output suitable for use with `file-truename'
@@ -741,7 +803,7 @@ on the remote host.")
 (defconst tramp-perl-encode
   "%s -e '
 # This script contributed by Juanma Barranquero <lektu@terra.es>.
-# Copyright (C) 2002-2015 Free Software Foundation, Inc.
+# Copyright (C) 2002-2016 Free Software Foundation, Inc.
 use strict;
 
 my %%trans = do {
@@ -779,7 +841,7 @@ This string is passed to `format', so percent characters need to be doubled.")
 (defconst tramp-perl-decode
   "%s -e '
 # This script contributed by Juanma Barranquero <lektu@terra.es>.
-# Copyright (C) 2002-2015 Free Software Foundation, Inc.
+# Copyright (C) 2002-2016 Free Software Foundation, Inc.
 use strict;
 
 my %%trans = do {
@@ -830,6 +892,78 @@ Escape sequence %s is replaced with name of Perl binary.")
   "Perl program to use for decoding a file.
 Escape sequence %s is replaced with name of Perl binary.")
 
+(defconst tramp-awk-encode
+  "od -v -t x1 -A n | busybox awk '\\
+BEGIN {
+  b64 = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\"
+  b16 = \"0123456789abcdef\"
+}
+{
+  for (c=1; c<=length($0); c++) {
+    d=index(b16, substr($0,c,1))
+    if (d--) {
+      for (b=1; b<=4; b++) {
+        o=o*2+int(d/8); d=(d*2)%%16
+        if (++obc==6) {
+          printf substr(b64,o+1,1)
+          if (++rc>75) { printf \"\\n\"; rc=0 }
+          obc=0; o=0
+        }
+      }
+    }
+  }
+}
+END {
+  if (obc) {
+    tail=(obc==2) ? \"==\\n\" : \"=\\n\"
+    while (obc++<6) { o=o*2 }
+    printf \"%%c\", substr(b64,o+1,1)
+  } else {
+    tail=\"\\n\"
+  }
+  printf tail
+}'"
+  "Awk program to use for encoding a file.
+This string is passed to `format', so percent characters need to be doubled.")
+
+(defconst tramp-awk-decode
+  "busybox awk '\\
+BEGIN {
+  b64 = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\"
+}
+{
+  for (i=1; i<=length($0); i++) {
+    c=index(b64, substr($0,i,1))
+    if(c--) {
+      for(b=0; b<6; b++) {
+        o=o*2+int(c/32); c=(c*2)%%64
+        if(++obc==8) {
+          if (o) {
+            printf \"%%c\", o
+          } else {
+            system(\"dd if=/dev/zero bs=1 count=1 2>/dev/null\")
+          }
+          obc=0; o=0
+        }
+      }
+    }
+  }
+}'"
+  "Awk program to use for decoding a file.
+This string is passed to `format', so percent characters need to be doubled.")
+
+(defconst tramp-awk-coding-test
+  "test -c /dev/zero && \
+od -v -t x1 -A n </dev/null && \
+busybox awk '{}' </dev/null"
+  "Test command for checking `tramp-awk-encode' and `tramp-awk-decode'.")
+
+(defconst tramp-stat-marker "/////"
+  "Marker in stat commands for file attributes.")
+
+(defconst tramp-stat-quoted-marker "\\/\\/\\/\\/\\/"
+  "Quoted marker in stat commands for file attributes.")
+
 (defconst tramp-vc-registered-read-file-names
   "echo \"(\"
 while read file; do
@@ -865,20 +999,17 @@ of command line.")
     (directory-files . tramp-handle-directory-files)
     (directory-files-and-attributes
      . tramp-sh-handle-directory-files-and-attributes)
-    ;; `dired-call-process' performed by default handler.
     (dired-compress-file . tramp-sh-handle-dired-compress-file)
-    (dired-recursive-delete-directory
-     . tramp-sh-handle-dired-recursive-delete-directory)
     (dired-uncache . tramp-handle-dired-uncache)
     (expand-file-name . tramp-sh-handle-expand-file-name)
     (file-accessible-directory-p . tramp-handle-file-accessible-directory-p)
     (file-acl . tramp-sh-handle-file-acl)
     (file-attributes . tramp-sh-handle-file-attributes)
     (file-directory-p . tramp-sh-handle-file-directory-p)
-    ;; `file-equal-p' performed by default handler.
+    (file-equal-p . tramp-handle-file-equal-p)
     (file-executable-p . tramp-sh-handle-file-executable-p)
     (file-exists-p . tramp-sh-handle-file-exists-p)
-    ;; `file-in-directory-p' performed by default handler.
+    (file-in-directory-p . tramp-handle-file-in-directory-p)
     (file-local-copy . tramp-sh-handle-file-local-copy)
     (file-modes . tramp-handle-file-modes)
     (file-name-all-completions . tramp-sh-handle-file-name-all-completions)
@@ -890,6 +1021,7 @@ of command line.")
     (file-newer-than-file-p . tramp-sh-handle-file-newer-than-file-p)
     (file-notify-add-watch . tramp-sh-handle-file-notify-add-watch)
     (file-notify-rm-watch . tramp-handle-file-notify-rm-watch)
+    (file-notify-valid-p . tramp-handle-file-notify-valid-p)
     (file-ownership-preserved-p . tramp-sh-handle-file-ownership-preserved-p)
     (file-readable-p . tramp-sh-handle-file-readable-p)
     (file-regular-p . tramp-handle-file-regular-p)
@@ -903,8 +1035,6 @@ of command line.")
     ;; `get-file-buffer' performed by default handler.
     (insert-directory . tramp-sh-handle-insert-directory)
     (insert-file-contents . tramp-handle-insert-file-contents)
-    (insert-file-contents-literally
-     . tramp-sh-handle-insert-file-contents-literally)
     (load . tramp-handle-load)
     (make-auto-save-file-name . tramp-handle-make-auto-save-file-name)
     (make-directory . tramp-sh-handle-make-directory)
@@ -919,7 +1049,7 @@ of command line.")
     (shell-command . tramp-handle-shell-command)
     (start-file-process . tramp-sh-handle-start-file-process)
     (substitute-in-file-name . tramp-handle-substitute-in-file-name)
-    (unhandled-file-name-directory . tramp-handle-unhandled-file-name-directory)
+    (unhandled-file-name-directory . ignore)
     (vc-registered . tramp-sh-handle-vc-registered)
     (verify-visited-file-modtime . tramp-sh-handle-verify-visited-file-modtime)
     (write-region . tramp-sh-handle-write-region))
@@ -978,15 +1108,19 @@ target of the symlink differ."
       ;; Right, they are on the same host, regardless of user, method,
       ;; etc.  We now make the link on the remote machine. This will
       ;; occur as the user that FILENAME belongs to.
-      (tramp-send-command-and-check
-       l
-       (format
-       "cd %s && %s -sf %s %s"
-       (tramp-shell-quote-argument cwd)
-       ln
-       (tramp-shell-quote-argument filename)
-       (tramp-shell-quote-argument l-localname))
-       t))))
+      (and (tramp-send-command-and-check
+            l (format "cd %s" (tramp-shell-quote-argument cwd)))
+           (tramp-send-command-and-check
+            l (format
+               "%s -sf %s %s"
+               ln
+               (tramp-shell-quote-argument filename)
+               ;; The command could exceed PATH_MAX, so we use
+               ;; relative file names.  However, relative file names
+               ;; could start with "-".  `tramp-shell-quote-argument'
+               ;; does not handle this, we must do it ourselves.
+               (tramp-shell-quote-argument
+                (concat "./" (file-name-nondirectory l-localname)))))))))
 
 (defun tramp-sh-handle-file-truename (filename)
   "Like `file-truename' for Tramp files."
@@ -1022,22 +1156,17 @@ target of the symlink differ."
                   (format "tramp_perl_file_truename %s"
                           (tramp-shell-quote-argument localname)))))
 
-          ;; Do it yourself.  We bind `directory-sep-char' here for
-          ;; XEmacs on Windows, which would otherwise use backslash.
-          (t (let* ((directory-sep-char ?/)
-                    (steps (tramp-compat-split-string localname "/"))
-                    (localnamedir (tramp-run-real-handler
-                                   'file-name-as-directory (list localname)))
-                    (is-dir (string= localname localnamedir))
-                    (thisstep nil)
-                    (numchase 0)
-                    ;; Don't make the following value larger than
-                    ;; necessary.  People expect an error message in
-                    ;; a timely fashion when something is wrong;
-                    ;; otherwise they might think that Emacs is hung.
-                    ;; Of course, correctness has to come first.
-                    (numchase-limit 20)
-                    symlink-target)
+          ;; Do it yourself.
+          (t (let ((steps (split-string localname "/" 'omit))
+                   (thisstep nil)
+                   (numchase 0)
+                   ;; Don't make the following value larger than
+                   ;; necessary.  People expect an error message in a
+                   ;; timely fashion when something is wrong;
+                   ;; otherwise they might think that Emacs is hung.
+                   ;; Of course, correctness has to come first.
+                   (numchase-limit 20)
+                   symlink-target)
                (while (and steps (< numchase numchase-limit))
                  (setq thisstep (pop steps))
                  (tramp-message
@@ -1077,9 +1206,8 @@ target of the symlink differ."
                              symlink-target))
                           (setq symlink-target localname))
                         (setq steps
-                              (append (tramp-compat-split-string
-                                       symlink-target "/")
-                                      steps)))
+                              (append
+                               (split-string symlink-target "/" 'omit) steps)))
                        (t
                         ;; It's a file.
                         (setq result (cons thisstep result)))))
@@ -1093,10 +1221,8 @@ target of the symlink differ."
                      (if result
                          (mapconcat 'identity (cons "" result) "/")
                        "/"))
-               (when (and is-dir
-                          (or (string= "" result)
-                              (not (string= (substring result -1) "/"))))
-                 (setq result (concat result "/"))))))
+               (when (string= "" result)
+                 (setq result "/")))))
 
          (tramp-message v 4 "True name of `%s' is `%s'" localname result)
          result))))
@@ -1149,89 +1275,107 @@ target of the symlink differ."
                 res-inode res-filemodes res-numlinks
                 res-uid res-gid res-size res-symlink-target)
     (tramp-message vec 5 "file attributes with ls: %s" localname)
-    (tramp-send-command
-     vec
-     (format "(%s %s || %s -h %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)
-            (if (eq id-format 'integer) "-ildn" "-ild")
-            (tramp-shell-quote-argument localname)))
-    ;; parse `ls -l' output ...
-    (with-current-buffer (tramp-get-buffer vec)
-      (when (> (buffer-size) 0)
-        (goto-char (point-min))
-        ;; ... inode
-        (setq res-inode
-              (condition-case err
-                  (read (current-buffer))
-                (invalid-read-syntax
-                 (when (and (equal (cadr err)
-                                   "Integer constant overflow in reader")
-                            (string-match
-                             "^[0-9]+\\([0-9][0-9][0-9][0-9][0-9]\\)\\'"
-                             (car (cddr err))))
-                   (let* ((big (read (substring (car (cddr err)) 0
-                                                (match-beginning 1))))
-                          (small (read (match-string 1 (car (cddr err)))))
-                          (twiddle (/ small 65536)))
-                     (cons (+ big twiddle)
-                           (- small (* twiddle 65536))))))))
-        ;; ... file mode flags
-        (setq res-filemodes (symbol-name (read (current-buffer))))
-        ;; ... number links
-        (setq res-numlinks (read (current-buffer)))
-        ;; ... uid and gid
-        (setq res-uid (read (current-buffer)))
-        (setq res-gid (read (current-buffer)))
-        (if (eq id-format 'integer)
+    ;; We cannot send all three commands combined, it could exceed
+    ;; NAME_MAX or PATH_MAX.  Happened on Mac OS X, for example.
+    (when (or (tramp-send-command-and-check
+               vec
+               (format "%s %s"
+                       (tramp-get-file-exists-command vec)
+                       (tramp-shell-quote-argument localname)))
+              (tramp-send-command-and-check
+               vec
+               (format "%s -h %s"
+                       (tramp-get-test-command vec)
+                       (tramp-shell-quote-argument localname))))
+      (tramp-send-command
+       vec
+       (format "%s %s %s %s"
+               (tramp-get-ls-command vec)
+               (if (eq id-format 'integer) "-ildn" "-ild")
+               ;; On systems which have no quoting style, file names
+               ;; with special characters could fail.
+               (cond
+                ((tramp-get-ls-command-with-quoting-style vec)
+                 "--quoting-style=c")
+                ((tramp-get-ls-command-with-w-option vec)
+                 "-w")
+                (t ""))
+               (tramp-shell-quote-argument localname)))
+      ;; Parse `ls -l' output ...
+      (with-current-buffer (tramp-get-buffer vec)
+        (when (> (buffer-size) 0)
+          (goto-char (point-min))
+          ;; ... inode
+          (setq res-inode
+                (condition-case err
+                    (read (current-buffer))
+                  (invalid-read-syntax
+                   (when (and (equal (cadr err)
+                                     "Integer constant overflow in reader")
+                              (string-match
+                               "^[0-9]+\\([0-9][0-9][0-9][0-9][0-9]\\)\\'"
+                               (car (cddr err))))
+                     (let* ((big (read (substring (car (cddr err)) 0
+                                                  (match-beginning 1))))
+                            (small (read (match-string 1 (car (cddr err)))))
+                            (twiddle (/ small 65536)))
+                       (cons (+ big twiddle)
+                             (- small (* twiddle 65536))))))))
+          ;; ... file mode flags
+          (setq res-filemodes (symbol-name (read (current-buffer))))
+          ;; ... number links
+          (setq res-numlinks (read (current-buffer)))
+          ;; ... uid and gid
+          (setq res-uid (read (current-buffer)))
+          (setq res-gid (read (current-buffer)))
+          (if (eq id-format 'integer)
+              (progn
+                (unless (numberp res-uid) (setq res-uid -1))
+                (unless (numberp res-gid) (setq res-gid -1)))
             (progn
-              (unless (numberp res-uid) (setq res-uid -1))
-              (unless (numberp res-gid) (setq res-gid -1)))
-          (progn
-            (unless (stringp res-uid) (setq res-uid (symbol-name res-uid)))
-            (unless (stringp res-gid) (setq res-gid (symbol-name res-gid)))))
-        ;; ... size
-        (setq res-size (read (current-buffer)))
-        ;; 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
-        (when symlinkp
-          (search-forward "-> ")
-          (setq res-symlink-target (buffer-substring (point) (point-at-eol))))
-        ;; return data gathered
-        (list
-         ;; 0. t for directory, string (name linked to) for symbolic
-         ;; link, or nil.
-         (or dirp res-symlink-target)
-         ;; 1. Number of links to file.
-         res-numlinks
-         ;; 2. File uid.
-         res-uid
-         ;; 3. File gid.
-         res-gid
-         ;; 4. Last access time, as a list of integers.  Normally this
-         ;; would be in the same format as `current-time', but the
-         ;; subseconds part is not currently implemented, and (0 0)
-         ;; denotes an unknown time.
-         ;; 5. Last modification time, likewise.
-         ;; 6. Last status change time, likewise.
-         '(0 0) '(0 0) '(0 0)          ;CCC how to find out?
-         ;; 7. Size in bytes (-1, if number is out of range).
-         res-size
-         ;; 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'
-         t
-         ;; 10. inode number.
-         res-inode
-         ;; 11. Device number.  Will be replaced by a virtual device number.
-         -1
-         )))))
+              (unless (stringp res-uid) (setq res-uid (symbol-name res-uid)))
+              (unless (stringp res-gid) (setq res-gid (symbol-name res-gid)))))
+          ;; ... size
+          (setq res-size (read (current-buffer)))
+          ;; 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.
+          (when symlinkp
+            (search-forward "-> ")
+            (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.
+           (or dirp res-symlink-target)
+           ;; 1. Number of links to file.
+           res-numlinks
+           ;; 2. File uid.
+           res-uid
+           ;; 3. File gid.
+           res-gid
+           ;; 4. Last access time, as a list of integers.  Normally
+           ;; this would be in the same format as `current-time', but
+           ;; the subseconds part is not currently implemented, and
+          ;; (0 0) denotes an unknown time.
+           ;; 5. Last modification time, likewise.
+           ;; 6. Last status change time, likewise.
+           '(0 0) '(0 0) '(0 0)                ;CCC how to find out?
+           ;; 7. Size in bytes (-1, if number is out of range).
+           res-size
+           ;; 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'.
+           t
+           ;; 10. Inode number.
+           res-inode
+           ;; 11. Device number.  Will be replaced by a virtual device number.
+           -1))))))
 
 (defun tramp-do-file-attributes-with-perl
   (vec localname &optional id-format)
@@ -1251,17 +1395,28 @@ 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
+     ;; `tramp-stat-marker', in order to make a proper shell escape of
+     ;; them in file names.
+     "( (%s %s || %s -h %s) && (%s -c "
+     "'((%s%%N%s) %%h %s %s %%Xe0 %%Ye0 %%Ze0 %%se0 %s%%A%s t %%ie0 -1)' "
+     "%s | sed -e 's/\"/\\\\\"/g' -e 's/%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\"")
-    (tramp-shell-quote-argument localname))))
+    tramp-stat-marker tramp-stat-marker
+    (if (eq id-format 'integer)
+       "%ue0" (concat tramp-stat-marker "%U" tramp-stat-marker))
+    (if (eq id-format 'integer)
+       "%ge0" (concat tramp-stat-marker "%G" tramp-stat-marker))
+    tramp-stat-marker tramp-stat-marker
+    (tramp-shell-quote-argument localname)
+    tramp-stat-quoted-marker)))
 
 (defun tramp-sh-handle-set-visited-file-modtime (&optional time-list)
   "Like `set-visited-file-modtime' for Tramp files."
@@ -1277,8 +1432,7 @@ target of the symlink differ."
               (attr (file-attributes f))
               ;; '(-1 65535) means file doesn't exists yet.
               (modtime (or (nth 5 attr) '(-1 65535))))
-         (when (boundp 'last-coding-system-used)
-           (setq coding-system-used (symbol-value 'last-coding-system-used)))
+         (setq coding-system-used last-coding-system-used)
          ;; We use '(0 0) as a don't-know value.  See also
          ;; `tramp-do-file-attributes-with-ls'.
          (if (not (equal modtime '(0 0)))
@@ -1292,8 +1446,7 @@ target of the symlink differ."
              (setq attr (buffer-substring (point) (point-at-eol))))
            (tramp-set-file-property
             v localname "visited-file-modtime-ild" attr))
-         (when (boundp 'last-coding-system-used)
-           (set 'last-coding-system-used coding-system-used))
+         (setq last-coding-system-used coding-system-used)
          nil)))))
 
 ;; This function makes the same assumption as
@@ -1312,7 +1465,7 @@ of."
       ;; connection.
       (if (or (not f)
              (eq (visited-file-modtime) 0)
-             (not (tramp-file-name-handler 'file-remote-p f nil 'connected)))
+             (not (file-remote-p f nil 'connected)))
          t
        (with-parsed-tramp-file-name f nil
          (let* ((remote-file-name-inhibit-cache t)
@@ -1352,51 +1505,31 @@ 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
      v
-     (format "chmod %s %s"
-            (tramp-compat-decimal-to-octal mode)
-            (tramp-shell-quote-argument localname))
+     (format "chmod %o %s" mode (tramp-shell-quote-argument localname))
      "Error while changing file's mode %s" filename)))
 
 (defun tramp-sh-handle-set-file-times (filename &optional time)
   "Like `set-file-times' for Tramp files."
-  (if (tramp-tramp-file-p filename)
-      (with-parsed-tramp-file-name filename nil
-       (when (tramp-get-remote-touch v)
-         (tramp-flush-file-property v localname)
-         (let ((time (if (or (null time) (equal time '(0 0)))
-                         (current-time)
-                       time))
-               ;; With GNU Emacs, `format-time-string' has an
-               ;; optional parameter UNIVERSAL.  This is preferred,
-               ;; because we could handle the case when the remote
-               ;; host is located in a different time zone as the
-               ;; local host.
-               (utc (not (featurep 'xemacs))))
-           (tramp-send-command-and-check
-            v (format
-               "%s %s %s %s"
-               (if utc "env TZ=UTC" "")
-               (tramp-get-remote-touch v)
-               (if (tramp-get-connection-property v "touch-t" nil)
-                   (format "-t %s"
-                           (if utc
-                               (format-time-string "%Y%m%d%H%M.%S" time t)
-                             (format-time-string "%Y%m%d%H%M.%S" time)))
-                 "")
-               (tramp-shell-quote-argument localname))))))
-
-    ;; We handle also the local part, because in older Emacsen,
-    ;; without `set-file-times', this function is an alias for this.
-    ;; We are local, so we don't need the UTC settings.
-    (zerop
-     (tramp-call-process
-      nil "touch" nil nil nil "-t"
-      (format-time-string "%Y%m%d%H%M.%S" time)
-      (tramp-shell-quote-argument 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)
+                   time)))
+       (tramp-send-command-and-check
+        v (format
+           "env TZ=UTC %s %s %s"
+           (tramp-get-remote-touch v)
+           (if (tramp-get-connection-property v "touch-t" nil)
+               (format "-t %s" (format-time-string "%Y%m%d%H%M.%S" time t))
+             "")
+           (tramp-shell-quote-argument localname)))))))
 
 (defun tramp-set-file-uid-gid (filename &optional uid gid)
   "Set the ownership for FILENAME.
@@ -1424,24 +1557,19 @@ 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."
-  (with-tramp-connection-property
-      (tramp-get-connection-process vec) "selinux-p"
-    (let ((result (tramp-find-executable
-                  vec "getenforce" (tramp-get-remote-path vec) t t)))
-      (and result
-          (string-equal
-           (tramp-send-command-and-read
-            vec (format "echo \\\"`%S`\\\"" result))
-           "Enforcing")))))
+  (with-tramp-connection-property (tramp-get-connection-process vec) "selinux-p"
+    (tramp-send-command-and-check vec "selinuxenabled")))
 
 (defun tramp-sh-handle-file-selinux-context (filename)
   "Like `file-selinux-context' for Tramp files."
@@ -1467,24 +1595,25 @@ be non-negative integers."
 (defun tramp-sh-handle-set-file-selinux-context (filename context)
   "Like `set-file-selinux-context' for Tramp files."
   (with-parsed-tramp-file-name filename nil
-    (if (and (consp context)
-            (tramp-remote-selinux-p v)
-            (tramp-send-command-and-check
-             v (format "chcon %s %s %s %s %s"
-                       (if (stringp (nth 0 context))
-                           (format "--user=%s" (nth 0 context)) "")
-                       (if (stringp (nth 1 context))
-                           (format "--role=%s" (nth 1 context)) "")
-                       (if (stringp (nth 2 context))
-                           (format "--type=%s" (nth 2 context)) "")
-                       (if (stringp (nth 3 context))
-                           (format "--range=%s" (nth 3 context)) "")
-                       (tramp-shell-quote-argument localname))))
-       (progn
-         (tramp-set-file-property v localname "file-selinux-context" context)
-         t)
-      (tramp-set-file-property v localname "file-selinux-context" 'undef)
-      nil)))
+    (when (and (consp context)
+              (tramp-remote-selinux-p v))
+      (let ((user (and (stringp (nth 0 context)) (nth 0 context)))
+           (role (and (stringp (nth 1 context)) (nth 1 context)))
+           (type (and (stringp (nth 2 context)) (nth 2 context)))
+           (range (and (stringp (nth 3 context)) (nth 3 context))))
+       (when (tramp-send-command-and-check
+              v (format "chcon %s %s %s %s %s"
+                        (if user (format "--user=%s" user) "")
+                        (if role (format "--role=%s" role) "")
+                        (if type (format "--type=%s" type) "")
+                        (if range (format "--range=%s" range) "")
+                      (tramp-shell-quote-argument localname)))
+         (if (and user role type range)
+             (tramp-set-file-property
+              v localname "file-selinux-context" context)
+           (tramp-set-file-property
+            v localname "file-selinux-context" 'undef))
+         t)))))
 
 (defun tramp-remote-acl-p (vec)
   "Check, whether ACL is enabled on the remote host."
@@ -1498,14 +1627,13 @@ 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))
          (delete-blank-lines)
          (when (> (point-max) (point-min))
-           (tramp-compat-funcall
-            'substring-no-properties (buffer-string))))))))
+           (substring-no-properties (buffer-string))))))))
 
 (defun tramp-sh-handle-set-file-acl (filename acl-string)
   "Like `set-file-acl' for Tramp files."
@@ -1523,7 +1651,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)))
 
@@ -1693,23 +1821,32 @@ 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
-     ;; use \000 as file separator.
-     ;; Apostrophs in the stat output are masked as \037 character, in
-     ;; order to make a proper shell escape of them in file names.
+     ;; but it does not work on all remote systems.  Apostrophes in
+     ;; the stat output are masked as `tramp-stat-marker', in order to
+     ;; make a proper shell escape of them in file names.
      "cd %s && echo \"(\"; (%s %s -a | "
      "xargs %s -c "
-     "'(\037%%n\037 (\037%%N\037) %%h %s %s %%Xe0 %%Ye0 %%Ze0 %%se0 \037%%A\037 t %%ie0 -1)'"
-     " -- 2>/dev/null | sed -e 's/\"/\\\\\"/g' -e 's/\037/\"/g'); echo \")\"")
+     "'(%s%%n%s (%s%%N%s) %%h %s %s %%Xe0 %%Ye0 %%Ze0 %%se0 %s%%A%s t %%ie0 -1)' "
+     "-- 2>/dev/null | sed -e 's/\"/\\\\\"/g' -e 's/%s/\"/g'); echo \")\"")
     (tramp-shell-quote-argument localname)
     (tramp-get-ls-command vec)
-    ;; On systems which have no quotings style, file names with
-    ;; special characters could fail.
-    (if (tramp-get-ls-command-with-quoting-style vec)
-       "--quoting-style=shell" "")
+    ;; On systems which have no quoting style, file names with special
+    ;; characters could fail.
+    (cond
+     ((tramp-get-ls-command-with-quoting-style vec)
+      "--quoting-style=shell")
+     ((tramp-get-ls-command-with-w-option vec)
+      "-w")
+     (t ""))
     (tramp-get-remote-stat vec)
-    (if (eq id-format 'integer) "%ue0" "\037%U\037")
-    (if (eq id-format 'integer) "%ge0" "\037%G\037"))))
+    tramp-stat-marker tramp-stat-marker
+    tramp-stat-marker tramp-stat-marker
+    (if (eq id-format 'integer)
+       "%ue0" (concat tramp-stat-marker "%U" tramp-stat-marker))
+    (if (eq id-format 'integer)
+       "%ge0" (concat tramp-stat-marker "%G" tramp-stat-marker))
+    tramp-stat-marker tramp-stat-marker
+    tramp-stat-quoted-marker)))
 
 ;; This function should return "foo/" for directories and "bar" for
 ;; files.
@@ -1747,7 +1884,7 @@ be non-negative integers."
                  (when cache-hit (list cache-hit))))
              ;; We cannot use a length of 0, because file properties
              ;; for "foo" and "foo/" are identical.
-             (tramp-compat-number-sequence (length filename) 1 -1)))))
+             (number-sequence (length filename) 1 -1)))))
 
          ;; Cache expired or no matching cache entry found so we need
          ;; to perform a remote operation.
@@ -1770,14 +1907,7 @@ be non-negative integers."
                   (format "tramp_perl_file_name_all_completions %s %s %d"
                           (tramp-shell-quote-argument localname)
                           (tramp-shell-quote-argument filename)
-                          (if (symbol-value
-                              ;; `read-file-name-completion-ignore-case'
-                              ;; is introduced with Emacs 22.1.
-                              (if (boundp
-                                   'read-file-name-completion-ignore-case)
-                                  'read-file-name-completion-ignore-case
-                                'completion-ignore-case))
-                             1 0)))
+                          (if read-file-name-completion-ignore-case 1 0)))
 
               (format (concat
                        "(cd %s 2>&1 && (%s -a %s 2>/dev/null"
@@ -1900,19 +2030,18 @@ tramp-sh-handle-file-name-all-completions: internal error accessing `%s': `%s'"
     (tramp-do-copy-or-rename-file
      'copy filename newname ok-if-already-exists keep-date
      preserve-uid-gid preserve-extended-attributes))
-   ;; Compat section.
+   ;; Compat section.  PRESERVE-EXTENDED-ATTRIBUTES has been
+   ;; introduced with Emacs 24.1 (as PRESERVE-SELINUX-CONTEXT), and
+   ;; renamed in Emacs 24.3.
    (preserve-extended-attributes
     (tramp-run-real-handler
      'copy-file
      (list filename newname ok-if-already-exists keep-date
           preserve-uid-gid preserve-extended-attributes)))
-   (preserve-uid-gid
-    (tramp-run-real-handler
-     'copy-file
-     (list filename newname ok-if-already-exists keep-date preserve-uid-gid)))
    (t
     (tramp-run-real-handler
-     'copy-file (list filename newname ok-if-already-exists keep-date)))))
+     'copy-file
+     (list filename newname ok-if-already-exists keep-date preserve-uid-gid)))))
 
 (defun tramp-sh-handle-copy-directory
   (dirname newname &optional keep-date parents copy-contents)
@@ -1921,7 +2050,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)
@@ -1967,7 +2096,8 @@ tramp-sh-handle-file-name-all-completions: internal error accessing `%s': `%s'"
   (if (or (tramp-tramp-file-p filename)
           (tramp-tramp-file-p newname))
       (tramp-do-copy-or-rename-file
-       'rename filename newname ok-if-already-exists t t)
+       'rename filename newname ok-if-already-exists
+       'keep-time 'preserve-uid-gid)
     (tramp-run-real-handler
      'rename-file (list filename newname ok-if-already-exists))))
 
@@ -2088,15 +2218,17 @@ FILENAME is the source file, NEWNAME the target file.
 KEEP-DATE is non-nil if NEWNAME should have the same timestamp as FILENAME."
   ;; 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.
-  ;; We remove `tramp-file-name-handler' from
+  ;; 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
-        (remq 'tramp-file-name-handler 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)))
@@ -2131,11 +2263,11 @@ the uid and gid from FILENAME."
                            op))))
             (localname1
              (if t1
-                 (tramp-file-name-handler 'file-remote-p filename 'localname)
+                 (file-remote-p filename 'localname)
                filename))
             (localname2
              (if t2
-                 (tramp-file-name-handler 'file-remote-p newname 'localname)
+                 (file-remote-p newname 'localname)
                newname))
             (prefix (file-remote-p (if t1 filename newname)))
              cmd-result)
@@ -2173,12 +2305,12 @@ the uid and gid from FILENAME."
                       (zerop
                        (logand
                         (file-modes (file-name-directory localname1))
-                        (tramp-compat-octal-to-decimal "1000"))))
+                        (string-to-number "1000" 8))))
                   (file-writable-p (file-name-directory localname2))
                   (or (file-directory-p localname2)
                       (file-writable-p localname2))))
            (if (eq op 'copy)
-               (tramp-compat-copy-file
+               (copy-file
                 localname1 localname2 ok-if-already-exists
                 keep-date preserve-uid-gid)
              (tramp-run-real-handler
@@ -2218,15 +2350,14 @@ the uid and gid from FILENAME."
                      ;; Since this does not work reliable, we also
                      ;; give read permissions.
                      (set-file-modes
-                      (concat prefix tmpfile)
-                      (tramp-compat-octal-to-decimal "0777"))
+                      (concat prefix tmpfile) (string-to-number "0777" 8))
                      (tramp-set-file-uid-gid
                       (concat prefix tmpfile)
                       (tramp-get-local-uid 'integer)
                       (tramp-get-local-gid 'integer)))
                     (t2
                      (if (eq op 'copy)
-                         (tramp-compat-copy-file
+                         (copy-file
                           localname1 tmpfile t
                           keep-date preserve-uid-gid)
                        (tramp-run-real-handler
@@ -2235,8 +2366,7 @@ the uid and gid from FILENAME."
                      ;; We must change the ownership as local user.
                      ;; Since this does not work reliable, we also
                      ;; give read permissions.
-                     (set-file-modes
-                      tmpfile (tramp-compat-octal-to-decimal "0777"))
+                     (set-file-modes tmpfile (string-to-number "0777" 8))
                      (tramp-set-file-uid-gid
                       tmpfile
                       (tramp-get-remote-uid v 'integer)
@@ -2295,7 +2425,7 @@ The method used must be an out-of-band method."
              ;; Save exit.
              (ignore-errors
                (if dir-flag
-                   (tramp-compat-delete-directory
+                   (delete-directory
                     (expand-file-name ".." tmpfile) 'recursive)
                  (delete-file tmpfile)))))
 
@@ -2315,16 +2445,17 @@ The method used must be an out-of-band method."
        (setq source (if t1
                         (tramp-make-copy-program-file-name v)
                       (shell-quote-argument filename))
-             target (funcall
+          target (if t2
+                     (tramp-make-copy-program-file-name v)
+                   (shell-quote-argument
+                    (funcall
                      (if (and (file-directory-p filename)
                               (string-equal
                                (file-name-nondirectory filename)
                                (file-name-nondirectory newname)))
                          'file-name-directory
                        'identity)
-                     (if t2
-                         (tramp-make-copy-program-file-name v)
-                       (shell-quote-argument newname))))
+                     newname))))
 
        ;; Check for host and port number.  We cannot use
        ;; `tramp-file-name-port', because this returns also
@@ -2341,7 +2472,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))
@@ -2354,17 +2485,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
@@ -2373,9 +2500,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
@@ -2389,16 +2514,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
@@ -2429,10 +2550,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
@@ -2477,7 +2598,7 @@ The method used must be an out-of-band method."
                   orig-vec 6 "%s"
                   (mapconcat 'identity (process-command p) " "))
                  (tramp-set-connection-property p "vector" orig-vec)
-                 (tramp-compat-set-process-query-on-exit-flag p nil)
+                 (set-process-query-on-exit-flag p nil)
 
                  ;; We must adapt `tramp-local-end-of-line' for
                  ;; sending the password.
@@ -2525,7 +2646,7 @@ The method used must be an out-of-band method."
       (unless (eq op 'copy)
        (if (file-regular-p filename)
            (delete-file filename)
-         (tramp-compat-delete-directory filename 'recursive))))))
+         (delete-directory filename 'recursive))))))
 
 (defun tramp-sh-handle-make-directory (dir &optional parents)
   "Like `make-directory' for Tramp files."
@@ -2565,51 +2686,16 @@ The method used must be an out-of-band method."
 
 ;; Dired.
 
-;; CCC: This does not seem to be enough. Something dies when
-;;      we try and delete two directories under Tramp :/
-(defun tramp-sh-handle-dired-recursive-delete-directory (filename)
-  "Recursively delete the directory given.
-This is like `dired-recursive-delete-directory' for Tramp files."
-  (with-parsed-tramp-file-name filename nil
-    ;; Run a shell command 'rm -r <localname>'.
-    ;; Code shamelessly stolen from the dired implementation and, um, hacked :)
-    (unless (file-exists-p filename)
-      (tramp-error v 'file-error "No such directory: %s" filename))
-    ;; Which is better, -r or -R? (-r works for me <daniel@danann.net>).
-    (tramp-send-command
-     v
-     (format "rm -rf %s" (tramp-shell-quote-argument localname))
-     ;; Don't read the output, do it explicitly.
-     nil t)
-    ;; Wait for the remote system to return to us...
-    ;; This might take a while, allow it plenty of time.
-    (tramp-wait-for-output (tramp-get-connection-process v) 120)
-    ;; Make sure that it worked...
-    (tramp-flush-file-property v (file-name-directory localname))
-    (tramp-flush-directory-property v localname)
-    (and (file-exists-p filename)
-        (tramp-error
-         v 'file-error "Failed to recursively delete %s" filename))))
+(defvar dired-compress-file-suffixes)
+(declare-function dired-remove-file "dired-aux")
 
-(defun tramp-sh-handle-dired-compress-file (file &rest _ok-flag)
+(defun tramp-sh-handle-dired-compress-file (file)
   "Like `dired-compress-file' for Tramp files."
-  ;; OK-FLAG is valid for XEmacs only, but not implemented.
   ;; Code stolen mainly from dired-aux.el.
   (with-parsed-tramp-file-name file nil
     (tramp-flush-file-property v localname)
     (save-excursion
-      (let ((suffixes
-            (if (not (featurep 'xemacs))
-                ;; Emacs case
-                (symbol-value 'dired-compress-file-suffixes)
-              ;; XEmacs has `dired-compression-method-alist', which is
-              ;; transformed into `dired-compress-file-suffixes' structure.
-              (mapcar
-               (lambda (x)
-                 (list (concat (regexp-quote (nth 1 x)) "\\'")
-                       nil
-                       (mapconcat 'identity (nth 3 x) " ")))
-               (symbol-value 'dired-compression-method-alist))))
+      (let ((suffixes dired-compress-file-suffixes)
            suffix)
        ;; See if any suffix rule matches this file name.
        (while suffixes
@@ -2627,8 +2713,7 @@ This is like `dired-recursive-delete-directory' for Tramp files."
                 (when (tramp-send-command-and-check
                        v (concat (nth 2 suffix) " "
                                  (tramp-shell-quote-argument localname)))
-                  ;; `dired-remove-file' is not defined in XEmacs.
-                  (tramp-compat-funcall 'dired-remove-file file)
+                  (dired-remove-file file)
                   (string-match (car suffix) file)
                   (concat (substring file 0 (match-beginning 0))))))
              (t
@@ -2638,8 +2723,7 @@ This is like `dired-recursive-delete-directory' for Tramp files."
                 (when (tramp-send-command-and-check
                        v (concat "gzip -f "
                                  (tramp-shell-quote-argument localname)))
-                  ;; `dired-remove-file' is not defined in XEmacs.
-                  (tramp-compat-funcall 'dired-remove-file file)
+                  (dired-remove-file file)
                   (cond ((file-exists-p (concat file ".gz"))
                          (concat file ".gz"))
                         ((file-exists-p (concat file ".z"))
@@ -2749,9 +2833,7 @@ This is like `dired-recursive-delete-directory' for Tramp files."
          ;; Decode the output, it could be multibyte.
          (decode-coding-region
           beg (point-max)
-          (or file-name-coding-system
-              (and (boundp 'default-file-name-coding-system)
-                   (symbol-value 'default-file-name-coding-system))))
+          (or file-name-coding-system default-file-name-coding-system))
 
          ;; The inserted file could be from somewhere else.
          (when (and (not wildcard) (not full-directory-p))
@@ -2814,13 +2896,10 @@ the result will be a local, non-Tramp, file name."
       (while (string-match "//" localname)
        (setq localname (replace-match "/" t t localname)))
       ;; No tilde characters in file name, do normal
-      ;; `expand-file-name' (this does "/./" and "/../").  We bind
-      ;; `directory-sep-char' here for XEmacs on Windows, which would
-      ;; otherwise use backslash.  `default-directory' is bound,
-      ;; because on Windows there would be problems with UNC shares or
-      ;; Cygwin mounts.
-      (let ((directory-sep-char ?/)
-           (default-directory (tramp-compat-temporary-file-directory)))
+      ;; `expand-file-name' (this does "/./" and "/../").
+      ;; `default-directory' is bound, because on Windows there would
+      ;; be problems with UNC shares or Cygwin mounts.
+      (let ((default-directory (tramp-compat-temporary-file-directory)))
        (tramp-make-tramp-file-name
         method user host
         (tramp-drop-volume-letter
@@ -2863,10 +2942,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
@@ -2937,7 +3021,7 @@ the result will be a local, non-Tramp, file name."
                        ;; Send the command.
                        (tramp-send-command v command nil t) ; nooutput
                      ;; Check, whether a pty is associated.
-                     (unless (tramp-compat-process-get
+                     (unless (process-get
                               (tramp-get-connection-process v) 'remote-tty)
                        (tramp-error
                         v 'file-error
@@ -2947,7 +3031,7 @@ the result will be a local, non-Tramp, file name."
                    ;; process.  We ignore errors, because the process
                    ;; could have finished already.
                    (ignore-errors
-                     (tramp-compat-set-process-query-on-exit-flag p t)
+                     (set-process-query-on-exit-flag p t)
                      (set-marker (process-mark p) (point)))
                    ;; Return process.
                    p))))
@@ -3071,12 +3155,7 @@ the result will be a local, non-Tramp, file name."
       ;; because the remote process could have changed them.
       (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
-      ;; by `program'.  If it doesn't exist, we assume its default
-      ;; value `t'.
-      (unless (and (boundp 'process-file-side-effects)
-                  (not (symbol-value 'process-file-side-effects)))
+      (unless process-file-side-effects
         (tramp-flush-directory-property v ""))
 
       ;; Return exit status.
@@ -3102,21 +3181,22 @@ the result will be a local, non-Tramp, file name."
           ;; `copy-file' handles direct copy and out-of-band methods.
           ((or (tramp-local-host-p v)
                (tramp-method-out-of-band-p v size))
-           (copy-file filename tmpfile t t))
+           (copy-file filename tmpfile 'ok-if-already-exists 'keep-time))
 
           ;; Use inline encoding for file transfer.
           (rem-enc
            (save-excursion
              (with-tramp-progress-reporter
               v 3
-              (format "Encoding remote file `%s' with `%s'" filename rem-enc)
+              (format-message "Encoding remote file `%s' with `%s'"
+                               filename rem-enc)
               (tramp-barf-unless-okay
                v (format rem-enc (tramp-shell-quote-argument localname))
                "Encoding remote file failed"))
 
              (with-tramp-progress-reporter
-                 v 3 (format "Decoding local file `%s' with `%s'"
-                             tmpfile loc-dec)
+                 v 3 (format-message "Decoding local file `%s' with `%s'"
+                                     tmpfile loc-dec)
                (if (functionp loc-dec)
                    ;; If local decoding is a function, we call it.
                    ;; We must disable multibyte, because
@@ -3162,29 +3242,6 @@ the result will be a local, non-Tramp, file name."
       (run-hooks 'tramp-handle-file-local-copy-hook)
       tmpfile)))
 
-;; This is needed for XEmacs only.  Code stolen from files.el.
-(defun tramp-sh-handle-insert-file-contents-literally
-  (filename &optional visit beg end replace)
-  "Like `insert-file-contents-literally' for Tramp files."
-  (let ((format-alist nil)
-       (after-insert-file-functions nil)
-       (coding-system-for-read 'no-conversion)
-       (coding-system-for-write 'no-conversion)
-       (find-buffer-file-type-function
-        (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-operation 'insert-file-contents))
-    (unwind-protect
-       (progn
-         (fset 'find-buffer-file-type (lambda (_filename) t))
-         (insert-file-contents filename visit beg end replace))
-      ;; Save exit.
-      (if find-buffer-file-type-function
-         (fset 'find-buffer-file-type find-buffer-file-type-function)
-       (fmakunbound 'find-buffer-file-type)))))
-
 ;; CCC grok LOCKNAME
 (defun tramp-sh-handle-write-region
   (start end filename &optional append visit lockname confirm)
@@ -3201,14 +3258,13 @@ the result will be a local, non-Tramp, file name."
     ;;    (error
     ;;     "tramp-sh-handle-write-region: LOCKNAME must be nil or equal FILENAME"))
 
-    ;; XEmacs takes a coding system as the seventh argument, not `confirm'.
-    (when (and (not (featurep 'xemacs)) confirm (file-exists-p filename))
+    (when (and confirm (file-exists-p filename))
       (unless (y-or-n-p (format "File %s exists; overwrite anyway? " filename))
        (tramp-error v 'file-error "File not overwritten")))
 
-    (let ((uid (or (nth 2 (tramp-compat-file-attributes filename 'integer))
+    (let ((uid (or (nth 2 (file-attributes filename 'integer))
                   (tramp-get-remote-uid v 'integer)))
-         (gid (or (nth 3 (tramp-compat-file-attributes filename 'integer))
+         (gid (or (nth 3 (file-attributes filename 'integer))
                   (tramp-get-remote-gid v 'integer))))
 
       (if (and (tramp-local-host-p v)
@@ -3266,9 +3322,7 @@ the result will be a local, non-Tramp, file name."
               (signal (car err) (cdr err))))
 
            ;; Now, `last-coding-system-used' has the right value.  Remember it.
-           (when (boundp 'last-coding-system-used)
-             (setq coding-system-used
-                   (symbol-value 'last-coding-system-used))))
+           (setq coding-system-used last-coding-system-used))
 
          ;; The permissions of the temporary file should be set.  If
          ;; FILENAME does not exist (eq modes nil) it has been
@@ -3278,7 +3332,7 @@ the result will be a local, non-Tramp, file name."
          (when modes
            (set-file-modes
             tmpfile
-            (logior (or modes 0) (tramp-compat-octal-to-decimal "0400"))))
+            (logior (or modes 0) (string-to-number "0400" 8))))
 
          ;; This is a bit lengthy due to the different methods
          ;; possible for file transfer.  First, we check whether the
@@ -3297,8 +3351,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
@@ -3323,8 +3376,9 @@ the result will be a local, non-Tramp, file name."
                    (set-buffer-multibyte nil)
                    ;; Use encoding function or command.
                    (with-tramp-progress-reporter
-                       v 3 (format "Encoding local file `%s' using `%s'"
-                                   tmpfile loc-enc)
+                       v 3 (format-message
+                            "Encoding local file `%s' using `%s'"
+                            tmpfile loc-enc)
                      (if (functionp loc-enc)
                          ;; The following `let' is a workaround for
                          ;; the base64.el that comes with pgnus-0.84.
@@ -3353,8 +3407,9 @@ the result will be a local, non-Tramp, file name."
                    ;; writes to remote file.  Because this happens on
                    ;; the remote host, we cannot use the function.
                    (with-tramp-progress-reporter
-                       v 3 (format "Decoding remote file `%s' using `%s'"
-                                   filename rem-dec)
+                       v 3 (format-message
+                            "Decoding remote file `%s' using `%s'"
+                            filename rem-dec)
                      (goto-char (point-max))
                      (unless (bolp) (newline))
                      (tramp-send-command
@@ -3417,7 +3472,7 @@ the result will be a local, non-Tramp, file name."
       (let (last-coding-system-used (need-chown t))
        ;; Set file modification time.
        (when (or (eq visit t) (stringp visit))
-          (let ((file-attr (tramp-compat-file-attributes filename 'integer)))
+          (let ((file-attr (file-attributes filename 'integer)))
             (set-visited-file-modtime
              ;; We must pass modtime explicitly, because FILENAME can
              ;; be different from (buffer-file-name), f.e. if
@@ -3452,10 +3507,10 @@ the result will be a local, non-Tramp, file name."
 ;; any other remote command.
 (defun tramp-sh-handle-vc-registered (file)
   "Like `vc-registered' for Tramp files."
-  (tramp-compat-with-temp-message ""
+  (with-temp-message ""
     (with-parsed-tramp-file-name file nil
       (with-tramp-progress-reporter
-         v 3 (format "Checking `vc-registered' for %s" file)
+         v 3 (format-message "Checking `vc-registered' for %s" file)
 
        ;; There could be new files, created by the vc backend.  We
        ;; cannot reuse the old cache entries, therefore.  In
@@ -3582,22 +3637,33 @@ Fall back to normal file name handler if no Tramp handler exists."
   "Like `file-notify-add-watch' for Tramp files."
   (setq file-name (expand-file-name file-name))
   (with-parsed-tramp-file-name file-name nil
-    (let* ((default-directory (file-name-directory file-name))
-          command events filter p sequence)
+    (let ((default-directory (file-name-directory file-name))
+         command events filter p sequence)
       (cond
        ;; gvfs-monitor-dir.
        ((setq command (tramp-get-remote-gvfs-monitor-dir v))
-       (setq filter 'tramp-sh-file-gvfs-monitor-dir-process-filter
+       (setq filter 'tramp-sh-gvfs-monitor-dir-process-filter
+             events
+             (cond
+              ((and (memq 'change flags) (memq 'attribute-change flags))
+               '(created changed changes-done-hint moved deleted
+                         attribute-changed))
+              ((memq 'change flags)
+               '(created changed changes-done-hint moved deleted))
+              ((memq 'attribute-change flags) '(attribute-changed)))
              sequence `(,command ,localname)))
        ;; inotifywait.
        ((setq command (tramp-get-remote-inotifywait v))
-       (setq filter 'tramp-sh-file-inotifywait-process-filter
+       (setq filter 'tramp-sh-inotifywait-process-filter
              events
              (cond
               ((and (memq 'change flags) (memq 'attribute-change flags))
-               "create,modify,move,delete,attrib")
-              ((memq 'change flags) "create,modify,move,delete")
-              ((memq 'attribute-change flags) "attrib"))
+               (concat "create,modify,move,moved_from,moved_to,move_self,"
+                       "delete,delete_self,attrib,ignored"))
+              ((memq 'change flags)
+               (concat "create,modify,move,moved_from,moved_to,move_self,"
+                       "delete,delete_self,ignored"))
+              ((memq 'attribute-change flags) "attrib,ignored"))
              sequence `(,command "-mq" "-e" ,events ,localname)))
        ;; None.
        (t (tramp-error
@@ -3619,23 +3685,35 @@ Fall back to normal file name handler if no Tramp handler exists."
           (mapconcat 'identity sequence " "))
        (tramp-message v 6 "Run `%s', %S" (mapconcat 'identity sequence " ") p)
        (tramp-set-connection-property p "vector" v)
-       (tramp-compat-set-process-query-on-exit-flag p nil)
+       ;; Needed for `tramp-sh-gvfs-monitor-dir-process-filter'.
+       (process-put p 'events events)
+       (process-put p 'watch-name localname)
+       (set-process-query-on-exit-flag p nil)
        (set-process-filter p filter)
+       ;; There might be an error if the monitor is not supported.
+       ;; Give the filter a chance to read the output.
+       (tramp-accept-process-output p 1)
+       (unless (memq (process-status p) '(run open))
+         (tramp-error
+          v 'file-notify-error "Monitoring not supported for `%s'" file-name))
        p))))
 
-(defun tramp-sh-file-gvfs-monitor-dir-process-filter (proc string)
-  "Read output from \"gvfs-monitor-dir\" and add corresponding file-notify events."
+(defun tramp-sh-gvfs-monitor-dir-process-filter (proc string)
+  "Read output from \"gvfs-monitor-dir\" and add corresponding \
+file-notify events."
   (let ((remote-prefix
         (with-current-buffer (process-buffer proc)
           (file-remote-p default-directory)))
-       (rest-string (tramp-compat-process-get proc 'rest-string)))
+       (rest-string (process-get proc 'rest-string)))
     (when rest-string
       (tramp-message proc 10 "Previous string:\n%s" rest-string))
     (tramp-message proc 6 "%S\n%s" proc string)
     (setq string (concat rest-string string)
          ;; Attribute change is returned in unused wording.
-         string (tramp-compat-replace-regexp-in-string
+         string (replace-regexp-in-string
                  "ATTRIB CHANGED" "ATTRIBUTE_CHANGED" string))
+    (when (string-match "Monitoring not supported" string)
+      (delete-process proc))
 
     (while (string-match
            (concat "^[\n\r]*"
@@ -3644,32 +3722,38 @@ Fall back to normal file name handler if no Tramp handler exists."
                    "\\(Other = \\([^\n\r]+\\)[\n\r]+\\)?"
                    "Event = \\([^[:blank:]]+\\)[\n\r]+")
            string)
-      (let ((object
-            (list
-             proc
-             (intern-soft
-              (tramp-compat-replace-regexp-in-string
-               "_" "-" (downcase (match-string 4 string))))
-             ;; File names are returned as absolute paths.  We must
-             ;; add the remote prefix.
-             (concat remote-prefix (match-string 1 string))
-             (when (match-string 3 string)
-               (concat remote-prefix (match-string 3 string))))))
+      (let* ((file (match-string 1 string))
+            (file1 (match-string 3 string))
+            (object
+             (list
+              proc
+              (intern-soft
+               (replace-regexp-in-string
+                "_" "-" (downcase (match-string 4 string))))
+              ;; File names are returned as absolute paths.  We must
+              ;; add the remote prefix.
+              (concat remote-prefix file)
+              (when file1 (concat remote-prefix file1)))))
        (setq string (replace-match "" nil nil string))
+       ;; Remove watch when file or directory to be watched is deleted.
+       (when (and (member (cadr object) '(moved deleted))
+                  (string-equal file (process-get proc 'watch-name)))
+         (delete-process proc))
        ;; Usually, we would add an Emacs event now.  Unfortunately,
        ;; `unread-command-events' does not accept several events at
        ;; once.  Therefore, we apply the callback directly.
-       (tramp-compat-funcall 'file-notify-callback object)))
+       (when (member (cadr object) (process-get proc 'events))
+         (tramp-compat-funcall 'file-notify-callback object))))
 
     ;; Save rest of the string.
     (when (zerop (length string)) (setq string nil))
     (when string (tramp-message proc 10 "Rest string:\n%s" string))
-    (tramp-compat-process-put proc 'rest-string string)))
+    (process-put proc 'rest-string string)))
 
-(defun tramp-sh-file-inotifywait-process-filter (proc string)
+(defun tramp-sh-inotifywait-process-filter (proc string)
   "Read output from \"inotifywait\" and add corresponding file-notify events."
   (tramp-message proc 6 "%S\n%s" proc string)
-  (dolist (line (split-string string "[\n\r]+" 'omit-nulls))
+  (dolist (line (split-string string "[\n\r]+" 'omit))
     ;; Check, whether there is a problem.
     (unless
        (string-match
@@ -3685,9 +3769,12 @@ Fall back to normal file name handler if no Tramp handler exists."
            (mapcar
             (lambda (x)
               (intern-soft
-               (tramp-compat-replace-regexp-in-string "_" "-" (downcase x))))
-            (split-string (match-string 1 line) "," 'omit-nulls))
+               (replace-regexp-in-string "_" "-" (downcase x))))
+            (split-string (match-string 1 line) "," 'omit))
            (match-string 3 line))))
+      ;; Remove watch when file or directory to be watched is deleted.
+      (when (equal (cadr object) 'ignored)
+       (delete-process proc))
       ;; Usually, we would add an Emacs event now.  Unfortunately,
       ;; `unread-command-events' does not accept several events at
       ;; once.  Therefore, we apply the callback directly.
@@ -3703,7 +3790,12 @@ Only send the definition if it has not already been done."
   (let ((scripts (tramp-get-connection-property
                  (tramp-get-connection-process vec) "scripts" nil)))
     (unless (member name scripts)
-      (with-tramp-progress-reporter vec 5 (format "Sending script `%s'" name)
+      (with-tramp-progress-reporter
+         vec 5 (format-message "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 (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)))
@@ -3716,17 +3808,6 @@ Only send the definition if it has not already been done."
        (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."
@@ -3786,8 +3867,7 @@ This function expects to be in the right *tramp* buffer."
            (setq result (concat "\\" progname))))
       (unless result
        (when ignore-tilde
-         ;; Remove all ~/foo directories from dirlist.  In XEmacs,
-         ;; `remove' is in CL, and we want to avoid CL dependencies.
+         ;; Remove all ~/foo directories from dirlist.
          (let (newdl d)
            (while dirlist
              (setq d (car dirlist))
@@ -3884,7 +3964,7 @@ file exists and nonzero exit status otherwise."
 (defun tramp-open-shell (vec shell)
   "Opens shell SHELL."
   (with-tramp-progress-reporter
-      vec 5 (format "Opening remote shell `%s'" shell)
+      vec 5 (format-message "Opening remote shell `%s'" shell)
     ;; Find arguments for this shell.
     (let ((alist tramp-sh-extra-args)
          item extra-args)
@@ -3923,12 +4003,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"
@@ -3986,16 +4061,14 @@ seconds.  If not, it produces an error message with the given ERROR-ARGS."
   "Set up an interactive shell.
 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)))
-
-    ;; Disable echo.
+  (let ((tramp-end-of-output tramp-initial-end-of-output)
+       (case-fold-search t))
+    (tramp-open-shell vec (tramp-get-method-parameter vec 'tramp-remote-shell))
+
+    ;; 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 -onlcr -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.
@@ -4014,6 +4087,25 @@ process to set up.  VEC specifies the connection."
    vec (format "PS1=%s PS2='' PS3='' PROMPT_COMMAND=''"
               (tramp-shell-quote-argument tramp-end-of-output)) t)
 
+  ;; Check whether the output of "uname -sr" has been changed.  If
+  ;; yes, this is a strong indication that we must expire all
+  ;; connection properties.  We start again with
+  ;; `tramp-maybe-open-connection', it will be caught there.
+  (tramp-message vec 5 "Checking system information")
+  (let ((old-uname (tramp-get-connection-property vec "uname" nil))
+       (new-uname
+        (tramp-set-connection-property
+         vec "uname"
+         (tramp-send-command-and-read vec "echo \\\"`uname -sr`\\\""))))
+    (when (and (stringp old-uname) (not (string-equal old-uname new-uname)))
+      (tramp-message
+       vec 3
+       "Connection reset, because remote host changed from `%s' to `%s'"
+       old-uname new-uname)
+      ;; We want to keep the password.
+      (tramp-cleanup-connection vec t t)
+      (throw 'uname-changed (tramp-maybe-open-connection vec))))
+
   ;; Try to set up the coding system correctly.
   ;; CCC this can't be the right way to do it.  Hm.
   (tramp-message vec 5 "Determining coding system")
@@ -4022,25 +4114,32 @@ process to set up.  VEC specifies the connection."
        ;; Use MULE to select the right EOL convention for communicating
        ;; with the process.
        (let ((cs (or (and (memq 'utf-8 (coding-system-list))
-                          (string-match "utf8" (tramp-get-remote-locale vec))
+                          (string-match "utf-?8" (tramp-get-remote-locale vec))
                           (cons 'utf-8 'utf-8))
-                     (tramp-compat-funcall 'process-coding-system proc)
+                     (process-coding-system proc)
                      (cons 'undecided 'undecided)))
              cs-decode cs-encode)
          (when (symbolp cs) (setq cs (cons cs cs)))
-         (setq cs-decode (car cs))
-         (setq cs-encode (cdr cs))
-         (unless cs-decode (setq cs-decode 'undecided))
-         (unless cs-encode (setq cs-encode 'undecided))
-         (setq cs-encode (tramp-compat-coding-system-change-eol-conversion
-                          cs-encode 'unix))
+         (setq cs-decode (or (car cs) 'undecided)
+                cs-encode (or (cdr cs) 'undecided))
+         (setq cs-encode
+               (coding-system-change-eol-conversion
+                cs-encode
+                (if (string-match
+                     "^Darwin" (tramp-get-connection-property vec "uname" ""))
+                    'mac 'unix)))
          (tramp-send-command vec "echo foo ; echo bar" t)
          (goto-char (point-min))
          (when (search-forward "\r" nil t)
-           (setq cs-decode (tramp-compat-coding-system-change-eol-conversion
+           (setq cs-decode (coding-system-change-eol-conversion
                             cs-decode 'dos)))
-         (tramp-compat-funcall
-          'set-buffer-process-coding-system cs-decode cs-encode)
+          ;; Special setting for Mac OS X.
+          (when (and (string-match
+                      "^Darwin" (tramp-get-connection-property vec "uname" ""))
+                     (memq 'utf-8-hfs (coding-system-list)))
+            (setq cs-decode 'utf-8-hfs
+                  cs-encode 'utf-8-hfs))
+         (set-buffer-process-coding-system cs-decode cs-encode)
          (tramp-message
           vec 5 "Setting coding system to `%s' and `%s'" cs-decode cs-encode))
       ;; Look for ^M and do something useful if found.
@@ -4052,25 +4151,6 @@ process to set up.  VEC specifies the connection."
 
   (tramp-send-command vec "set +o vi +o emacs" t)
 
-  ;; Check whether the output of "uname -sr" has been changed.  If
-  ;; yes, this is a strong indication that we must expire all
-  ;; connection properties.  We start again with
-  ;; `tramp-maybe-open-connection', it will be caught there.
-  (tramp-message vec 5 "Checking system information")
-  (let ((old-uname (tramp-get-connection-property vec "uname" nil))
-       (new-uname
-        (tramp-set-connection-property
-         vec "uname"
-         (tramp-send-command-and-read vec "echo \\\"`uname -sr`\\\""))))
-    (when (and (stringp old-uname) (not (string-equal old-uname new-uname)))
-      (tramp-message
-       vec 3
-       "Connection reset, because remote host changed from `%s' to `%s'"
-       old-uname new-uname)
-      ;; We want to keep the password.
-      (tramp-cleanup-connection vec t t)
-      (throw 'uname-changed (tramp-maybe-open-connection vec))))
-
   ;; Check whether the remote host suffers from buggy
   ;; `send-process-string'.  This is known for FreeBSD (see comment in
   ;; `send_process', file process.c).  I've tested sending 624 bytes
@@ -4104,7 +4184,7 @@ process to set up.  VEC specifies the connection."
   (tramp-find-shell vec)
 
   ;; Disable unexpected output.
-  (tramp-send-command vec "mesg n; biff n" t)
+  (tramp-send-command vec "mesg n 2>/dev/null; biff n 2>/dev/null" t)
 
   ;; IRIX64 bash expands "!" even when in single quotes.  This
   ;; destroys our shell functions, we must disable it.  See
@@ -4117,10 +4197,14 @@ process to set up.  VEC specifies the connection."
                      (tramp-get-connection-property vec "uname" ""))
     (tramp-send-command vec "stty -oxtabs" t))
 
+  ;; Set utf8 encoding.  Needed for Mac OS X, for example.  This is
+  ;; non-POSIX, so we must expect errors on some systems.
+  (tramp-send-command vec "stty iutf8 2>/dev/null" t)
+
   ;; Set `remote-tty' process property.
   (let ((tty (tramp-send-command-and-read vec "echo \\\"`tty`\\\"" 'noerror)))
     (unless (zerop (length tty))
-      (tramp-compat-process-put proc 'remote-tty tty)))
+      (process-put proc 'remote-tty tty)))
 
   ;; Dump stty settings in the traces.
   (when (>= tramp-verbose 9)
@@ -4133,7 +4217,7 @@ process to set up.  VEC specifies the connection."
                     (copy-sequence tramp-remote-process-environment)))
        unset vars item)
     (while env
-      (setq item (tramp-compat-split-string (car env) "="))
+      (setq item (split-string (car env) "=" 'omit))
       (setcdr item (mapconcat 'identity (cdr item) "="))
       (if (and (stringp (cdr item)) (not (string-equal (cdr item) "")))
          (push (format "%s %s" (car item) (cdr item)) vars)
@@ -4173,7 +4257,7 @@ process to set up.  VEC specifies the connection."
   "List of local coding commands for inline transfer.
 Each item is a list that looks like this:
 
-\(FORMAT ENCODING DECODING\)
+\(FORMAT ENCODING DECODING)
 
 FORMAT is  symbol describing the encoding/decoding format.  It can be
 `b64' for base64 encoding, `uu' for uu encoding, or `pack' for simple packing.
@@ -4190,16 +4274,19 @@ and end of region, and are expected to replace the region contents
 with the encoded or decoded results, respectively.")
 
 (defconst tramp-remote-coding-commands
-  '((b64 "base64" "base64 -d -i")
+  `((b64 "base64" "base64 -d -i")
     ;; "-i" is more robust with older base64 from GNU coreutils.
     ;; However, I don't know whether all base64 versions do supports
     ;; this option.
     (b64 "base64" "base64 -d")
+    (b64 "openssl enc -base64" "openssl enc -d -base64")
     (b64 "mimencode -b" "mimencode -u -b")
     (b64 "mmencode -b" "mmencode -u -b")
     (b64 "recode data..base64" "recode base64..data")
     (b64 tramp-perl-encode-with-module tramp-perl-decode-with-module)
     (b64 tramp-perl-encode tramp-perl-decode)
+    ;; This is painful slow, so we put it on the end.
+    (b64 tramp-awk-encode tramp-awk-decode ,tramp-awk-coding-test)
     (uu  "uuencode xxx" "uudecode -o /dev/stdout" "test -c /dev/stdout")
     (uu  "uuencode xxx" "uudecode -o -")
     (uu  "uuencode xxx" "uudecode -p")
@@ -4208,7 +4295,7 @@ with the encoded or decoded results, respectively.")
   "List of remote coding commands for inline transfer.
 Each item is a list that looks like this:
 
-\(FORMAT ENCODING DECODING [TEST]\)
+\(FORMAT ENCODING DECODING [TEST])
 
 FORMAT is a symbol describing the encoding/decoding format.  It can be
 `b64' for base64 encoding, `uu' for uu encoding, or `pack' for simple packing.
@@ -4278,7 +4365,8 @@ Goes through the list `tramp-local-coding-commands' and
                    (unless (tramp-send-command-and-check vec rem-test t)
                      (throw 'wont-work-remote nil)))
                  ;; Check if remote perl exists when necessary.
-                 (when (and (not (stringp rem-enc))
+                 (when (and (symbolp rem-enc)
+                            (string-match "perl" (symbol-name rem-enc))
                             (not (tramp-get-remote-perl vec)))
                    (throw 'wont-work-remote nil))
                  ;; Check if remote encoding and decoding commands can be
@@ -4319,8 +4407,7 @@ Goes through the list `tramp-local-coding-commands' and
                               value
                               (format-spec-make
                                ?t
-                               (tramp-file-name-handler
-                                'file-remote-p tmpfile 'localname)))))
+                               (file-remote-p tmpfile 'localname)))))
                      (tramp-maybe-send-script vec value name)
                      (setq rem-dec name)))
                  (tramp-message
@@ -4380,7 +4467,7 @@ means discard it)."
   "List of compress and decompress commands for inline transfer.
 Each item is a list that looks like this:
 
-\(COMPRESS DECOMPRESS\)
+\(COMPRESS DECOMPRESS)
 
 COMPRESS or DECOMPRESS are strings with the respective commands.")
 
@@ -4516,7 +4603,7 @@ Gateway hops are already opened."
        (push
         (vector
          (tramp-file-name-method hop) (tramp-file-name-user hop)
-         (tramp-compat-funcall 'tramp-gw-open-connection vec gw hop) nil nil)
+         (tramp-gw-open-connection vec gw hop) nil nil)
         target-alist)
        ;; For the password prompt, we need the correct values.
        ;; Therefore, we must remember the gateway vector.  But we
@@ -4528,15 +4615,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."
@@ -4544,7 +4625,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)))
@@ -4553,8 +4634,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))
@@ -4566,6 +4646,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
@@ -4615,6 +4737,7 @@ connection if a previous connection has died for some reason."
        (unless (and p (processp p) (memq (process-status p) '(run open)))
 
          ;; If `non-essential' is non-nil, don't reopen a new connection.
+         ;; This variable has been introduced with Emacs 24.1.
          (when (and (boundp 'non-essential) (symbol-value 'non-essential))
            (throw 'non-essential 'non-essential))
 
@@ -4647,8 +4770,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)
@@ -4668,7 +4790,7 @@ connection if a previous connection has died for some reason."
                ;; Set sentinel and query flag.
                (tramp-set-connection-property p "vector" vec)
                (set-process-sentinel p 'tramp-process-sentinel)
-               (tramp-compat-set-process-query-on-exit-flag p nil)
+               (set-process-query-on-exit-flag p nil)
                (setq tramp-current-connection
                      (cons (butlast (append vec nil) 2) (current-time))
                      tramp-current-host (system-name))
@@ -4689,22 +4811,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)))
@@ -4892,8 +5010,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
@@ -4968,12 +5086,12 @@ Return ATTR."
     (when (and (numberp (nth 2 attr)) (< (nth 2 attr) 0))
       (setcar (nthcdr 2 attr) -1))
     (when (and (floatp (nth 2 attr))
-               (<= (nth 2 attr) (tramp-compat-most-positive-fixnum)))
+               (<= (nth 2 attr) most-positive-fixnum))
       (setcar (nthcdr 2 attr) (round (nth 2 attr))))
     (when (and (numberp (nth 3 attr)) (< (nth 3 attr) 0))
       (setcar (nthcdr 3 attr) -1))
     (when (and (floatp (nth 3 attr))
-               (<= (nth 3 attr) (tramp-compat-most-positive-fixnum)))
+               (<= (nth 3 attr) most-positive-fixnum))
       (setcar (nthcdr 3 attr) (round (nth 3 attr))))
     ;; Convert last access time.
     (unless (listp (nth 4 attr))
@@ -4994,7 +5112,7 @@ Return ATTR."
     (when (< (nth 7 attr) 0)
       (setcar (nthcdr 7 attr) -1))
     (when (and (floatp (nth 7 attr))
-               (<= (nth 7 attr) (tramp-compat-most-positive-fixnum)))
+               (<= (nth 7 attr) most-positive-fixnum))
       (setcar (nthcdr 7 attr) (round (nth 7 attr))))
     ;; Convert file mode bits to string.
     (unless (stringp (nth 8 attr))
@@ -5042,14 +5160,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)))
@@ -5059,7 +5180,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
@@ -5098,25 +5219,32 @@ Return ATTR."
            ;; The login shell could return more than just the $PATH
            ;; string.  So we use `tramp-end-of-heredoc' as marker.
            (when elt2
-             (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)
-               (mapconcat
-                'identity
-                (tramp-get-method-parameter
-                 (tramp-file-name-method vec) 'tramp-remote-shell-args)
-                " ")
-               (tramp-shell-quote-argument tramp-end-of-heredoc))
-              nil (regexp-quote tramp-end-of-heredoc)))))
+             (or
+              (tramp-send-command-and-read
+               vec
+               (format
+                "%s %s %s 'echo %s \\\"$PATH\\\"'"
+                (tramp-get-method-parameter vec 'tramp-remote-shell)
+                (mapconcat
+                 'identity
+                 (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))
+               'noerror (regexp-quote tramp-end-of-heredoc))
+              (progn
+                (tramp-message
+                 vec 2 "Could not retrieve `tramp-own-remote-path'")
+                nil)))))
 
       ;; Replace place holder `tramp-default-remote-path'.
       (when elt1
        (setcdr elt1
                (append
-                (tramp-compat-split-string (or default-remote-path "") ":")
+                 (split-string (or default-remote-path "") ":" 'omit)
                 (cdr elt1)))
        (setq remote-path (delq 'tramp-default-remote-path remote-path)))
 
@@ -5124,7 +5252,7 @@ Return ATTR."
       (when elt2
        (setcdr elt2
                (append
-                (tramp-compat-split-string (or own-remote-path "") ":")
+                 (split-string (or own-remote-path "") ":" 'omit)
                 (cdr elt2)))
        (setq remote-path (delq 'tramp-own-remote-path remote-path)))
 
@@ -5154,7 +5282,7 @@ Return ATTR."
 (defun tramp-get-remote-locale (vec)
   (with-tramp-connection-property vec "locale"
     (tramp-send-command vec "locale -a")
-    (let ((candidates '("en_US.utf8" "C.utf8"))
+    (let ((candidates '("en_US.utf8" "C.utf8" "en_US.UTF-8"))
          locale)
       (with-current-buffer (tramp-get-connection-buffer vec)
        (while candidates
@@ -5206,13 +5334,20 @@ Return ATTR."
   (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-ls-command-with-w-option (vec)
+  (save-match-data
+    (with-tramp-connection-property vec "ls-w-option"
+      (tramp-message vec 5 "Checking, whether `ls -w' works")
+      ;; Option "-w" is available on BSD systems.  No argument is
+      ;; given, because this could return wrong results in case "ls"
+      ;; supports the "-w NUM" argument, as for busyboxes.
+      (tramp-send-command-and-check
+       vec (format "%s -alw" (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")
@@ -5321,7 +5456,7 @@ Return ATTR."
           "%s -t %s %s"
           result
           (format-time-string "%Y%m%d%H%M.%S")
-          (tramp-file-name-handler 'file-remote-p tmpfile 'localname))))
+          (file-remote-p tmpfile 'localname))))
        (delete-file tmpfile))
       result)))
 
@@ -5356,7 +5491,7 @@ Return ATTR."
           (tramp-get-remote-id vec)
           (if (equal id-format 'integer) "" "n")
           (if (equal id-format 'integer)
-              "" "| sed -e s/^/\\\"/ -e s/\$/\\\"/"))))
+              "" "| sed -e s/^/\\\"/ -e s/\\$/\\\"/"))))
 
 (defun tramp-get-remote-uid-with-perl (vec id-format)
   (tramp-send-command-and-read
@@ -5407,7 +5542,7 @@ Return ATTR."
           (tramp-get-remote-id vec)
           (if (equal id-format 'integer) "" "n")
           (if (equal id-format 'integer)
-              "" "| sed -e s/^/\\\"/ -e s/\$/\\\"/"))))
+              "" "| sed -e s/^/\\\"/ -e s/\\$/\\\"/"))))
 
 (defun tramp-get-remote-gid-with-perl (vec id-format)
   (tramp-send-command-and-read
@@ -5470,7 +5605,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
@@ -5504,7 +5639,7 @@ function cell is returned to be applied on a buffer."
                       (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)
@@ -5513,7 +5648,7 @@ function cell is returned to be applied on a buffer."
                     (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)))))
@@ -5559,8 +5694,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
@@ -5606,5 +5739,7 @@ function cell is returned to be applied on a buffer."
 ;;   rsync).
 ;; * Keep a second connection open for out-of-band methods like scp or
 ;;   rsync.
+;; * Check, whether we could also use "getent passwd" and "getent
+;;   group" for user/group name completion.
 
 ;;; tramp-sh.el ends here