Spelling fixes.
[bpt/emacs.git] / lisp / net / tramp-sh.el
index a25877a..51fc6e2 100644 (file)
@@ -28,7 +28,6 @@
 
 (eval-when-compile (require 'cl))      ; ignore-errors
 (require 'tramp)
-(require 'shell)
 
 ;; Pacify byte-compiler.  The function is needed on XEmacs only.  I'm
 ;; not sure at all that this is the right way to do it, but let's hope
@@ -66,6 +65,9 @@ files conditionalize this setup based on the TERM environment variable."
   :group 'tramp
   :type 'string)
 
+(defconst tramp-color-escape-sequence-regexp "\e[[;0-9]+m"
+  "Escape sequences produced by the \"ls\" command.")
+
 ;; ksh on OpenBSD 4.5 requires that $PS1 contains a `#' character for
 ;; root users.  It uses the `$' character for other users.  In order
 ;; to guarantee a proper prompt, we use "#$ " for the prompt.
@@ -88,7 +90,8 @@ detected as prompt when being sent on echoing hosts, therefore.")
   '("rcp"
     (tramp-login-program        "rsh")
     (tramp-login-args           (("%h") ("-l" "%u")))
-    (tramp-remote-sh            "/bin/sh")
+    (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-args    ("-c"))
     (tramp-copy-program         "rcp")
     (tramp-copy-args            (("-p" "%k") ("-r")))
     (tramp-copy-keep-date       t)
@@ -98,7 +101,8 @@ detected as prompt when being sent on echoing hosts, therefore.")
   '("remcp"
     (tramp-login-program        "remsh")
     (tramp-login-args           (("%h") ("-l" "%u")))
-    (tramp-remote-sh            "/bin/sh")
+    (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-args    ("-c"))
     (tramp-copy-program         "rcp")
     (tramp-copy-args            (("-p" "%k")))
     (tramp-copy-keep-date       t)))
@@ -108,7 +112,8 @@ detected as prompt when being sent on echoing hosts, therefore.")
    (tramp-login-program        "ssh")
    (tramp-login-args           (("-l" "%u") ("-p" "%p")        ("-e" "none") ("%h")))
    (tramp-async-args           (("-q")))
-   (tramp-remote-sh            "/bin/sh")
+   (tramp-remote-shell         "/bin/sh")
+   (tramp-remote-shell-args    ("-c"))
    (tramp-copy-program         "scp")
    (tramp-copy-args            (("-P" "%p") ("-p" "%k")        ("-q") ("-r")))
    (tramp-copy-keep-date       t)
@@ -124,7 +129,8 @@ detected as prompt when being sent on echoing hosts, therefore.")
     (tramp-login-args           (("-l" "%u") ("-p" "%p")
                                 ("-1") ("-e" "none") ("%h")))
     (tramp-async-args           (("-q")))
-    (tramp-remote-sh            "/bin/sh")
+    (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-args    ("-c"))
     (tramp-copy-program         "scp")
     (tramp-copy-args            (("-1") ("-P" "%p") ("-p" "%k") ("-q") ("-r")))
     (tramp-copy-keep-date       t)
@@ -140,7 +146,8 @@ detected as prompt when being sent on echoing hosts, therefore.")
     (tramp-login-args           (("-l" "%u") ("-p" "%p")
                                 ("-2") ("-e" "none") ("%h")))
     (tramp-async-args           (("-q")))
-    (tramp-remote-sh            "/bin/sh")
+    (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-args    ("-c"))
     (tramp-copy-program         "scp")
     (tramp-copy-args            (("-2") ("-P" "%p") ("-p" "%k") ("-q") ("-r")))
     (tramp-copy-keep-date       t)
@@ -158,7 +165,8 @@ detected as prompt when being sent on echoing hosts, therefore.")
                                 ("-o" "ControlMaster=yes")
                                 ("-e" "none") ("%h")))
     (tramp-async-args           (("-q")))
-    (tramp-remote-sh            "/bin/sh")
+    (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-args    ("-c"))
     (tramp-copy-program         "scp")
     (tramp-copy-args            (("-P" "%p") ("-p" "%k") ("-q") ("-r")
                                 ("-o" "ControlPath=%t.%%r@%%h:%%p")
@@ -177,7 +185,8 @@ detected as prompt when being sent on echoing hosts, therefore.")
                                 ("-e" "none") ("-t" "-t")
                                 ("%h") ("/bin/sh")))
     (tramp-async-args           (("-q")))
-    (tramp-remote-sh            "/bin/sh")
+    (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-args    ("-c"))
     (tramp-copy-program         "scp")
     (tramp-copy-args            (("-P" "%p") ("-p" "%k") ("-q") ("-r")))
     (tramp-copy-keep-date       t)
@@ -192,7 +201,8 @@ detected as prompt when being sent on echoing hosts, therefore.")
     (tramp-login-program        "ssh")
     (tramp-login-args           (("-l" "%u") ("-p" "%p") ("-e" "none") ("%h")))
     (tramp-async-args           (("-q")))
-    (tramp-remote-sh            "/bin/sh")
+    (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-args    ("-c"))
     (tramp-copy-program         "sftp")))
 ;;;###tramp-autoload
 (add-to-list 'tramp-methods
@@ -200,7 +210,8 @@ detected as prompt when being sent on echoing hosts, therefore.")
     (tramp-login-program        "ssh")
     (tramp-login-args           (("-l" "%u") ("-p" "%p") ("-e" "none") ("%h")))
     (tramp-async-args           (("-q")))
-    (tramp-remote-sh            "/bin/sh")
+    (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-args    ("-c"))
     (tramp-copy-program         "rsync")
     (tramp-copy-args            (("-e" "ssh") ("-t" "%k") ("-r")))
     (tramp-copy-keep-date       t)
@@ -215,7 +226,8 @@ detected as prompt when being sent on echoing hosts, therefore.")
                                 ("-o" "ControlMaster=yes")
                                 ("-e" "none") ("%h")))
     (tramp-async-args           (("-q")))
-    (tramp-remote-sh            "/bin/sh")
+    (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-args    ("-c"))
     (tramp-copy-program         "rsync")
     (tramp-copy-args            (("-t" "%k") ("-r")))
     (tramp-copy-env             (("RSYNC_RSH")
@@ -231,20 +243,23 @@ detected as prompt when being sent on echoing hosts, therefore.")
   '("rsh"
     (tramp-login-program        "rsh")
     (tramp-login-args           (("%h") ("-l" "%u")))
-    (tramp-remote-sh            "/bin/sh")))
+    (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-args    ("-c"))))
 ;;;###tramp-autoload
 (add-to-list 'tramp-methods
   '("remsh"
     (tramp-login-program        "remsh")
     (tramp-login-args           (("%h") ("-l" "%u")))
-    (tramp-remote-sh            "/bin/sh")))
+    (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-args    ("-c"))))
 ;;;###tramp-autoload
 (add-to-list 'tramp-methods
   '("ssh"
     (tramp-login-program        "ssh")
     (tramp-login-args           (("-l" "%u") ("-p" "%p") ("-e" "none") ("%h")))
     (tramp-async-args           (("-q")))
-    (tramp-remote-sh            "/bin/sh")
+    (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-args    ("-c"))
     (tramp-gw-args              (("-o" "GlobalKnownHostsFile=/dev/null")
                                 ("-o" "UserKnownHostsFile=/dev/null")
                                 ("-o" "StrictHostKeyChecking=no")))
@@ -256,7 +271,8 @@ detected as prompt when being sent on echoing hosts, therefore.")
     (tramp-login-args           (("-l" "%u") ("-p" "%p")
                                 ("-1") ("-e" "none") ("%h")))
     (tramp-async-args           (("-q")))
-    (tramp-remote-sh            "/bin/sh")
+    (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-args    ("-c"))
     (tramp-gw-args              (("-o" "GlobalKnownHostsFile=/dev/null")
                                 ("-o" "UserKnownHostsFile=/dev/null")
                                 ("-o" "StrictHostKeyChecking=no")))
@@ -268,7 +284,8 @@ detected as prompt when being sent on echoing hosts, therefore.")
     (tramp-login-args           (("-l" "%u") ("-p" "%p")
                                 ("-2") ("-e" "none") ("%h")))
     (tramp-async-args           (("-q")))
-    (tramp-remote-sh            "/bin/sh")
+    (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-args    ("-c"))
     (tramp-gw-args              (("-o" "GlobalKnownHostsFile=/dev/null")
                                 ("-o" "UserKnownHostsFile=/dev/null")
                                 ("-o" "StrictHostKeyChecking=no")))
@@ -281,7 +298,8 @@ detected as prompt when being sent on echoing hosts, therefore.")
                                 ("-e" "none") ("-t" "-t")
                                 ("%h") ("/bin/sh")))
     (tramp-async-args           (("-q")))
-    (tramp-remote-sh            "/bin/sh")
+    (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-args    ("-c"))
     (tramp-gw-args              (("-o" "GlobalKnownHostsFile=/dev/null")
                                 ("-o" "UserKnownHostsFile=/dev/null")
                                 ("-o" "StrictHostKeyChecking=no")))
@@ -291,38 +309,44 @@ detected as prompt when being sent on echoing hosts, therefore.")
   '("telnet"
     (tramp-login-program        "telnet")
     (tramp-login-args           (("%h") ("%p")))
-    (tramp-remote-sh            "/bin/sh")
+    (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-args    ("-c"))
     (tramp-default-port         23)))
 ;;;###tramp-autoload
 (add-to-list 'tramp-methods
   '("su"
     (tramp-login-program        "su")
     (tramp-login-args           (("-") ("%u")))
-    (tramp-remote-sh            "/bin/sh")))
+    (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-args    ("-c"))))
 ;;;###tramp-autoload
 (add-to-list 'tramp-methods
   '("sudo"
     (tramp-login-program        "sudo")
     (tramp-login-args           (("-u" "%u") ("-s") ("-H") ("-p" "Password:")))
-    (tramp-remote-sh            "/bin/sh")))
+    (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-args    ("-c"))))
 ;;;###tramp-autoload
 (add-to-list 'tramp-methods
   '("ksu"
     (tramp-login-program        "ksu")
     (tramp-login-args           (("%u") ("-q")))
-    (tramp-remote-sh            "/bin/sh")))
+    (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-args    ("-c"))))
 ;;;###tramp-autoload
 (add-to-list 'tramp-methods
   '("krlogin"
     (tramp-login-program        "krlogin")
     (tramp-login-args           (("%h") ("-l" "%u") ("-x")))
-    (tramp-remote-sh            "/bin/sh")))
+    (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-args    ("-c"))))
 ;;;###tramp-autoload
 (add-to-list 'tramp-methods
   '("plink"
     (tramp-login-program        "plink")
     (tramp-login-args           (("-l" "%u") ("-P" "%p") ("-ssh") ("%h")))
-    (tramp-remote-sh            "/bin/sh")
+    (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-args    ("-c"))
     (tramp-password-end-of-line "xy") ;see docstring for "xy"
     (tramp-default-port         22)))
 ;;;###tramp-autoload
@@ -330,7 +354,8 @@ detected as prompt when being sent on echoing hosts, therefore.")
   '("plink1"
     (tramp-login-program        "plink")
     (tramp-login-args           (("-l" "%u") ("-P" "%p") ("-1" "-ssh") ("%h")))
-    (tramp-remote-sh            "/bin/sh")
+    (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-args    ("-c"))
     (tramp-password-end-of-line "xy") ;see docstring for "xy"
     (tramp-default-port         22)))
 ;;;###tramp-autoload
@@ -345,13 +370,15 @@ detected as prompt when being sent on echoing hosts, therefore.")
                                    tramp-terminal-type
                                    tramp-initial-end-of-output))
                                 ("/bin/sh")))
-    (tramp-remote-sh            "/bin/sh")))
+    (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-args    ("-c"))))
 ;;;###tramp-autoload
 (add-to-list 'tramp-methods
   '("pscp"
     (tramp-login-program        "plink")
     (tramp-login-args           (("-l" "%u") ("-P" "%p") ("-ssh") ("%h")))
-    (tramp-remote-sh            "/bin/sh")
+    (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-args    ("-c"))
     (tramp-copy-program         "pscp")
     (tramp-copy-args            (("-P" "%p") ("-scp") ("-p" "%k")
                                 ("-q") ("-r")))
@@ -364,7 +391,8 @@ detected as prompt when being sent on echoing hosts, therefore.")
   '("psftp"
     (tramp-login-program        "plink")
     (tramp-login-args           (("-l" "%u") ("-P" "%p") ("-ssh") ("%h")))
-    (tramp-remote-sh            "/bin/sh")
+    (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-args    ("-c"))
     (tramp-copy-program         "pscp")
     (tramp-copy-args            (("-P" "%p") ("-sftp") ("-p" "%k")
                                 ("-q") ("-r")))
@@ -376,7 +404,8 @@ detected as prompt when being sent on echoing hosts, therefore.")
   '("fcp"
     (tramp-login-program        "fsh")
     (tramp-login-args           (("%h") ("-l" "%u") ("sh" "-i")))
-    (tramp-remote-sh            "/bin/sh -i")
+    (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-args    ("-i") ("-c"))
     (tramp-copy-program         "fcp")
     (tramp-copy-args            (("-p" "%k")))
     (tramp-copy-keep-date       t)))
@@ -400,11 +429,13 @@ detected as prompt when being sent on echoing hosts, therefore.")
                 "\\'")
               nil ,(user-login-name)))
 
+;;;###tramp-autoload
 (defconst tramp-completion-function-alist-rsh
   '((tramp-parse-rhosts "/etc/hosts.equiv")
     (tramp-parse-rhosts "~/.rhosts"))
   "Default list of (FUNCTION FILE) pairs to be examined for rsh methods.")
 
+;;;###tramp-autoload
 (defconst tramp-completion-function-alist-ssh
   '((tramp-parse-rhosts      "/etc/hosts.equiv")
     (tramp-parse-rhosts      "/etc/shosts.equiv")
@@ -420,47 +451,60 @@ detected as prompt when being sent on echoing hosts, therefore.")
     (tramp-parse-sknownhosts "~/.ssh2/knownhosts"))
   "Default list of (FUNCTION FILE) pairs to be examined for ssh methods.")
 
+;;;###tramp-autoload
 (defconst tramp-completion-function-alist-telnet
   '((tramp-parse-hosts "/etc/hosts"))
   "Default list of (FUNCTION FILE) pairs to be examined for telnet methods.")
 
+;;;###tramp-autoload
 (defconst tramp-completion-function-alist-su
   '((tramp-parse-passwd "/etc/passwd"))
   "Default list of (FUNCTION FILE) pairs to be examined for su methods.")
 
+;;;###tramp-autoload
 (defconst tramp-completion-function-alist-putty
   '((tramp-parse-putty
      "HKEY_CURRENT_USER\\Software\\SimonTatham\\PuTTY\\Sessions"))
   "Default list of (FUNCTION REGISTRY) pairs to be examined for putty methods.")
 
-(tramp-set-completion-function "rcp" tramp-completion-function-alist-rsh)
-(tramp-set-completion-function "remcp" tramp-completion-function-alist-rsh)
-(tramp-set-completion-function "scp" tramp-completion-function-alist-ssh)
-(tramp-set-completion-function "scp1" tramp-completion-function-alist-ssh)
-(tramp-set-completion-function "scp2" tramp-completion-function-alist-ssh)
-(tramp-set-completion-function "scpc" tramp-completion-function-alist-ssh)
-(tramp-set-completion-function "scpx" tramp-completion-function-alist-ssh)
-(tramp-set-completion-function "sftp" tramp-completion-function-alist-ssh)
-(tramp-set-completion-function "rsync" tramp-completion-function-alist-ssh)
-(tramp-set-completion-function "rsyncc" tramp-completion-function-alist-ssh)
-(tramp-set-completion-function "rsh" tramp-completion-function-alist-rsh)
-(tramp-set-completion-function "remsh" tramp-completion-function-alist-rsh)
-(tramp-set-completion-function "ssh" tramp-completion-function-alist-ssh)
-(tramp-set-completion-function "ssh1" tramp-completion-function-alist-ssh)
-(tramp-set-completion-function "ssh2" tramp-completion-function-alist-ssh)
-(tramp-set-completion-function "ssh1_old" tramp-completion-function-alist-ssh)
-(tramp-set-completion-function "ssh2_old" tramp-completion-function-alist-ssh)
-(tramp-set-completion-function "sshx" tramp-completion-function-alist-ssh)
-(tramp-set-completion-function "telnet" tramp-completion-function-alist-telnet)
-(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 "krlogin" tramp-completion-function-alist-rsh)
-(tramp-set-completion-function "plink" tramp-completion-function-alist-ssh)
-(tramp-set-completion-function "plink1" tramp-completion-function-alist-ssh)
-(tramp-set-completion-function "plinkx" tramp-completion-function-alist-putty)
-(tramp-set-completion-function "pscp" tramp-completion-function-alist-ssh)
-(tramp-set-completion-function "fcp" tramp-completion-function-alist-ssh)
+;;;###tramp-autoload
+(eval-after-load 'tramp
+  '(progn
+     (tramp-set-completion-function "rcp" tramp-completion-function-alist-rsh)
+     (tramp-set-completion-function "remcp" tramp-completion-function-alist-rsh)
+     (tramp-set-completion-function "scp" tramp-completion-function-alist-ssh)
+     (tramp-set-completion-function "scp1" tramp-completion-function-alist-ssh)
+     (tramp-set-completion-function "scp2" tramp-completion-function-alist-ssh)
+     (tramp-set-completion-function "scpc" tramp-completion-function-alist-ssh)
+     (tramp-set-completion-function "scpx" tramp-completion-function-alist-ssh)
+     (tramp-set-completion-function "sftp" tramp-completion-function-alist-ssh)
+     (tramp-set-completion-function "rsync" tramp-completion-function-alist-ssh)
+     (tramp-set-completion-function
+      "rsyncc" tramp-completion-function-alist-ssh)
+     (tramp-set-completion-function "rsh" tramp-completion-function-alist-rsh)
+     (tramp-set-completion-function "remsh" tramp-completion-function-alist-rsh)
+     (tramp-set-completion-function "ssh" tramp-completion-function-alist-ssh)
+     (tramp-set-completion-function "ssh1" tramp-completion-function-alist-ssh)
+     (tramp-set-completion-function "ssh2" tramp-completion-function-alist-ssh)
+     (tramp-set-completion-function
+      "ssh1_old" tramp-completion-function-alist-ssh)
+     (tramp-set-completion-function
+      "ssh2_old" tramp-completion-function-alist-ssh)
+     (tramp-set-completion-function "sshx" tramp-completion-function-alist-ssh)
+     (tramp-set-completion-function
+      "telnet" tramp-completion-function-alist-telnet)
+     (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
+      "krlogin" tramp-completion-function-alist-rsh)
+     (tramp-set-completion-function "plink" tramp-completion-function-alist-ssh)
+     (tramp-set-completion-function
+      "plink1" tramp-completion-function-alist-ssh)
+     (tramp-set-completion-function
+      "plinkx" tramp-completion-function-alist-putty)
+     (tramp-set-completion-function "pscp" tramp-completion-function-alist-ssh)
+     (tramp-set-completion-function "fcp" tramp-completion-function-alist-ssh)))
 
 ;; "getconf PATH" yields:
 ;; HP-UX: /usr/bin:/usr/ccs/bin:/opt/ansic/bin:/opt/langtools/bin:/opt/fortran/bin
@@ -469,7 +513,7 @@ detected as prompt when being sent on echoing hosts, therefore.")
 ;; FreeBSD: /usr/bin:/bin:/usr/sbin:/sbin: - beware trailing ":"!
 ;; IRIX64: /usr/bin
 (defcustom tramp-remote-path
-  '(tramp-default-remote-path "/usr/sbin" "/usr/local/bin"
+  '(tramp-default-remote-path "/bin" "/usr/bin" "/usr/sbin" "/usr/local/bin"
     "/local/bin" "/local/freeware/bin" "/local/gnu/bin"
     "/usr/freeware/bin" "/usr/pkg/bin" "/usr/contrib/bin")
   "*List of directories to search for executables on remote host.
@@ -505,7 +549,7 @@ as given in your `~/.profile'."
   "*List of environment variables to be set on the remote host.
 
 Each element should be a string of the form ENVVARNAME=VALUE.  An
-entry ENVVARNAME= diables the corresponding environment variable,
+entry ENVVARNAME= disables the corresponding environment variable,
 which might have been set in the init files like ~/.profile.
 
 Special handling is applied to the PATH environment, which should
@@ -924,7 +968,7 @@ This is used to map a mode number to a permission string.")
     (executable-find . tramp-sh-handle-executable-find)
     (start-file-process . tramp-sh-handle-start-file-process)
     (process-file . tramp-sh-handle-process-file)
-    (shell-command . tramp-sh-handle-shell-command)
+    (shell-command . tramp-handle-shell-command)
     (insert-directory . tramp-sh-handle-insert-directory)
     (expand-file-name . tramp-sh-handle-expand-file-name)
     (substitute-in-file-name . tramp-handle-substitute-in-file-name)
@@ -1014,106 +1058,110 @@ target of the symlink differ."
 (defun tramp-sh-handle-file-truename (filename &optional counter prev-dirs)
   "Like `file-truename' for Tramp files."
   (with-parsed-tramp-file-name (expand-file-name filename) nil
-    (with-file-property v localname "file-truename"
-      (let ((result nil))                      ; result steps in reverse order
-       (tramp-message v 4 "Finding true name for `%s'" filename)
-       (cond
-        ;; Use GNU readlink --canonicalize-missing where available.
-        ((tramp-get-remote-readlink v)
-         (setq result
-               (tramp-send-command-and-read
-                v
-                (format "echo \"\\\"`%s --canonicalize-missing %s`\\\"\""
-                        (tramp-get-remote-readlink v)
-                        (tramp-shell-quote-argument localname)))))
-
-        ;; Use Perl implementation.
-        ((and (tramp-get-remote-perl v)
-              (tramp-get-connection-property v "perl-file-spec" nil)
-              (tramp-get-connection-property v "perl-cwd-realpath" nil))
-         (tramp-maybe-send-script
-          v tramp-perl-file-truename "tramp_perl_file_truename")
-         (setq result
-               (tramp-send-command-and-read
-                v
-                (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)
-             (while (and steps (< numchase numchase-limit))
-               (setq thisstep (pop steps))
-               (tramp-message
-                v 5 "Check %s"
-                (mapconcat 'identity
-                           (append '("") (reverse result) (list thisstep))
-                           "/"))
-               (setq symlink-target
-                     (nth 0 (file-attributes
-                             (tramp-make-tramp-file-name
-                              method user host
-                              (mapconcat 'identity
-                                         (append '("")
-                                                 (reverse result)
-                                                 (list thisstep))
-                                         "/")))))
-               (cond ((string= "." thisstep)
-                      (tramp-message v 5 "Ignoring step `.'"))
-                     ((string= ".." thisstep)
-                      (tramp-message v 5 "Processing step `..'")
-                      (pop result))
-                     ((stringp symlink-target)
-                      ;; It's a symlink, follow it.
-                      (tramp-message v 5 "Follow symlink to %s" symlink-target)
-                      (setq numchase (1+ numchase))
-                      (when (file-name-absolute-p symlink-target)
-                        (setq result nil))
-                      ;; If the symlink was absolute, we'll get a string like
-                      ;; "/user@host:/some/target"; extract the
-                      ;; "/some/target" part from it.
-                      (when (tramp-tramp-file-p symlink-target)
-                        (unless (tramp-equal-remote filename symlink-target)
-                          (tramp-error
-                           v 'file-error
-                           "Symlink target `%s' on wrong host" symlink-target))
-                        (setq symlink-target localname))
-                      (setq steps
-                            (append (tramp-compat-split-string
-                                     symlink-target "/")
-                                    steps)))
-                     (t
-                      ;; It's a file.
-                      (setq result (cons thisstep result)))))
-             (when (>= numchase numchase-limit)
-               (tramp-error
-                v 'file-error
-                "Maximum number (%d) of symlinks exceeded" numchase-limit))
-             (setq result (reverse result))
-             ;; Combine list to form string.
-             (setq result
-                   (if result
-                       (mapconcat 'identity (cons "" result) "/")
-                     "/"))
-             (when (and is-dir (or (string= "" result)
-                                   (not (string= (substring result -1) "/"))))
-               (setq result (concat result "/"))))))
-
-        (tramp-message v 4 "True name of `%s' is `%s'" filename result)
-        (tramp-make-tramp-file-name method user host result)))))
+    (tramp-make-tramp-file-name method user host
+      (with-file-property v localname "file-truename"
+       (let ((result nil))                     ; result steps in reverse order
+         (tramp-message v 4 "Finding true name for `%s'" filename)
+         (cond
+          ;; Use GNU readlink --canonicalize-missing where available.
+          ((tramp-get-remote-readlink v)
+           (setq result
+                 (tramp-send-command-and-read
+                  v
+                  (format "echo \"\\\"`%s --canonicalize-missing %s`\\\"\""
+                          (tramp-get-remote-readlink v)
+                          (tramp-shell-quote-argument localname)))))
+
+          ;; Use Perl implementation.
+          ((and (tramp-get-remote-perl v)
+                (tramp-get-connection-property v "perl-file-spec" nil)
+                (tramp-get-connection-property v "perl-cwd-realpath" nil))
+           (tramp-maybe-send-script
+            v tramp-perl-file-truename "tramp_perl_file_truename")
+           (setq result
+                 (tramp-send-command-and-read
+                  v
+                  (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)
+               (while (and steps (< numchase numchase-limit))
+                 (setq thisstep (pop steps))
+                 (tramp-message
+                  v 5 "Check %s"
+                  (mapconcat 'identity
+                             (append '("") (reverse result) (list thisstep))
+                             "/"))
+                 (setq symlink-target
+                       (nth 0 (file-attributes
+                               (tramp-make-tramp-file-name
+                                method user host
+                                (mapconcat 'identity
+                                           (append '("")
+                                                   (reverse result)
+                                                   (list thisstep))
+                                           "/")))))
+                 (cond ((string= "." thisstep)
+                        (tramp-message v 5 "Ignoring step `.'"))
+                       ((string= ".." thisstep)
+                        (tramp-message v 5 "Processing step `..'")
+                        (pop result))
+                       ((stringp symlink-target)
+                        ;; It's a symlink, follow it.
+                        (tramp-message
+                         v 5 "Follow symlink to %s" symlink-target)
+                        (setq numchase (1+ numchase))
+                        (when (file-name-absolute-p symlink-target)
+                          (setq result nil))
+                        ;; If the symlink was absolute, we'll get a
+                        ;; string like "/user@host:/some/target";
+                        ;; extract the "/some/target" part from it.
+                        (when (tramp-tramp-file-p symlink-target)
+                          (unless (tramp-equal-remote filename symlink-target)
+                            (tramp-error
+                             v 'file-error
+                             "Symlink target `%s' on wrong host"
+                             symlink-target))
+                          (setq symlink-target localname))
+                        (setq steps
+                              (append (tramp-compat-split-string
+                                       symlink-target "/")
+                                      steps)))
+                       (t
+                        ;; It's a file.
+                        (setq result (cons thisstep result)))))
+               (when (>= numchase numchase-limit)
+                 (tramp-error
+                  v 'file-error
+                  "Maximum number (%d) of symlinks exceeded" numchase-limit))
+               (setq result (reverse result))
+               ;; Combine list to form string.
+               (setq result
+                     (if result
+                         (mapconcat 'identity (cons "" result) "/")
+                       "/"))
+               (when (and is-dir
+                          (or (string= "" result)
+                              (not (string= (substring result -1) "/"))))
+                 (setq result (concat result "/"))))))
+
+         (tramp-message v 4 "True name of `%s' is `%s'" localname result)
+         result)))))
 
 ;; Basic functions.
 
@@ -1550,17 +1598,14 @@ and gid of the corresponding user is taken.  Both parameters must be integers."
 
 (defun tramp-sh-handle-file-directory-p (filename)
   "Like `file-directory-p' for Tramp files."
-  ;; Care must be taken that this function returns `t' for symlinks
-  ;; pointing to directories.  Surely the most obvious implementation
-  ;; would be `test -d', but that returns false for such symlinks.
-  ;; CCC: Stefan Monnier says that `test -d' follows symlinks.  And
-  ;; I now think he's right.  So we could be using `test -d', couldn't
-  ;; we?
-  ;;
-  ;; Alternatives: `cd %s', `test -d %s'
   (with-parsed-tramp-file-name filename nil
-    (with-file-property v localname "file-directory-p"
-      (tramp-run-test "-d" filename))))
+    ;; `file-directory-p' is used as predicate for filename completion.
+    ;; Sometimes, when a connection is not established yet, it is
+    ;; desirable to return t immediately for "/method:foo:".  It can
+    ;; be expected that this is always a directory.
+    (or (zerop (length localname))
+       (with-file-property v localname "file-directory-p"
+         (tramp-run-test "-d" filename)))))
 
 (defun tramp-sh-handle-file-writable-p (filename)
   "Like `file-writable-p' for Tramp files."
@@ -1694,7 +1739,9 @@ and gid of the corresponding user is taken.  Both parameters must be integers."
                        "file-name-all-completions"
                        nil)))
                  (when cache-hit (list cache-hit))))
-             (tramp-compat-number-sequence (length filename) 0 -1)))))
+             ;; We cannot use a length of 0, because file properties
+             ;; for "foo" and "foo/" are identical.
+             (tramp-compat-number-sequence (length filename) 1 -1)))))
 
          ;; Cache expired or no matching cache entry found so we need
          ;; to perform a remote operation.
@@ -1759,12 +1806,12 @@ and gid of the corresponding user is taken.  Both parameters must be integers."
            (with-current-buffer (tramp-get-buffer v)
              (goto-char (point-max))
 
-             ;; Check result code, found in last line of output
+             ;; Check result code, found in last line of output.
              (forward-line -1)
              (if (looking-at "^fail$")
                  (progn
                    ;; Grab error message from line before last line
-                   ;; (it was put there by `cd 2>&1')
+                   ;; (it was put there by `cd 2>&1').
                    (forward-line -1)
                    (tramp-error
                     v 'file-error
@@ -1785,9 +1832,8 @@ tramp-sh-handle-file-name-all-completions: internal error accessing `%s': `%s'"
                (push (buffer-substring (point) (point-at-eol)) result)))
 
            ;; Because the remote op went through OK we know the
-           ;; directory we `cd'-ed to exists
-           (tramp-set-file-property
-            v localname "file-exists-p" t)
+           ;; directory we `cd'-ed to exists.
+           (tramp-set-file-property v localname "file-exists-p" t)
 
            ;; Because the remote op went through OK we know every
            ;; file listed by `ls' exists.
@@ -1796,11 +1842,10 @@ tramp-sh-handle-file-name-all-completions: internal error accessing `%s': `%s'"
                    v (concat localname entry) "file-exists-p" t))
                 result)
 
-           ;; Store result in the cache
+           ;; Store result in the cache.
            (tramp-set-file-property
             v (concat localname filename)
-            "file-name-all-completions"
-            result))))))))
+           "file-name-all-completions" result))))))))
 
 ;; cp, mv and ln
 
@@ -2236,7 +2281,7 @@ The method used must be an out-of-band method."
        ;; password.
        (setq tramp-current-method (tramp-file-name-method v)
              tramp-current-user   (tramp-file-name-user v)
-             tramp-current-host   (tramp-file-name-host v))
+             tramp-current-host   (tramp-file-name-real-host v))
 
        ;; Expand hops.  Might be necessary for gateway methods.
        (setq v (car (tramp-compute-multi-hops v)))
@@ -2567,6 +2612,12 @@ This is like `dired-recursive-delete-directory' for Tramp files."
          (forward-line 1)
          (delete-region (match-beginning 0) (point)))
 
+       ;; Some busyboxes are reluctant to discard colors.
+       (unless (string-match "color" (tramp-get-connection-property v "ls" ""))
+         (goto-char beg)
+         (while (re-search-forward tramp-color-escape-sequence-regexp nil t)
+           (replace-match "")))
+
        ;; The inserted file could be from somewhere else.
        (when (and (not wildcard) (not full-directory-p))
          (goto-char (point-max))
@@ -2654,6 +2705,7 @@ the result will be a local, non-Tramp, filename."
     (let ((vec (tramp-get-connection-property proc "vector" nil)))
       (when vec
        (tramp-message vec 5 "Sentinel called: `%s' `%s'" proc event)
+        (tramp-flush-connection-property proc)
         (tramp-flush-directory-property vec "")))))
 
 ;; We use BUFFER also as connection buffer during setup. Because of
@@ -2665,8 +2717,13 @@ the result will be a local, non-Tramp, filename."
     ;; When PROGRAM is nil, we just provide a tty.
     (let ((command
           (when (stringp program)
-            (format "cd %s; exec %s"
+            (format "cd %s; exec env PS1=%s %s"
                     (tramp-shell-quote-argument localname)
+                    ;; Use a human-friendly prompt, for example for `shell'.
+                    (tramp-shell-quote-argument
+                     (format "%s %s"
+                             (file-remote-p default-directory)
+                             tramp-initial-end-of-output))
                     (mapconcat 'tramp-shell-quote-argument
                                (cons program args) " "))))
          (tramp-process-connection-type
@@ -2706,9 +2763,7 @@ the result will be a local, non-Tramp, filename."
                       v 'file-error
                       "pty association is not supported for `%s'" name)))))
              (let ((p (tramp-get-connection-process v)))
-               ;; Set sentinel and query flag for this process.
-               (tramp-set-connection-property p "vector" v)
-               (set-process-sentinel p 'tramp-process-sentinel)
+               ;; Set query flag for this process.
                (tramp-compat-set-process-query-on-exit-flag p t)
                ;; Return process.
                p)))
@@ -2825,7 +2880,7 @@ the result will be a local, non-Tramp, filename."
       ;; `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'.
+      ;; value `t'.
       (unless (and (boundp 'process-file-side-effects)
                   (not (symbol-value 'process-file-side-effects)))
         (tramp-flush-directory-property v ""))
@@ -2845,87 +2900,6 @@ the result will be a local, non-Tramp, filename."
        (apply 'call-process program tmpfile buffer display args)
       (delete-file tmpfile))))
 
-(defun tramp-sh-handle-shell-command
-  (command &optional output-buffer error-buffer)
-  "Like `shell-command' for Tramp files."
-  (let* ((asynchronous (string-match "[ \t]*&[ \t]*\\'" command))
-        ;; We cannot use `shell-file-name' and `shell-command-switch',
-        ;; they are variables of the local host.
-        (args (list
-               (tramp-get-method-parameter
-                (tramp-file-name-method
-                 (tramp-dissect-file-name default-directory))
-                'tramp-remote-sh)
-               "-c" (substring command 0 asynchronous)))
-        current-buffer-p
-        (output-buffer
-         (cond
-          ((bufferp output-buffer) output-buffer)
-          ((stringp output-buffer) (get-buffer-create output-buffer))
-          (output-buffer
-           (setq current-buffer-p t)
-           (current-buffer))
-          (t (get-buffer-create
-              (if asynchronous
-                  "*Async Shell Command*"
-                "*Shell Command Output*")))))
-        (error-buffer
-         (cond
-          ((bufferp error-buffer) error-buffer)
-          ((stringp error-buffer) (get-buffer-create error-buffer))))
-        (buffer
-         (if (and (not asynchronous) error-buffer)
-             (with-parsed-tramp-file-name default-directory nil
-               (list output-buffer (tramp-make-tramp-temp-file v)))
-           output-buffer))
-        (p (get-buffer-process output-buffer)))
-
-    ;; Check whether there is another process running.  Tramp does not
-    ;; support 2 (asynchronous) processes in parallel.
-    (when p
-      (if (yes-or-no-p "A command is running.  Kill it? ")
-         (ignore-errors (kill-process p))
-       (error "Shell command in progress")))
-
-    (if current-buffer-p
-       (progn
-         (barf-if-buffer-read-only)
-         (push-mark nil t))
-      (with-current-buffer output-buffer
-       (setq buffer-read-only nil)
-       (erase-buffer)))
-
-    (if (and (not current-buffer-p) (integerp asynchronous))
-       (prog1
-           ;; Run the process.
-           (apply 'start-file-process "*Async Shell*" buffer args)
-         ;; Display output.
-         (pop-to-buffer output-buffer)
-         (setq mode-line-process '(":%s"))
-         (shell-mode))
-
-      (prog1
-         ;; Run the process.
-         (apply 'process-file (car args) nil buffer nil (cdr args))
-       ;; Insert error messages if they were separated.
-       (when (listp buffer)
-         (with-current-buffer error-buffer
-           (insert-file-contents (cadr buffer)))
-         (delete-file (cadr buffer)))
-       (if current-buffer-p
-           ;; This is like exchange-point-and-mark, but doesn't
-           ;; activate the mark.  It is cleaner to avoid activation,
-           ;; even though the command loop would deactivate the mark
-           ;; because we inserted text.
-           (goto-char (prog1 (mark t)
-                        (set-marker (mark-marker) (point)
-                                    (current-buffer))))
-         ;; There's some output, display it.
-         (when (with-current-buffer output-buffer (> (point-max) (point-min)))
-           (if (functionp 'display-message-or-buffer)
-               (tramp-compat-funcall 'display-message-or-buffer output-buffer)
-             (pop-to-buffer output-buffer))))))))
-
 (defun tramp-sh-handle-file-local-copy (filename)
   "Like `file-local-copy' for Tramp files."
   (with-parsed-tramp-file-name filename nil
@@ -3429,8 +3403,10 @@ Fall back to normal file name handler if no Tramp handler exists."
 (defun tramp-maybe-send-script (vec script name)
   "Define in remote shell function NAME implemented as SCRIPT.
 Only send the definition if it has not already been done."
-  (let* ((p (tramp-get-connection-process vec))
-        (scripts (tramp-get-connection-property p "scripts" nil)))
+  ;; We cannot let-bind (tramp-get-connection-process vec) because it
+  ;; might be nil.
+  (let ((scripts (tramp-get-connection-property
+                 (tramp-get-connection-process vec) "scripts" nil)))
     (unless (member name scripts)
       (tramp-with-progress-reporter vec 5 (format "Sending script `%s'" name)
        ;; The script could contain a call of Perl.  This is masked with `%s'.
@@ -3439,7 +3415,8 @@ Only send the definition if it has not already been done."
         (format "%s () {\n%s\n}" name
                 (format script (tramp-get-remote-perl vec)))
         "Script %s sending failed" name)
-       (tramp-set-connection-property p "scripts" (cons name scripts))))))
+       (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
@@ -3609,11 +3586,11 @@ file exists and nonzero exit status otherwise."
       (when extra-args (setq shell (concat shell " " extra-args)))
       (tramp-send-command
        vec (format "exec env ENV='' PROMPT_COMMAND='' PS1=%s PS2='' PS3='' %s"
-                  (shell-quote-argument tramp-end-of-output) shell)
+                  (tramp-shell-quote-argument tramp-end-of-output) shell)
        t))
     ;; Setting prompts.
     (tramp-send-command
-     vec (format "PS1=%s" (shell-quote-argument tramp-end-of-output)) t)
+     vec (format "PS1=%s" (tramp-shell-quote-argument tramp-end-of-output)) t)
     (tramp-send-command vec "PS2=''" t)
     (tramp-send-command vec "PS3=''" t)
     (tramp-send-command vec "PROMPT_COMMAND=''" t)))
@@ -3626,9 +3603,11 @@ file exists and nonzero exit status otherwise."
        (tramp-send-command vec "echo ~root" t)
        (cond
         ((or (string-match "^~root$" (buffer-string))
-             ;; The default shell (ksh93) of OpenSolaris is buggy.
-             (string-equal (tramp-get-connection-property vec "uname" "")
-                           "SunOS 5.11"))
+             ;; The default shell (ksh93) of OpenSolaris and Solaris
+             ;; is buggy.  We've got reports for "SunOS 5.10" and
+             ;; "SunOS 5.11" so far.
+             (string-match (regexp-opt '("SunOS 5.10" "SunOS 5.11"))
+                           (tramp-get-connection-property vec "uname" "")))
          (setq shell
                (or (tramp-find-executable
                     vec "bash" (tramp-get-remote-path vec) t t)
@@ -3647,7 +3626,7 @@ file exists and nonzero exit status otherwise."
             (tramp-set-connection-property
              vec "remote-shell"
              (tramp-get-method-parameter
-              (tramp-file-name-method vec) 'tramp-remote-sh)))))))))
+              (tramp-file-name-method vec) 'tramp-remote-shell)))))))))
 
 ;; Utility functions.
 
@@ -3683,7 +3662,8 @@ process to set up.  VEC specifies the connection."
     ;; discarded as well.
     (tramp-open-shell
      vec
-     (tramp-get-method-parameter (tramp-file-name-method vec) 'tramp-remote-sh))
+     (tramp-get-method-parameter
+      (tramp-file-name-method vec) 'tramp-remote-shell))
 
     ;; Disable echo.
     (tramp-message vec 5 "Setting up remote shell environment")
@@ -3703,7 +3683,7 @@ process to set up.  VEC specifies the connection."
 
   (tramp-message vec 5 "Setting shell prompt")
   (tramp-send-command
-   vec (format "PS1=%s" (shell-quote-argument tramp-end-of-output)) t)
+   vec (format "PS1=%s" (tramp-shell-quote-argument tramp-end-of-output)) t)
   (tramp-send-command vec "PS2=''" t)
   (tramp-send-command vec "PS3=''" t)
   (tramp-send-command vec "PROMPT_COMMAND=''" t)
@@ -3817,10 +3797,9 @@ process to set up.  VEC specifies the connection."
     (tramp-send-command vec "stty -oxtabs" t))
 
   ;; Set `remote-tty' process property.
-  (ignore-errors
-    (let ((tty (tramp-send-command-and-read vec "echo \\\"`tty`\\\"")))
-      (unless (zerop (length tty))
-       (tramp-compat-process-put proc 'remote-tty tty))))
+  (let ((tty (tramp-send-command-and-read vec "echo \\\"`tty`\\\"" 'noerror)))
+    (unless (zerop (length tty))
+      (tramp-compat-process-put proc 'remote-tty tty)))
 
   ;; Dump stty settings in the traces.
   (when (>= tramp-verbose 9)
@@ -4047,6 +4026,7 @@ means discard it)."
 (defconst tramp-inline-compress-commands
   '(("gzip" "gzip -d")
     ("bzip2" "bzip2 -d")
+    ("xz" "xz -d")
     ("compress" "compress -d"))
   "List of compress and decompress commands for inline transfer.
 Each item is a list that looks like this:
@@ -4274,16 +4254,24 @@ connection if a previous connection has died for some reason."
                 ;; This must be done in order to avoid our file name handler.
                 (p (let ((default-directory
                            (tramp-compat-temporary-file-directory)))
-                     (start-process
+                     (apply
+                      'start-process
                       (tramp-get-connection-name vec)
                       (tramp-get-connection-buffer vec)
-                      tramp-encoding-shell))))
+                      (if tramp-encoding-command-interactive
+                          (list tramp-encoding-shell
+                                tramp-encoding-command-interactive)
+                        (list tramp-encoding-shell))))))
+
+           ;; 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)
 
            (tramp-message
             vec 6 "%s" (mapconcat 'identity (process-command p) " "))
 
            ;; Check whether process is alive.
-           (tramp-compat-set-process-query-on-exit-flag p nil)
            (tramp-barf-if-no-shell-prompt
             p 60 "Couldn't find local shell prompt %s" tramp-encoding-shell)
 
@@ -4306,7 +4294,7 @@ connection if a previous connection has died for some reason."
                     (gw (tramp-get-file-property hop "" "gateway" nil))
                     (g-method (and gw (tramp-file-name-method gw)))
                     (g-user (and gw (tramp-file-name-user gw)))
-                    (g-host (and gw (tramp-file-name-host gw)))
+                    (g-host (and gw (tramp-file-name-real-host gw)))
                     (command login-program)
                     ;; We don't create the temporary file.  In fact,
                     ;; it is just a prefix for the ControlPath option
@@ -4323,7 +4311,7 @@ connection if a previous connection has died for some reason."
                         (tramp-compat-temporary-file-directory)))))
                     spec)
 
-               ;; Add arguments for asynchrononous processes.
+               ;; Add arguments for asynchronous processes.
                (when (and process-name async-args)
                  (setq login-args (append async-args login-args)))
 
@@ -4468,31 +4456,40 @@ DONT-SUPPRESS-ERR is non-nil, stderr won't be sent to /dev/null."
   "Run COMMAND, check exit status, throw error if exit status not okay.
 Similar to `tramp-send-command-and-check' but accepts two more arguments
 FMT and ARGS which are passed to `error'."
-  (unless (tramp-send-command-and-check vec command)
-    (apply 'tramp-error vec 'file-error fmt args)))
+  (or (tramp-send-command-and-check vec command)
+      (apply 'tramp-error vec 'file-error fmt args)))
 
-(defun tramp-send-command-and-read (vec command)
+(defun tramp-send-command-and-read (vec command &optional noerror)
   "Run COMMAND and return the output, which must be a Lisp expression.
-In case there is no valid Lisp expression, it raises an error"
-  (tramp-barf-unless-okay vec command "`%s' returns with error" command)
-  (with-current-buffer (tramp-get-connection-buffer vec)
-    ;; Read the expression.
-    (goto-char (point-min))
-    (condition-case nil
-       (prog1 (read (current-buffer))
-         ;; Error handling.
-         (when (re-search-forward "\\S-" (point-at-eol) t)
-           (error nil)))
-      (error (tramp-error
-             vec 'file-error
-             "`%s' does not return a valid Lisp expression: `%s'"
-             command (buffer-string))))))
+In case there is no valid Lisp expression and NOERROR is nil, it
+raises an error."
+  (when (if noerror
+           (tramp-send-command-and-check vec command)
+         (tramp-barf-unless-okay
+          vec command "`%s' returns with error" command))
+    (with-current-buffer (tramp-get-connection-buffer vec)
+      ;; Read the expression.
+      (goto-char (point-min))
+      (condition-case nil
+         (prog1 (read (current-buffer))
+           ;; Error handling.
+           (when (re-search-forward "\\S-" (point-at-eol) t)
+             (error nil)))
+       (error (unless noerror
+                (tramp-error
+                 vec 'file-error
+                 "`%s' does not return a valid Lisp expression: `%s'"
+                 command (buffer-string))))))))
 
 (defun tramp-convert-file-attributes (vec attr)
   "Convert file-attributes ATTR generated by perl script, stat or ls.
 Convert file mode bits to string and set virtual device number.
 Return ATTR."
   (when attr
+    ;; Remove color escape sequences from symlink.
+    (when (stringp (car attr))
+      (while (string-match tramp-color-escape-sequence-regexp (car attr))
+       (setcar attr (replace-match "" nil nil (car attr)))))
     ;; Convert last access time.
     (unless (listp (nth 4 attr))
       (setcar (nthcdr 4 attr)
@@ -4644,6 +4641,8 @@ This is used internally by `tramp-file-mode-from-int'."
   (and
    ;; It shall be an out-of-band method.
    (tramp-get-method-parameter (tramp-file-name-method 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
    ;; does not exist a remote encoding.
    (or (null tramp-copy-size-limit)
@@ -4668,8 +4667,7 @@ This is used internally by `tramp-file-mode-from-int'."
             (when elt1
               (or
                (tramp-send-command-and-read
-                vec
-                "x=`getconf PATH 2>/dev/null` && echo \\\"$x\\\" || echo nil")
+                vec "echo \\\"`getconf PATH 2>/dev/null`\\\"" 'noerror)
                ;; Default if "getconf" is not available.
                (progn
                  (tramp-message
@@ -4725,16 +4723,6 @@ This is used internally by `tramp-file-mode-from-int'."
           x))
        remote-path)))))
 
-(defun tramp-get-remote-tmpdir (vec)
-  (with-connection-property vec "tmp-directory"
-    (let ((dir (tramp-shell-quote-argument "/tmp")))
-      (if (and (tramp-send-command-and-check
-               vec (format "%s -d %s" (tramp-get-test-command vec) dir))
-              (tramp-send-command-and-check
-               vec (format "%s -w %s" (tramp-get-test-command vec) dir)))
-         dir
-       (tramp-error vec 'file-error "Directory %s not accessible" dir)))))
-
 (defun tramp-get-ls-command (vec)
   (with-connection-property vec "ls"
     (tramp-message vec 5 "Finding a suitable `ls' command")
@@ -4831,15 +4819,12 @@ This is used internally by `tramp-file-mode-from-int'."
     (let ((result (tramp-find-executable
                   vec "stat" (tramp-get-remote-path vec)))
          tmp)
-      ;; Check whether stat(1) returns usable syntax.  %s does not
+      ;; Check whether stat(1) returns usable syntax.  "%s" does not
       ;; work on older AIX systems.
       (when result
        (setq tmp
-             ;; We don't want to display an error message.
-             (tramp-compat-with-temp-message (or (current-message) "")
-               (ignore-errors
-                 (tramp-send-command-and-read
-                  vec (format "%s -c '(\"%%N\" %%s)' /" result)))))
+             (tramp-send-command-and-read
+              vec (format "%s -c '(\"%%N\" %%s)' /" result) 'noerror))
        (unless (and (listp tmp) (stringp (car tmp))
                     (string-match "^./.$" (car tmp))
                     (integerp (cadr tmp)))
@@ -4852,11 +4837,8 @@ This is used internally by `tramp-file-mode-from-int'."
     (let ((result (tramp-find-executable
                   vec "readlink" (tramp-get-remote-path vec))))
       (when (and result
-                ;; We don't want to display an error message.
-                (tramp-compat-with-temp-message (or (current-message) "")
-                  (ignore-errors
-                    (tramp-send-command-and-check
-                     vec (format "%s --canonicalize-missing /" result)))))
+                (tramp-send-command-and-check
+                 vec (format "%s --canonicalize-missing /" result)))
        result))))
 
 (defun tramp-get-remote-trash (vec)
@@ -5051,11 +5033,11 @@ function cell is returned to be applied on a buffer."
 ;;   until the last but one hop via `start-file-process'.  Apply it
 ;;   also for ftp and smb.
 ;; * WIBNI if we had a command "trampclient"?  If I was editing in
-;;   some shell with root priviledges, it would be nice if I could
+;;   some shell with root privileges, it would be nice if I could
 ;;   just call
 ;;     trampclient filename.c
 ;;   as an editor, and the _current_ shell would connect to an Emacs
-;;   server and would be used in an existing non-priviledged Emacs
+;;   server and would be used in an existing non-privileged Emacs
 ;;   session for doing the editing in question.
 ;;   That way, I need not tell Emacs my password again and be afraid
 ;;   that it makes it into core dumps or other ugly stuff (I had Emacs