Merge from emacs-23; up to 2010-06-08T03:06:47Z!dann@ics.uci.edu.
[bpt/emacs.git] / lisp / net / tramp-sh.el
index 423b4fc..ec5c46b 100644 (file)
@@ -1,7 +1,6 @@
 ;;; tramp-sh.el --- Tramp access functions for (s)sh-like connections
 
-;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-;;   2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+;; Copyright (C) 1998-2011 Free Software Foundation, Inc.
 
 ;; (copyright statements below in code to be updated with the above notice)
 
@@ -67,9 +66,9 @@ files conditionalize this setup based on the TERM environment variable."
   :group 'tramp
   :type 'string)
 
-;; ksh on OpenBSD 4.5 requires, that PS1 contains a `#' character for
+;; 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.
+;; to guarantee a proper prompt, we use "#$ " for the prompt.
 
 (defvar tramp-end-of-output
   (format
@@ -104,9 +103,9 @@ detected as prompt when being sent on echoing hosts, therefore.")
     (tramp-copy-args            (("-p" "%k")))
     (tramp-copy-keep-date       t)))
 ;;;###tramp-autoload
-(add-to-list
- 'tramp-methods
'("scp"   (tramp-login-program        "ssh")
+(add-to-list 'tramp-methods
+ '("scp"
+   (tramp-login-program        "ssh")
    (tramp-login-args           (("-l" "%u") ("-p" "%p")        ("-e" "none") ("%h")))
    (tramp-async-args           (("-q")))
    (tramp-remote-sh            "/bin/sh")
@@ -161,10 +160,11 @@ detected as prompt when being sent on echoing hosts, therefore.")
     (tramp-async-args           (("-q")))
     (tramp-remote-sh            "/bin/sh")
     (tramp-copy-program         "scp")
-    (tramp-copy-args            (("-P" "%p") ("-p" "%k") ("-q")
+    (tramp-copy-args            (("-P" "%p") ("-p" "%k") ("-q") ("-r")
                                 ("-o" "ControlPath=%t.%%r@%%h:%%p")
                                 ("-o" "ControlMaster=auto")))
     (tramp-copy-keep-date       t)
+    (tramp-copy-recursive       t)
     (tramp-gw-args              (("-o" "GlobalKnownHostsFile=/dev/null")
                                 ("-o" "UserKnownHostsFile=/dev/null")
                                 ("-o" "StrictHostKeyChecking=no")))
@@ -179,8 +179,9 @@ detected as prompt when being sent on echoing hosts, therefore.")
     (tramp-async-args           (("-q")))
     (tramp-remote-sh            "/bin/sh")
     (tramp-copy-program         "scp")
-    (tramp-copy-args            (("-p" "%k")))
+    (tramp-copy-args            (("-P" "%p") ("-p" "%k") ("-q") ("-r")))
     (tramp-copy-keep-date       t)
+    (tramp-copy-recursive       t)
     (tramp-gw-args              (("-o" "GlobalKnownHostsFile=/dev/null")
                                 ("-o" "UserKnownHostsFile=/dev/null")
                                 ("-o" "StrictHostKeyChecking=no")))
@@ -305,6 +306,12 @@ detected as prompt when being sent on echoing hosts, therefore.")
     (tramp-login-args           (("-u" "%u") ("-s") ("-H") ("-p" "Password:")))
     (tramp-remote-sh            "/bin/sh")))
 ;;;###tramp-autoload
+(add-to-list 'tramp-methods
+  '("ksu"
+    (tramp-login-program        "ksu")
+    (tramp-login-args           (("%u") ("-q")))
+    (tramp-remote-sh            "/bin/sh")))
+;;;###tramp-autoload
 (add-to-list 'tramp-methods
   '("krlogin"
     (tramp-login-program        "krlogin")
@@ -346,8 +353,10 @@ detected as prompt when being sent on echoing hosts, therefore.")
     (tramp-login-args           (("-l" "%u") ("-P" "%p") ("-ssh") ("%h")))
     (tramp-remote-sh            "/bin/sh")
     (tramp-copy-program         "pscp")
-    (tramp-copy-args            (("-P" "%p") ("-scp") ("-p" "%k")))
+    (tramp-copy-args            (("-P" "%p") ("-scp") ("-p" "%k")
+                                ("-q") ("-r")))
     (tramp-copy-keep-date       t)
+    (tramp-copy-recursive       t)
     (tramp-password-end-of-line "xy") ;see docstring for "xy"
     (tramp-default-port         22)))
 ;;;###tramp-autoload
@@ -357,8 +366,10 @@ detected as prompt when being sent on echoing hosts, therefore.")
     (tramp-login-args           (("-l" "%u") ("-P" "%p") ("-ssh") ("%h")))
     (tramp-remote-sh            "/bin/sh")
     (tramp-copy-program         "pscp")
-    (tramp-copy-args            (("-P" "%p") ("-sftp") ("-p" "%k")))
+    (tramp-copy-args            (("-P" "%p") ("-sftp") ("-p" "%k")
+                                ("-q") ("-r")))
     (tramp-copy-keep-date       t)
+    (tramp-copy-recursive       t)
     (tramp-password-end-of-line "xy"))) ;see docstring for "xy"
 ;;;###tramp-autoload
 (add-to-list 'tramp-methods
@@ -370,13 +381,23 @@ detected as prompt when being sent on echoing hosts, therefore.")
     (tramp-copy-args            (("-p" "%k")))
     (tramp-copy-keep-date       t)))
 
+;;;###tramp-autoload
 (add-to-list 'tramp-default-method-alist
             `(,tramp-local-host-regexp "\\`root\\'" "su"))
 
+;;;###tramp-autoload
 (add-to-list 'tramp-default-user-alist
-            '("\\`su\\(do\\)?\\'" nil "root"))
+            `(,(concat "\\`" (regexp-opt '("su" "sudo" "ksu")) "\\'")
+              nil "root"))
+;; Do not add "ssh" based methods, otherwise ~/.ssh/config would be ignored.
+;;;###tramp-autoload
 (add-to-list 'tramp-default-user-alist
-            `("\\`r\\(em\\)?\\(cp\\|sh\\)\\|telnet\\|plink1?\\'"
+            `(,(concat
+                "\\`"
+                (regexp-opt
+                 '("rcp" "remcp" "rsh" "telnet" "krlogin"
+                   "plink" "plink1" "pscp" "psftp" "fcp"))
+                "\\'")
               nil ,(user-login-name)))
 
 (defconst tramp-completion-function-alist-rsh
@@ -433,6 +454,7 @@ detected as prompt when being sent on echoing hosts, therefore.")
 (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)
@@ -460,7 +482,9 @@ tilde expansion, all directory names starting with `~' will be ignored.
 `Default Directories' represent the list of directories given by
 the command \"getconf PATH\".  It is recommended to use this
 entry on top of this list, because these are the default
-directories for POSIX compatible commands.
+directories for POSIX compatible commands.  On remote hosts which
+do not offer the getconf command (like cygwin), the value
+\"/bin:/usr/bin\" is used instead of.
 
 `Private Directories' are the settings of the $PATH environment,
 as given in your `~/.profile'."
@@ -485,7 +509,7 @@ entry ENVVARNAME= diables 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
-not be set here. Instead of, it should be set via `tramp-remote-path'."
+not be set here. Instead, it should be set via `tramp-remote-path'."
   :group 'tramp
   :type '(repeat string))
 
@@ -620,7 +644,7 @@ passed to `format', so percent characters need to be doubled.")
 ;; unless this spits out a complete line, including the '\n' at the
 ;; end.
 ;; The device number is returned as "-1", because there will be a virtual
-;; device number set in `tramp-handle-file-attributes'.
+;; device number set in `tramp-sh-handle-file-attributes'.
 (defconst tramp-perl-file-attributes
   "%s -e '
 @stat = lstat($ARGV[0]);
@@ -738,8 +762,7 @@ on the remote host.")
 (defconst tramp-perl-encode
   "%s -e '
 # This script contributed by Juanma Barranquero <lektu@terra.es>.
-# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
-#   Free Software Foundation, Inc.
+# Copyright (C) 2002-2011 Free Software Foundation, Inc.
 use strict;
 
 my %%trans = do {
@@ -780,8 +803,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, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
-#   Free Software Foundation, Inc.
+# Copyright (C) 2002-2011 Free Software Foundation, Inc.
 use strict;
 
 my %%trans = do {
@@ -867,62 +889,63 @@ This is used to map a mode number to a permission string.")
 ;; get-file-buffer.
 (defconst tramp-sh-file-name-handler-alist
   '((load . tramp-handle-load)
-    (make-symbolic-link . tramp-handle-make-symbolic-link)
+    (make-symbolic-link . tramp-sh-handle-make-symbolic-link)
     (file-name-as-directory . tramp-handle-file-name-as-directory)
     (file-name-directory . tramp-handle-file-name-directory)
     (file-name-nondirectory . tramp-handle-file-name-nondirectory)
-    (file-truename . tramp-handle-file-truename)
-    (file-exists-p . tramp-handle-file-exists-p)
-    (file-directory-p . tramp-handle-file-directory-p)
-    (file-executable-p . tramp-handle-file-executable-p)
-    (file-readable-p . tramp-handle-file-readable-p)
+    (file-truename . tramp-sh-handle-file-truename)
+    (file-exists-p . tramp-sh-handle-file-exists-p)
+    (file-directory-p . tramp-sh-handle-file-directory-p)
+    (file-executable-p . tramp-sh-handle-file-executable-p)
+    (file-readable-p . tramp-sh-handle-file-readable-p)
     (file-regular-p . tramp-handle-file-regular-p)
     (file-symlink-p . tramp-handle-file-symlink-p)
-    (file-writable-p . tramp-handle-file-writable-p)
-    (file-ownership-preserved-p . tramp-handle-file-ownership-preserved-p)
-    (file-newer-than-file-p . tramp-handle-file-newer-than-file-p)
-    (file-attributes . tramp-handle-file-attributes)
+    (file-writable-p . tramp-sh-handle-file-writable-p)
+    (file-ownership-preserved-p . tramp-sh-handle-file-ownership-preserved-p)
+    (file-newer-than-file-p . tramp-sh-handle-file-newer-than-file-p)
+    (file-attributes . tramp-sh-handle-file-attributes)
     (file-modes . tramp-handle-file-modes)
     (directory-files . tramp-handle-directory-files)
-    (directory-files-and-attributes . tramp-handle-directory-files-and-attributes)
-    (file-name-all-completions . tramp-handle-file-name-all-completions)
+    (directory-files-and-attributes
+     . tramp-sh-handle-directory-files-and-attributes)
+    (file-name-all-completions . tramp-sh-handle-file-name-all-completions)
     (file-name-completion . tramp-handle-file-name-completion)
-    (add-name-to-file . tramp-handle-add-name-to-file)
-    (copy-file . tramp-handle-copy-file)
-    (copy-directory . tramp-handle-copy-directory)
-    (rename-file . tramp-handle-rename-file)
-    (set-file-modes . tramp-handle-set-file-modes)
-    (set-file-times . tramp-handle-set-file-times)
-    (make-directory . tramp-handle-make-directory)
-    (delete-directory . tramp-handle-delete-directory)
-    (delete-file . tramp-handle-delete-file)
+    (add-name-to-file . tramp-sh-handle-add-name-to-file)
+    (copy-file . tramp-sh-handle-copy-file)
+    (copy-directory . tramp-sh-handle-copy-directory)
+    (rename-file . tramp-sh-handle-rename-file)
+    (set-file-modes . tramp-sh-handle-set-file-modes)
+    (set-file-times . tramp-sh-handle-set-file-times)
+    (make-directory . tramp-sh-handle-make-directory)
+    (delete-directory . tramp-sh-handle-delete-directory)
+    (delete-file . tramp-sh-handle-delete-file)
     (directory-file-name . tramp-handle-directory-file-name)
     ;; `executable-find' is not official yet.
-    (executable-find . tramp-handle-executable-find)
-    (start-file-process . tramp-handle-start-file-process)
-    (process-file . tramp-handle-process-file)
-    (shell-command . tramp-handle-shell-command)
-    (insert-directory . tramp-handle-insert-directory)
-    (expand-file-name . tramp-handle-expand-file-name)
+    (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)
+    (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)
-    (file-local-copy . tramp-handle-file-local-copy)
+    (file-local-copy . tramp-sh-handle-file-local-copy)
     (file-remote-p . tramp-handle-file-remote-p)
     (insert-file-contents . tramp-handle-insert-file-contents)
     (insert-file-contents-literally
-     . tramp-handle-insert-file-contents-literally)
-    (write-region . tramp-handle-write-region)
+     . tramp-sh-handle-insert-file-contents-literally)
+    (write-region . tramp-sh-handle-write-region)
     (find-backup-file-name . tramp-handle-find-backup-file-name)
-    (make-auto-save-file-name . tramp-handle-make-auto-save-file-name)
+    (make-auto-save-file-name . tramp-sh-handle-make-auto-save-file-name)
     (unhandled-file-name-directory . tramp-handle-unhandled-file-name-directory)
-    (dired-compress-file . tramp-handle-dired-compress-file)
+    (dired-compress-file . tramp-sh-handle-dired-compress-file)
     (dired-recursive-delete-directory
-     . tramp-handle-dired-recursive-delete-directory)
+     . tramp-sh-handle-dired-recursive-delete-directory)
     (dired-uncache . tramp-handle-dired-uncache)
-    (set-visited-file-modtime . tramp-handle-set-visited-file-modtime)
-    (verify-visited-file-modtime . tramp-handle-verify-visited-file-modtime)
-    (file-selinux-context . tramp-handle-file-selinux-context)
-    (set-file-selinux-context . tramp-handle-set-file-selinux-context)
-    (vc-registered . tramp-handle-vc-registered))
+    (set-visited-file-modtime . tramp-sh-handle-set-visited-file-modtime)
+    (verify-visited-file-modtime . tramp-sh-handle-verify-visited-file-modtime)
+    (file-selinux-context . tramp-sh-handle-file-selinux-context)
+    (set-file-selinux-context . tramp-sh-handle-set-file-selinux-context)
+    (vc-registered . tramp-sh-handle-vc-registered))
   "Alist of handler functions.
 Operations not mentioned here will be handled by the normal Emacs functions.")
 
@@ -933,7 +956,7 @@ Operations not mentioned here will be handled by the normal Emacs functions.")
 
 ;;; File Name Handler Functions:
 
-(defun tramp-handle-make-symbolic-link
+(defun tramp-sh-handle-make-symbolic-link
   (filename linkname &optional ok-if-already-exists)
   "Like `make-symbolic-link' for Tramp files.
 If LINKNAME is a non-Tramp file, it is used verbatim as the target of
@@ -988,71 +1011,7 @@ target of the symlink differ."
        (tramp-shell-quote-argument l-localname))
        t))))
 
-(defun tramp-handle-load (file &optional noerror nomessage nosuffix must-suffix)
-  "Like `load' for Tramp files."
-  (with-parsed-tramp-file-name (expand-file-name file) nil
-    (unless nosuffix
-      (cond ((file-exists-p (concat file ".elc"))
-            (setq file (concat file ".elc")))
-           ((file-exists-p (concat file ".el"))
-            (setq file (concat file ".el")))))
-    (when must-suffix
-      ;; The first condition is always true for absolute file names.
-      ;; Included for safety's sake.
-      (unless (or (file-name-directory file)
-                 (string-match "\\.elc?\\'" file))
-       (tramp-error
-        v 'file-error
-        "File `%s' does not include a `.el' or `.elc' suffix" file)))
-    (unless noerror
-      (when (not (file-exists-p file))
-       (tramp-error v 'file-error "Cannot load nonexistent file `%s'" file)))
-    (if (not (file-exists-p file))
-       nil
-      (let ((tramp-message-show-message (not nomessage)))
-       (with-progress-reporter v 0 (format "Loading %s" file)
-         (let ((local-copy (file-local-copy file)))
-           ;; MUST-SUFFIX doesn't exist on XEmacs, so let it default to nil.
-           (unwind-protect
-               (load local-copy noerror t t)
-             (delete-file local-copy)))))
-      t)))
-
-;; Localname manipulation functions that grok Tramp localnames...
-(defun tramp-handle-file-name-as-directory (file)
-  "Like `file-name-as-directory' but aware of Tramp files."
-  ;; `file-name-as-directory' would be sufficient except localname is
-  ;; the empty string.
-  (let ((v (tramp-dissect-file-name file t)))
-    ;; Run the command on the localname portion only.
-    (tramp-make-tramp-file-name
-     (tramp-file-name-method v)
-     (tramp-file-name-user v)
-     (tramp-file-name-host v)
-     (tramp-run-real-handler
-      'file-name-as-directory (list (or (tramp-file-name-localname v) ""))))))
-
-(defun tramp-handle-file-name-directory (file)
-  "Like `file-name-directory' but aware of Tramp files."
-  ;; Everything except the last filename thing is the directory.  We
-  ;; cannot apply `with-parsed-tramp-file-name', because this expands
-  ;; the remote file name parts.  This is a problem when we are in
-  ;; file name completion.
-  (let ((v (tramp-dissect-file-name file t)))
-    ;; Run the command on the localname portion only.
-    (tramp-make-tramp-file-name
-     (tramp-file-name-method v)
-     (tramp-file-name-user v)
-     (tramp-file-name-host v)
-     (tramp-run-real-handler
-      'file-name-directory (list (or (tramp-file-name-localname v) ""))))))
-
-(defun tramp-handle-file-name-nondirectory (file)
-  "Like `file-name-nondirectory' but aware of Tramp files."
-  (with-parsed-tramp-file-name file nil
-    (tramp-run-real-handler 'file-name-nondirectory (list localname))))
-
-(defun tramp-handle-file-truename (filename &optional counter prev-dirs)
+(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"
@@ -1158,7 +1117,7 @@ target of the symlink differ."
 
 ;; Basic functions.
 
-(defun tramp-handle-file-exists-p (filename)
+(defun tramp-sh-handle-file-exists-p (filename)
   "Like `file-exists-p' for Tramp files."
   (with-parsed-tramp-file-name filename nil
     (with-file-property v localname "file-exists-p"
@@ -1176,7 +1135,7 @@ target of the symlink differ."
 ;; CCC: This should check for an error condition and signal failure
 ;;      when something goes wrong.
 ;; Daniel Pittman <daniel@danann.net>
-(defun tramp-handle-file-attributes (filename &optional id-format)
+(defun tramp-sh-handle-file-attributes (filename &optional id-format)
   "Like `file-attributes' for Tramp files."
   (unless id-format (setq id-format 'integer))
   ;; Don't modify `last-coding-system-used' by accident.
@@ -1252,8 +1211,7 @@ target of the symlink differ."
         ;; if symlink, find out file name pointed to
         (when symlinkp
           (search-forward "-> ")
-          (setq res-symlink-target
-                (buffer-substring (point) (tramp-compat-line-end-position))))
+          (setq res-symlink-target (buffer-substring (point) (point-at-eol))))
         ;; return data gathered
         (list
          ;; 0. t for directory, string (name linked to) for symbolic
@@ -1304,7 +1262,7 @@ target of the symlink differ."
    (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 %%X.0 %%Y.0 %%Z.0 %%s.0 \"%%A\" t %%i.0 -1)' %s || echo nil)"
+    "( (%s %s || %s -h %s) && %s -c '((\"%%N\") %%h %s %s %%Xe0 %%Ye0 %%Ze0 %%se0 \"%%A\" t %%ie0 -1)' %s || echo nil)"
     (tramp-get-file-exists-command vec)
     (tramp-shell-quote-argument localname)
     (tramp-get-test-command vec)
@@ -1314,7 +1272,7 @@ target of the symlink differ."
     (if (eq id-format 'integer) "%g" "\"%G\"")
     (tramp-shell-quote-argument localname))))
 
-(defun tramp-handle-set-visited-file-modtime (&optional time-list)
+(defun tramp-sh-handle-set-visited-file-modtime (&optional time-list)
   "Like `set-visited-file-modtime' for Tramp files."
   (unless (buffer-file-name)
     (error "Can't set-visited-file-modtime: buffer `%s' not visiting a file"
@@ -1348,8 +1306,8 @@ target of the symlink differ."
          nil)))))
 
 ;; This function makes the same assumption as
-;; `tramp-handle-set-visited-file-modtime'.
-(defun tramp-handle-verify-visited-file-modtime (buf)
+;; `tramp-sh-handle-set-visited-file-modtime'.
+(defun tramp-sh-handle-verify-visited-file-modtime (buf)
   "Like `verify-visited-file-modtime' for Tramp files.
 At the time `verify-visited-file-modtime' calls this function, we
 already know that the buffer is visiting a file and that
@@ -1366,8 +1324,8 @@ of."
              (not (tramp-file-name-handler 'file-remote-p f nil 'connected)))
          t
        (with-parsed-tramp-file-name f nil
-         (tramp-flush-file-property v localname)
-         (let* ((attr (file-attributes f))
+         (let* ((remote-file-name-inhibit-cache t)
+                (attr (file-attributes f))
                 (modtime (nth 5 attr))
                 (mt (visited-file-modtime)))
 
@@ -1401,7 +1359,7 @@ of."
             ;; only if that agrees with the buffer's record.
             (t (equal mt '(-1 65535))))))))))
 
-(defun tramp-handle-set-file-modes (filename mode)
+(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 localname)
@@ -1413,7 +1371,7 @@ of."
             (tramp-shell-quote-argument localname))
      "Error while changing file's mode %s" filename)))
 
-(defun tramp-handle-set-file-times (filename &optional time)
+(defun tramp-sh-handle-set-file-times (filename &optional time)
   "Like `set-file-times' for Tramp files."
   (if (file-remote-p filename)
       (with-parsed-tramp-file-name filename nil
@@ -1486,7 +1444,7 @@ and gid of the corresponding user is taken.  Both parameters must be integers."
             vec (format "echo \\\"`%S`\\\"" result))
            "Enforcing")))))
 
-(defun tramp-handle-file-selinux-context (filename)
+(defun tramp-sh-handle-file-selinux-context (filename)
   "Like `file-selinux-context' for Tramp files."
   (with-parsed-tramp-file-name filename nil
     (with-file-property v localname "file-selinux-context"
@@ -1501,13 +1459,13 @@ and gid of the corresponding user is taken.  Both parameters must be integers."
                       (tramp-shell-quote-argument localname))))
          (with-current-buffer (tramp-get-connection-buffer v)
            (goto-char (point-min))
-           (when (re-search-forward regexp (tramp-compat-line-end-position) t)
+           (when (re-search-forward regexp (point-at-eol) t)
              (setq context (list (match-string 1) (match-string 2)
                                  (match-string 3) (match-string 4))))))
        ;; Return the context.
        context))))
 
-(defun tramp-handle-set-file-selinux-context (filename context)
+(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)
@@ -1530,7 +1488,7 @@ and gid of the corresponding user is taken.  Both parameters must be integers."
 
 ;; Simple functions using the `test' command.
 
-(defun tramp-handle-file-executable-p (filename)
+(defun tramp-sh-handle-file-executable-p (filename)
   "Like `file-executable-p' for Tramp files."
   (with-parsed-tramp-file-name filename nil
     (with-file-property v localname "file-executable-p"
@@ -1539,7 +1497,7 @@ and gid of the corresponding user is taken.  Both parameters must be integers."
       (or (tramp-check-cached-permissions v ?x)
          (tramp-run-test "-x" filename)))))
 
-(defun tramp-handle-file-readable-p (filename)
+(defun tramp-sh-handle-file-readable-p (filename)
   "Like `file-readable-p' for Tramp files."
   (with-parsed-tramp-file-name filename nil
     (with-file-property v localname "file-readable-p"
@@ -1553,7 +1511,7 @@ and gid of the corresponding user is taken.  Both parameters must be integers."
 ;; expansion will also provide a `test' command which groks `-nt' (for
 ;; newer than).  If this breaks, tell me about it and I'll try to do
 ;; something smarter about it.
-(defun tramp-handle-file-newer-than-file-p (file1 file2)
+(defun tramp-sh-handle-file-newer-than-file-p (file1 file2)
   "Like `file-newer-than-file-p' for Tramp files."
   (cond ((not (file-exists-p file1))
          nil)
@@ -1588,13 +1546,7 @@ and gid of the corresponding user is taken.  Both parameters must be integers."
 
 ;; Functions implemented using the basic functions above.
 
-(defun tramp-handle-file-modes (filename)
-  "Like `file-modes' for Tramp files."
-  (let ((truename (or (file-truename filename) filename)))
-    (when (file-exists-p truename)
-      (tramp-mode-string-to-int (nth 8 (file-attributes truename))))))
-
-(defun tramp-handle-file-directory-p (filename)
+(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
@@ -1608,23 +1560,7 @@ and gid of the corresponding user is taken.  Both parameters must be integers."
     (with-file-property v localname "file-directory-p"
       (tramp-run-test "-d" filename))))
 
-(defun tramp-handle-file-regular-p (filename)
-  "Like `file-regular-p' for Tramp files."
-  (and (file-exists-p filename)
-       (eq ?- (aref (nth 8 (file-attributes filename)) 0))))
-
-(defun tramp-handle-file-symlink-p (filename)
-  "Like `file-symlink-p' for Tramp files."
-  (with-parsed-tramp-file-name filename nil
-    (let ((x (car (file-attributes filename))))
-      (when (stringp x)
-       ;; When Tramp is running on VMS, then `file-name-absolute-p'
-       ;; might do weird things.
-       (if (file-name-absolute-p x)
-           (tramp-make-tramp-file-name method user host x)
-         x)))))
-
-(defun tramp-handle-file-writable-p (filename)
+(defun tramp-sh-handle-file-writable-p (filename)
   "Like `file-writable-p' for Tramp files."
   (with-parsed-tramp-file-name filename nil
     (with-file-property v localname "file-writable-p"
@@ -1637,7 +1573,7 @@ and gid of the corresponding user is taken.  Both parameters must be integers."
        (and (tramp-run-test "-d" (file-name-directory filename))
             (tramp-run-test "-w" (file-name-directory filename)))))))
 
-(defun tramp-handle-file-ownership-preserved-p (filename)
+(defun tramp-sh-handle-file-ownership-preserved-p (filename)
   "Like `file-ownership-preserved-p' for Tramp files."
   (with-parsed-tramp-file-name filename nil
     (with-file-property v localname "file-ownership-preserved-p"
@@ -1647,45 +1583,9 @@ and gid of the corresponding user is taken.  Both parameters must be integers."
        (or (null attributes)
            (= (nth 2 attributes) (tramp-get-remote-uid v 'integer)))))))
 
-;; Other file name ops.
-
-(defun tramp-handle-directory-file-name (directory)
-  "Like `directory-file-name' for Tramp files."
-  ;; If localname component of filename is "/", leave it unchanged.
-  ;; Otherwise, remove any trailing slash from localname component.
-  ;; Method, host, etc, are unchanged.  Does it make sense to try
-  ;; to avoid parsing the filename?
-  (with-parsed-tramp-file-name directory nil
-    (if (and (not (zerop (length localname)))
-            (eq (aref localname (1- (length localname))) ?/)
-            (not (string= localname "/")))
-       (substring directory 0 -1)
-      directory)))
-
 ;; Directory listings.
 
-(defun tramp-handle-directory-files
-  (directory &optional full match nosort files-only)
-  "Like `directory-files' for Tramp files."
-  ;; FILES-ONLY is valid for XEmacs only.
-  (when (file-directory-p directory)
-    (setq directory (file-name-as-directory (expand-file-name directory)))
-    (let ((temp (nreverse (file-name-all-completions "" directory)))
-         result item)
-
-      (while temp
-       (setq item (directory-file-name (pop temp)))
-       (when (and (or (null match) (string-match match item))
-                  (or (null files-only)
-                      ;; Files only.
-                      (and (equal files-only t) (file-regular-p item))
-                      ;; Directories only.
-                      (file-directory-p item)))
-         (push (if full (concat directory item) item)
-               result)))
-      (if nosort result (sort result 'string<)))))
-
-(defun tramp-handle-directory-files-and-attributes
+(defun tramp-sh-handle-directory-files-and-attributes
   (directory &optional full match nosort id-format)
   "Like `directory-files-and-attributes' for Tramp files."
   (unless id-format (setq id-format 'integer))
@@ -1750,7 +1650,7 @@ and gid of the corresponding user is taken.  Both parameters must be integers."
      ;; but it does not work on all remote systems.  Therefore, we
      ;; quote the filenames via sed.
      "cd %s; echo \"(\"; (%s -a | sed -e s/\\$/\\\"/g -e s/^/\\\"/g | xargs "
-     "%s -c '(\"%%n\" (\"%%N\") %%h %s %s %%X.0 %%Y.0 %%Z.0 %%s.0 \"%%A\" t %%i.0 -1)'); "
+     "%s -c '(\"%%n\" (\"%%N\") %%h %s %s %%Xe0 %%Ye0 %%Ze0 %%se0 \"%%A\" t %%ie0 -1)'); "
      "echo \")\"")
     (tramp-shell-quote-argument localname)
     (tramp-get-ls-command vec)
@@ -1760,7 +1660,7 @@ and gid of the corresponding user is taken.  Both parameters must be integers."
 
 ;; This function should return "foo/" for directories and "bar" for
 ;; files.
-(defun tramp-handle-file-name-all-completions (filename directory)
+(defun tramp-sh-handle-file-name-all-completions (filename directory)
   "Like `file-name-all-completions' for Tramp files."
   (unless (save-match-data (string-match "/" filename))
     (with-parsed-tramp-file-name (expand-file-name directory) nil
@@ -1770,46 +1670,39 @@ and gid of the corresponding user is taken.  Both parameters must be integers."
        (mapcar
        'list
         (or
-         ;; Try cache first
-         (and
-          ;; Ignore if expired
-          (or (not (integerp tramp-completion-reread-directory-timeout))
-              (<= (tramp-time-diff
-                   (current-time)
-                   (tramp-get-file-property
-                    v localname "last-completion" '(0 0 0)))
-                  tramp-completion-reread-directory-timeout))
-
-          ;; Try cache entries for filename, filename with last
-          ;; character removed, filename with last two characters
-          ;; removed, ..., and finally the empty string - all
-          ;; concatenated to the local directory name
-
-          ;; This is inefficient for very long filenames, pity
-          ;; `reduce' is not available...
-          (car
-           (apply
-            'append
-            (mapcar
-             (lambda (x)
-               (let ((cache-hit
-                      (tramp-get-file-property
-                       v
-                       (concat localname (substring filename 0 x))
-                       "file-name-all-completions"
-                       nil)))
-                 (when cache-hit (list cache-hit))))
-             (tramp-compat-number-sequence (length filename) 0 -1)))))
+        ;; Try cache entries for filename, filename with last
+        ;; character removed, filename with last two characters
+        ;; removed, ..., and finally the empty string - all
+        ;; concatenated to the local directory name.
+         (let ((remote-file-name-inhibit-cache
+               (or remote-file-name-inhibit-cache
+                   tramp-completion-reread-directory-timeout)))
+
+          ;; This is inefficient for very long filenames, pity
+          ;; `reduce' is not available...
+          (car
+           (apply
+            'append
+            (mapcar
+             (lambda (x)
+               (let ((cache-hit
+                      (tramp-get-file-property
+                       v
+                       (concat localname (substring filename 0 x))
+                       "file-name-all-completions"
+                       nil)))
+                 (when cache-hit (list cache-hit))))
+             (tramp-compat-number-sequence (length filename) 0 -1)))))
 
          ;; Cache expired or no matching cache entry found so we need
-         ;; to perform a remote operation
+         ;; to perform a remote operation.
          (let (result)
            ;; Get a list of directories and files, including reliably
            ;; tagging the directories with a trailing '/'.  Because I
            ;; rock.  --daniel@danann.net
 
            ;; Changed to perform `cd' in the same remote op and only
-           ;; get entries starting with `filename'. Capture any `cd'
+           ;; get entries starting with `filename'.  Capture any `cd'
            ;; error messages.  Ensure any `cd' and `echo' aliases are
            ;; ignored.
            (tramp-send-command
@@ -1873,9 +1766,8 @@ and gid of the corresponding user is taken.  Both parameters must be integers."
                    (forward-line -1)
                    (tramp-error
                     v 'file-error
-                    "tramp-handle-file-name-all-completions: %s"
-                    (buffer-substring
-                     (point) (tramp-compat-line-end-position))))
+                    "tramp-sh-handle-file-name-all-completions: %s"
+                    (buffer-substring (point) (point-at-eol))))
                ;; For peace of mind, if buffer doesn't end in `fail'
                ;; then it should end in `ok'.  If neither are in the
                ;; buffer something went seriously wrong on the remote
@@ -1884,13 +1776,11 @@ and gid of the corresponding user is taken.  Both parameters must be integers."
                  (tramp-error
                   v 'file-error
                   "\
-tramp-handle-file-name-all-completions: internal error accessing `%s': `%s'"
+tramp-sh-handle-file-name-all-completions: internal error accessing `%s': `%s'"
                   (tramp-shell-quote-argument localname) (buffer-string))))
 
              (while (zerop (forward-line -1))
-               (push (buffer-substring
-                      (point) (tramp-compat-line-end-position))
-                     result)))
+               (push (buffer-substring (point) (point-at-eol)) result)))
 
            ;; Because the remote op went through OK we know the
            ;; directory we `cd'-ed to exists
@@ -1904,31 +1794,15 @@ tramp-handle-file-name-all-completions: internal error accessing `%s': `%s'"
                    v (concat localname entry) "file-exists-p" t))
                 result)
 
-           (tramp-set-file-property
-            v localname "last-completion" (current-time))
-
            ;; Store result in the cache
            (tramp-set-file-property
             v (concat localname filename)
             "file-name-all-completions"
             result))))))))
 
-(defun tramp-handle-file-name-completion
-  (filename directory &optional predicate)
-  "Like `file-name-completion' for Tramp files."
-  (unless (tramp-tramp-file-p directory)
-    (error
-     "tramp-handle-file-name-completion invoked on non-tramp directory `%s'"
-     directory))
-  (try-completion
-   filename
-   (mapcar 'list (file-name-all-completions filename directory))
-   (when predicate
-     (lambda (x) (funcall predicate (expand-file-name (car x) directory))))))
-
 ;; cp, mv and ln
 
-(defun tramp-handle-add-name-to-file
+(defun tramp-sh-handle-add-name-to-file
   (filename newname &optional ok-if-already-exists)
   "Like `add-name-to-file' for Tramp files."
   (unless (tramp-equal-remote filename newname)
@@ -1960,7 +1834,7 @@ tramp-handle-file-name-all-completions: internal error accessing `%s': `%s'"
         "error with add-name-to-file, see buffer `%s' for details"
         (buffer-name))))))
 
-(defun tramp-handle-copy-file
+(defun tramp-sh-handle-copy-file
   (filename newname &optional ok-if-already-exists keep-date
            preserve-uid-gid preserve-selinux-context)
   "Like `copy-file' for Tramp files."
@@ -1987,7 +1861,8 @@ tramp-handle-file-name-all-completions: internal error accessing `%s': `%s'"
     (tramp-run-real-handler
      'copy-file (list filename newname ok-if-already-exists keep-date)))))
 
-(defun tramp-handle-copy-directory (dirname newname &optional keep-date parents)
+(defun tramp-sh-handle-copy-directory
+  (dirname newname &optional keep-date parents)
   "Like `copy-directory' for Tramp files."
   (let ((t1 (tramp-tramp-file-p dirname))
        (t2 (tramp-tramp-file-p newname)))
@@ -2023,7 +1898,7 @@ tramp-handle-file-name-all-completions: internal error accessing `%s': `%s'"
          (tramp-flush-file-property v (file-name-directory localname))
          (tramp-flush-file-property v localname))))))
 
-(defun tramp-handle-rename-file
+(defun tramp-sh-handle-rename-file
   (filename newname &optional ok-if-already-exists)
   "Like `rename-file' for Tramp files."
   ;; Check if both files are local -- invoke normal rename-file.
@@ -2051,9 +1926,10 @@ as FILENAME.  PRESERVE-UID-GID, when non-nil, instructs to keep
 the uid and gid if both files are on the same host.
 PRESERVE-SELINUX-CONTEXT activates selinux commands.
 
-This function is invoked by `tramp-handle-copy-file' and
-`tramp-handle-rename-file'.  It is an error if OP is neither of `copy'
-and `rename'.  FILENAME and NEWNAME must be absolute file names."
+This function is invoked by `tramp-sh-handle-copy-file' and
+`tramp-sh-handle-rename-file'.  It is an error if OP is neither
+of `copy' and `rename'.  FILENAME and NEWNAME must be absolute
+file names."
   (unless (memq op '(copy rename))
     (error "Unknown operation `%s', must be `copy' or `rename'" op))
   (let ((t1 (tramp-tramp-file-p filename))
@@ -2088,7 +1964,7 @@ and `rename'.  FILENAME and NEWNAME must be absolute file names."
 
               ;; Try out-of-band operation.
               ((tramp-method-out-of-band-p
-                v1 (nth 7 (file-attributes filename)))
+                v1 (nth 7 (file-attributes (file-truename filename))))
                (tramp-do-copy-or-rename-file-out-of-band
                 op filename newname keep-date))
 
@@ -2116,7 +1992,8 @@ and `rename'.  FILENAME and NEWNAME must be absolute file names."
 
           ;; If the Tramp file has an out-of-band method, the
           ;; corresponding copy-program can be invoked.
-          ((tramp-method-out-of-band-p v (nth 7 (file-attributes filename)))
+          ((tramp-method-out-of-band-p
+            v (nth 7 (file-attributes (file-truename filename))))
            (tramp-do-copy-or-rename-file-out-of-band
             op filename newname keep-date))
 
@@ -2312,29 +2189,27 @@ the uid and gid from FILENAME."
                       (list tmpfile localname2 ok-if-already-exists)))))
 
                ;; Save exit.
-               (condition-case nil
-                   (delete-file tmpfile)
-                 (error)))))))))
+               (ignore-errors (delete-file tmpfile)))))))))
 
       ;; Set the time and mode. Mask possible errors.
-      (condition-case nil
+      (ignore-errors
          (when keep-date
            (set-file-times newname file-times)
-           (set-file-modes newname file-modes))
-       (error)))))
+           (set-file-modes newname file-modes))))))
 
 (defun tramp-do-copy-or-rename-file-out-of-band (op filename newname keep-date)
   "Invoke rcp program to copy.
 The method used must be an out-of-band method."
-  (let ((t1 (tramp-tramp-file-p filename))
-       (t2 (tramp-tramp-file-p newname))
-       copy-program copy-args copy-env copy-keep-date port spec
-       source target)
+  (let* ((t1 (tramp-tramp-file-p filename))
+        (t2 (tramp-tramp-file-p newname))
+        (orig-vec (tramp-dissect-file-name (if t1 filename newname)))
+        copy-program copy-args copy-env copy-keep-date port spec
+        source target)
 
     (with-parsed-tramp-file-name (if t1 filename newname) nil
       (if (and t1 t2)
 
-         ;; Both are Tramp files.  We shall optimize it, when the
+         ;; Both are Tramp files.  We shall optimize it when the
          ;; methods for filename and newname are the same.
          (let* ((dir-flag (file-directory-p filename))
                 (tmpfile (tramp-compat-make-temp-file localname dir-flag)))
@@ -2349,12 +2224,17 @@ The method used must be an out-of-band method."
                  (tramp-do-copy-or-rename-file-out-of-band
                   'rename tmpfile newname keep-date))
              ;; Save exit.
-             (condition-case nil
-                 (if dir-flag
-                     (tramp-compat-delete-directory
-                      (expand-file-name ".." tmpfile) 'recursive)
-                   (delete-file tmpfile))
-               (error))))
+             (ignore-errors
+               (if dir-flag
+                   (tramp-compat-delete-directory
+                    (expand-file-name ".." tmpfile) 'recursive)
+                 (delete-file tmpfile)))))
+
+       ;; Set variables for computing the prompt for reading
+       ;; 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))
 
        ;; Expand hops.  Might be necessary for gateway methods.
        (setq v (car (tramp-compute-multi-hops v)))
@@ -2371,11 +2251,15 @@ The method used must be an out-of-band method."
                        'identity)
                      (if t2 (tramp-make-copy-program-file-name v) newname)))
 
-       ;; Check for port number.  Until now, there's no need for handling
-       ;; like method, user, host.
-       (setq host (tramp-file-name-real-host v)
-             port (tramp-file-name-port v)
-             port (or (and port (number-to-string port)) ""))
+       ;; Check for host and port number.  We cannot use
+       ;; `tramp-file-name-port', because this returns also
+       ;; `tramp-default-port', which might clash with settings in
+       ;; "~/.ssh/config".
+       (setq host (tramp-file-name-host v)
+             port "")
+       (when (string-match tramp-host-with-port-regexp host)
+         (setq host (string-to-number (match-string 1 host))
+               port (string-to-number (match-string 2 host))))
 
        ;; Compose copy command.
        (setq spec (format-spec-make
@@ -2388,16 +2272,20 @@ The method used must be an out-of-band method."
              copy-keep-date (tramp-get-method-parameter
                              method 'tramp-copy-keep-date)
              copy-args
-             (delq
-              nil
-              (mapcar
-               (lambda (x)
-                 (setq
-                  x
-                  ;; " " is indication for keep-date argument.
-                  (delete " " (mapcar (lambda (y) (format-spec y spec)) x)))
-                 (unless (member "" x) (mapconcat 'identity x " ")))
-               (tramp-get-method-parameter method 'tramp-copy-args)))
+             (delete
+              ;; " " has either been a replacement of "%k" (when
+              ;; keep-date argument is non-nil), or a replacement
+              ;; for the whole keep-date sublist.
+              " "
+              (dolist
+                  (x
+                   (tramp-get-method-parameter method 'tramp-copy-args)
+                   copy-args)
+                (setq copy-args
+                      (append
+                       copy-args
+                       (let ((y (mapcar (lambda (z) (format-spec z spec)) x)))
+                         (if (member "" y) '(" ") y))))))
              copy-env
              (delq
               nil
@@ -2415,14 +2303,8 @@ The method used must be an out-of-band method."
          (tramp-error
           v 'file-error "Cannot find copy program: %s" copy-program))
 
-       ;; Set variables for computing the prompt for reading
-       ;; 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))
-
-       (unwind-protect
-           (with-temp-buffer
+       (with-temp-buffer
+         (unwind-protect
              ;; The default directory must be remote.
              (let ((default-directory
                      (file-name-directory (if t1 filename newname)))
@@ -2433,7 +2315,8 @@ The method used must be an out-of-band method."
                (tramp-set-connection-property
                 v "process-buffer" (current-buffer))
                (while copy-env
-                 (tramp-message v 5 "%s=\"%s\"" (car copy-env) (cadr copy-env))
+                 (tramp-message
+                  orig-vec 5 "%s=\"%s\"" (car copy-env) (cadr copy-env))
                  (setenv (pop copy-env) (pop copy-env)))
 
                ;; Use an asynchronous process.  By this, password can
@@ -2444,20 +2327,20 @@ The method used must be an out-of-band method."
                (let ((p (let ((default-directory
                                 (tramp-compat-temporary-file-directory)))
                           (apply 'start-process
-                                 (tramp-get-connection-property
-                                  v "process-name" nil)
-                                 (tramp-get-connection-property
-                                  v "process-buffer" nil)
+                                 (tramp-get-connection-name v)
+                                 (tramp-get-connection-buffer v)
                                  copy-program
                                  (append copy-args (list source target))))))
                  (tramp-message
-                  v 6 "%s" (mapconcat 'identity (process-command p) " "))
-                 (tramp-set-process-query-on-exit-flag p nil)
-                 (tramp-process-actions p v tramp-actions-copy-out-of-band))))
+                  orig-vec 6 "%s"
+                  (mapconcat 'identity (process-command p) " "))
+                 (tramp-compat-set-process-query-on-exit-flag p nil)
+                 (tramp-process-actions p v tramp-actions-copy-out-of-band)))
 
-         ;; Reset the transfer process properties.
-         (tramp-set-connection-property v "process-name" nil)
-         (tramp-set-connection-property v "process-buffer" nil))
+           ;; Reset the transfer process properties.
+           (tramp-message orig-vec 6 "%s" (buffer-string))
+           (tramp-set-connection-property v "process-name" nil)
+           (tramp-set-connection-property v "process-buffer" nil)))
 
        ;; Handle KEEP-DATE argument.
        (when (and keep-date (not copy-keep-date))
@@ -2474,7 +2357,7 @@ The method used must be an out-of-band method."
            (delete-file filename)
          (tramp-compat-delete-directory filename 'recursive))))))
 
-(defun tramp-handle-make-directory (dir &optional parents)
+(defun tramp-sh-handle-make-directory (dir &optional parents)
   "Like `make-directory' for Tramp files."
   (setq dir (expand-file-name dir))
   (with-parsed-tramp-file-name dir nil
@@ -2486,7 +2369,7 @@ The method used must be an out-of-band method."
                 (tramp-shell-quote-argument localname))
        "Couldn't make directory %s" dir))))
 
-(defun tramp-handle-delete-directory (directory &optional recursive)
+(defun tramp-sh-handle-delete-directory (directory &optional recursive)
   "Like `delete-directory' for Tramp files."
   (setq directory (expand-file-name directory))
   (with-parsed-tramp-file-name directory nil
@@ -2498,7 +2381,7 @@ The method used must be an out-of-band method."
               (tramp-shell-quote-argument localname))
      "Couldn't delete %s" directory)))
 
-(defun tramp-handle-delete-file (filename &optional trash)
+(defun tramp-sh-handle-delete-file (filename &optional trash)
   "Like `delete-file' for Tramp files."
   (setq filename (expand-file-name filename))
   (with-parsed-tramp-file-name filename nil
@@ -2514,7 +2397,7 @@ The method used must be an out-of-band method."
 
 ;; CCC: This does not seem to be enough. Something dies when
 ;;      we try and delete two directories under Tramp :/
-(defun tramp-handle-dired-recursive-delete-directory (filename)
+(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
@@ -2526,7 +2409,7 @@ This is like `dired-recursive-delete-directory' for Tramp files."
     (tramp-send-command
      v
      (format "rm -rf %s" (tramp-shell-quote-argument localname))
-     ;; Don't read the output, do it explicitely.
+     ;; 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.
@@ -2538,7 +2421,7 @@ This is like `dired-recursive-delete-directory' for Tramp files."
         (tramp-error
          v 'file-error "Failed to recursively delete %s" filename))))
 
-(defun tramp-handle-dired-compress-file (file &rest ok-flag)
+(defun tramp-sh-handle-dired-compress-file (file &rest ok-flag)
   "Like `dired-compress-file' for Tramp files."
   ;; OK-FLAG is valid for XEmacs only, but not implemented.
   ;; Code stolen mainly from dired-aux.el.
@@ -2592,14 +2475,7 @@ This is like `dired-recursive-delete-directory' for Tramp files."
                          (concat file ".z"))
                         (t nil))))))))))
 
-(defun tramp-handle-dired-uncache (dir &optional dir-p)
-  "Like `dired-uncache' for Tramp files."
-  ;; DIR-P is valid for XEmacs only.
-  (with-parsed-tramp-file-name
-      (if (or dir-p (file-directory-p dir)) dir (file-name-directory dir)) nil
-    (tramp-flush-directory-property v localname)))
-
-(defun tramp-handle-insert-directory
+(defun tramp-sh-handle-insert-directory
   (filename switches &optional wildcard full-directory-p)
   "Like `insert-directory' for Tramp files."
   (setq filename (expand-file-name filename))
@@ -2673,7 +2549,7 @@ This is like `dired-recursive-delete-directory' for Tramp files."
          (forward-line -1))
        (when (looking-at "//DIRED//\\s-+")
          (let ((databeg (match-end 0))
-               (end (tramp-compat-line-end-position)))
+               (end (point-at-eol)))
            ;; Now read the numeric positions of file names.
            (goto-char databeg)
            (while (< (point) end)
@@ -2683,7 +2559,7 @@ This is like `dired-recursive-delete-directory' for Tramp files."
                    ;; End is followed by \n or by " -> ".
                    (put-text-property start end 'dired-filename t))))))
        ;; Remove trailing lines.
-       (goto-char (tramp-compat-line-beginning-position))
+       (goto-char (point-at-bol))
        (while (looking-at "//")
          (forward-line 1)
          (delete-region (match-beginning 0) (point)))
@@ -2702,15 +2578,9 @@ This is like `dired-recursive-delete-directory' for Tramp files."
 
        (goto-char (point-max))))))
 
-(defun tramp-handle-unhandled-file-name-directory (filename)
-  "Like `unhandled-file-name-directory' for Tramp files."
-  ;; With Emacs 23, we could simply return `nil'.  But we must keep it
-  ;; for backward compatibility.
-  (expand-file-name "~/"))
-
 ;; Canonicalization of file names.
 
-(defun tramp-handle-expand-file-name (name &optional dir)
+(defun tramp-sh-handle-expand-file-name (name &optional dir)
   "Like `expand-file-name' for Tramp files.
 If the localname part of the given filename starts with \"/../\" then
 the result will be a local, non-Tramp, filename."
@@ -2748,8 +2618,7 @@ the result will be a local, non-Tramp, filename."
                   v (format "cd %s; pwd" (tramp-shell-quote-argument uname)))
                  (with-current-buffer (tramp-get-buffer v)
                    (goto-char (point-min))
-                   (buffer-substring
-                    (point) (tramp-compat-line-end-position)))))
+                   (buffer-substring (point) (point-at-eol)))))
          (setq localname (concat uname fname))))
       ;; There might be a double slash, for example when "~/"
       ;; expands to "/".  Remove this.
@@ -2769,41 +2638,9 @@ the result will be a local, non-Tramp, filename."
          (tramp-run-real-handler
           'expand-file-name (list localname))))))))
 
-(defun tramp-handle-substitute-in-file-name (filename)
-  "Like `substitute-in-file-name' for Tramp files.
-\"//\" and \"/~\" substitute only in the local filename part.
-If the URL Tramp syntax is chosen, \"//\" as method delimeter and \"/~\" at
-beginning of local filename are not substituted."
-  ;; First, we must replace environment variables.
-  (setq filename (tramp-replace-environment-variables filename))
-  (with-parsed-tramp-file-name filename nil
-    (if (equal tramp-syntax 'url)
-       ;; We need to check localname only.  The other parts cannot contain
-       ;; "//" or "/~".
-       (if (and (> (length localname) 1)
-                (or (string-match "//" localname)
-                    (string-match "/~" localname 1)))
-           (tramp-run-real-handler 'substitute-in-file-name (list filename))
-         (tramp-make-tramp-file-name
-          (when method (substitute-in-file-name method))
-          (when user (substitute-in-file-name user))
-          (when host (substitute-in-file-name host))
-          (when localname
-            (tramp-run-real-handler
-             'substitute-in-file-name (list localname)))))
-      ;; Ignore in LOCALNAME everything before "//" or "/~".
-      (when (and (stringp localname) (string-match ".+?/\\(/\\|~\\)" localname))
-       (setq filename
-             (concat (file-remote-p filename)
-                     (replace-match "\\1" nil nil localname)))
-       ;; "/m:h:~" does not work for completion.  We use "/m:h:~/".
-       (when (string-match "~$" filename)
-         (setq filename (concat filename "/"))))
-      (tramp-run-real-handler 'substitute-in-file-name (list filename)))))
-
 ;;; Remote commands:
 
-(defun tramp-handle-executable-find (command)
+(defun tramp-sh-handle-executable-find (command)
   "Like `executable-find' for Tramp files."
   (with-parsed-tramp-file-name default-directory nil
     (tramp-find-executable v command (tramp-get-remote-path v) t)))
@@ -2819,66 +2656,70 @@ beginning of local filename are not substituted."
 ;; We use BUFFER also as connection buffer during setup. Because of
 ;; this, its original contents must be saved, and restored once
 ;; connection has been setup.
-(defun tramp-handle-start-file-process (name buffer program &rest args)
+(defun tramp-sh-handle-start-file-process (name buffer program &rest args)
   "Like `start-file-process' for Tramp files."
   (with-parsed-tramp-file-name default-directory nil
-    (unwind-protect
-       ;; When PROGRAM is nil, we just provide a tty.
-       (let ((command
-              (when (stringp program)
-                (format "cd %s; exec %s"
-                        (tramp-shell-quote-argument localname)
-                        (mapconcat 'tramp-shell-quote-argument
-                                   (cons program args) " "))))
-             (tramp-process-connection-type
-              (or (null program) tramp-process-connection-type))
-             (name1 name)
-             (i 0))
-         (unless buffer
-           ;; BUFFER can be nil.  We use a temporary buffer.
-           (setq buffer (generate-new-buffer tramp-temp-buffer-name)))
-         (while (get-process name1)
-           ;; NAME must be unique as process name.
-           (setq i (1+ i)
-                 name1 (format "%s<%d>" name i)))
-         (setq name name1)
-         ;; Set the new process properties.
-         (tramp-set-connection-property v "process-name" name)
-         (tramp-set-connection-property v "process-buffer" buffer)
-         ;; Activate narrowing in order to save BUFFER contents.
-         ;; Clear also the modification time; otherwise we might be
-         ;; interrupted by `verify-visited-file-modtime'.
-         (with-current-buffer (tramp-get-connection-buffer v)
-           (clear-visited-file-modtime)
-           (narrow-to-region (point-max) (point-max)))
-         (if command
-             ;; Send the command.
-             (tramp-send-command v command nil t) ; nooutput
-           ;; Check, whether a pty is associated.
-           (tramp-maybe-open-connection v)
-           (unless (tramp-compat-process-get
-                    (tramp-get-connection-process v) 'remote-tty)
-             (tramp-error
-              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)
-           (tramp-set-process-query-on-exit-flag p t)
-           ;; Return process.
-           p))
-      ;; Save exit.
-      (with-current-buffer (tramp-get-connection-buffer v)
-       (if (string-match tramp-temp-buffer-name (buffer-name))
-           (progn
-             (set-process-buffer (tramp-get-connection-process v) nil)
-             (kill-buffer (current-buffer)))
-         (widen)
-         (goto-char (point-max))))
-      (tramp-set-connection-property v "process-name" nil)
-      (tramp-set-connection-property v "process-buffer" nil))))
-
-(defun tramp-handle-process-file
+    ;; When PROGRAM is nil, we just provide a tty.
+    (let ((command
+          (when (stringp program)
+            (format "cd %s; exec %s"
+                    (tramp-shell-quote-argument localname)
+                    (mapconcat 'tramp-shell-quote-argument
+                               (cons program args) " "))))
+         (tramp-process-connection-type
+          (or (null program) tramp-process-connection-type))
+         (bmp (and (buffer-live-p buffer) (buffer-modified-p buffer)))
+         (name1 name)
+         (i 0))
+      (unwind-protect
+         (save-excursion
+           (save-restriction
+             (unless buffer
+               ;; BUFFER can be nil.  We use a temporary buffer.
+               (setq buffer (generate-new-buffer tramp-temp-buffer-name)))
+             (while (get-process name1)
+               ;; NAME must be unique as process name.
+               (setq i (1+ i)
+                     name1 (format "%s<%d>" name i)))
+             (setq name name1)
+             ;; Set the new process properties.
+             (tramp-set-connection-property v "process-name" name)
+             (tramp-set-connection-property v "process-buffer" buffer)
+             ;; Activate narrowing in order to save BUFFER contents.
+             ;; Clear also the modification time; otherwise we might
+             ;; be interrupted by `verify-visited-file-modtime'.
+             (with-current-buffer (tramp-get-connection-buffer v)
+               (let ((buffer-undo-list t))
+                 (clear-visited-file-modtime)
+                 (narrow-to-region (point-max) (point-max))
+                 (if command
+                     ;; Send the command.
+                     (tramp-send-command v command nil t) ; nooutput
+                   ;; Check, whether a pty is associated.
+                   (tramp-maybe-open-connection v)
+                   (unless (tramp-compat-process-get
+                            (tramp-get-connection-process v) 'remote-tty)
+                     (tramp-error
+                      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)
+               (tramp-compat-set-process-query-on-exit-flag p t)
+               ;; Return process.
+               p)))
+       ;; Save exit.
+       (with-current-buffer (tramp-get-connection-buffer v)
+         (if (string-match tramp-temp-buffer-name (buffer-name))
+             (progn
+               (set-process-buffer (tramp-get-connection-process v) nil)
+               (kill-buffer (current-buffer)))
+           (set-buffer-modified-p bmp)))
+       (tramp-set-connection-property v "process-name" nil)
+       (tramp-set-connection-property v "process-buffer" nil)))))
+
+(defun tramp-sh-handle-process-file
   (program &optional infile destination display &rest args)
   "Like `process-file' for Tramp files."
   ;; The implementation is not complete yet.
@@ -2991,7 +2832,7 @@ beginning of local filename are not substituted."
          (keyboard-quit)
        ret))))
 
-(defun tramp-handle-call-process-region
+(defun tramp-sh-handle-call-process-region
   (start end program &optional delete buffer display &rest args)
   "Like `call-process-region' for Tramp files."
   (let ((tmpfile (tramp-compat-make-temp-file "")))
@@ -3001,7 +2842,7 @@ beginning of local filename are not substituted."
        (apply 'call-process program tmpfile buffer display args)
       (delete-file tmpfile))))
 
-(defun tramp-handle-shell-command
+(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))
@@ -3082,16 +2923,15 @@ beginning of local filename are not substituted."
                (tramp-compat-funcall 'display-message-or-buffer output-buffer)
              (pop-to-buffer output-buffer))))))))
 
-(defun tramp-handle-file-local-copy (filename)
+(defun tramp-sh-handle-file-local-copy (filename)
   "Like `file-local-copy' for Tramp files."
-
   (with-parsed-tramp-file-name filename nil
     (unless (file-exists-p filename)
       (tramp-error
        v 'file-error
        "Cannot make local copy of non-existing file `%s'" filename))
 
-    (let* ((size (nth 7 (file-attributes filename)))
+    (let* ((size (nth 7 (file-attributes (file-truename filename))))
           (rem-enc (tramp-get-inline-coding v "remote-encoding" size))
           (loc-dec (tramp-get-inline-coding v "local-decoding" size))
           (tmpfile (tramp-compat-make-temp-file filename)))
@@ -3163,131 +3003,8 @@ beginning of local filename are not substituted."
       (run-hooks 'tramp-handle-file-local-copy-hook)
       tmpfile)))
 
-(defun tramp-handle-file-remote-p (filename &optional identification connected)
-  "Like `file-remote-p' for Tramp files."
-  (let ((tramp-verbose 3))
-    (when (tramp-tramp-file-p filename)
-      (let* ((v (tramp-dissect-file-name filename))
-            (p (tramp-get-connection-process v))
-            (c (and p (processp p) (memq (process-status p) '(run open)))))
-       ;; We expand the file name only, if there is already a connection.
-       (with-parsed-tramp-file-name
-           (if c (expand-file-name filename) filename) nil
-         (and (or (not connected) c)
-              (cond
-               ((eq identification 'method) method)
-               ((eq identification 'user) user)
-               ((eq identification 'host) host)
-               ((eq identification 'localname) localname)
-               (t (tramp-make-tramp-file-name method user host "")))))))))
-
-(defun tramp-handle-insert-file-contents
-  (filename &optional visit beg end replace)
-  "Like `insert-file-contents' for Tramp files."
-  (barf-if-buffer-read-only)
-  (setq filename (expand-file-name filename))
-  (let (result local-copy remote-copy)
-    (with-parsed-tramp-file-name filename nil
-      (unwind-protect
-         (if (not (file-exists-p filename))
-             ;; We don't raise a Tramp error, because it might be
-             ;; suppressed, like in `find-file-noselect-1'.
-             (signal 'file-error
-                     (list "File not found on remote host" filename))
-
-           (if (and (tramp-local-host-p v)
-                    (let (file-name-handler-alist)
-                      (file-readable-p localname)))
-               ;; Short track: if we are on the local host, we can
-               ;; run directly.
-               (setq result
-                     (tramp-run-real-handler
-                      'insert-file-contents
-                      (list localname visit beg end replace)))
-
-             ;; When we shall insert only a part of the file, we copy
-             ;; this part.
-             (when (or beg end)
-               (setq remote-copy (tramp-make-tramp-temp-file v))
-               (tramp-send-command
-                v
-                (cond
-                 ((and beg end)
-                  (format "tail -c +%d %s | head -c +%d >%s"
-                          (1+ beg) (tramp-shell-quote-argument localname)
-                          (- end beg) remote-copy))
-                 (beg
-                  (format "tail -c +%d %s >%s"
-                          (1+ beg) (tramp-shell-quote-argument localname)
-                          remote-copy))
-                 (end
-                  (format "head -c +%d %s >%s"
-                          (1+ end) (tramp-shell-quote-argument localname)
-                          remote-copy)))))
-
-             ;; `insert-file-contents-literally' takes care to avoid
-             ;; calling jka-compr.  By let-binding
-             ;; `inhibit-file-name-operation', we propagate that care
-             ;; to the `file-local-copy' operation.
-             (setq local-copy
-                   (let ((inhibit-file-name-operation
-                          (when (eq inhibit-file-name-operation
-                                    'insert-file-contents)
-                            'file-local-copy)))
-                     (cond
-                      ((stringp remote-copy)
-                       (file-local-copy
-                        (tramp-make-tramp-file-name
-                         method user host remote-copy)))
-                      ((stringp tramp-temp-buffer-file-name)
-                       (copy-file filename tramp-temp-buffer-file-name 'ok)
-                       tramp-temp-buffer-file-name)
-                      (t (file-local-copy filename)))))
-
-             ;; When the file is not readable for the owner, it
-             ;; cannot be inserted, even it is redable for the group
-             ;; or for everybody.
-             (set-file-modes local-copy (tramp-compat-octal-to-decimal "0600"))
-
-             (when (and (null remote-copy)
-                        (tramp-get-method-parameter
-                         method 'tramp-copy-keep-tmpfile))
-               ;; We keep the local file for performance reasons,
-               ;; useful for "rsync".
-               (setq tramp-temp-buffer-file-name local-copy)
-               (put 'tramp-temp-buffer-file-name 'permanent-local t))
-
-             (with-progress-reporter
-                 v 3 (format "Inserting local temp file `%s'" local-copy)
-               ;; We must ensure that `file-coding-system-alist'
-               ;; matches `local-copy'.
-               (let ((file-coding-system-alist
-                      (tramp-find-file-name-coding-system-alist
-                       filename local-copy)))
-                 (setq result
-                       (insert-file-contents
-                        local-copy nil nil nil replace))))))
-
-       ;; Save exit.
-       (progn
-         (when visit
-           (setq buffer-file-name filename)
-           (setq buffer-read-only (not (file-writable-p filename)))
-           (set-visited-file-modtime)
-           (set-buffer-modified-p nil))
-         (when (and (stringp local-copy)
-                    (or remote-copy (null tramp-temp-buffer-file-name)))
-           (delete-file local-copy))
-         (when (stringp remote-copy)
-           (delete-file
-            (tramp-make-tramp-file-name method user host remote-copy))))))
-
-    ;; Result.
-    (list (expand-file-name filename)
-         (cadr result))))
-
 ;; This is needed for XEmacs only.  Code stolen from files.el.
-(defun tramp-handle-insert-file-contents-literally
+(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)
@@ -3309,49 +3026,7 @@ beginning of local filename are not substituted."
          (fset 'find-buffer-file-type find-buffer-file-type-function)
        (fmakunbound 'find-buffer-file-type)))))
 
-(defun tramp-handle-find-backup-file-name (filename)
-  "Like `find-backup-file-name' for Tramp files."
-  (with-parsed-tramp-file-name filename nil
-    ;; We set both variables. It doesn't matter whether it is
-    ;; Emacs or XEmacs.
-    (let ((backup-directory-alist
-          ;; Emacs case.
-          (when (boundp 'backup-directory-alist)
-            (if (symbol-value 'tramp-backup-directory-alist)
-                (mapcar
-                 (lambda (x)
-                   (cons
-                    (car x)
-                    (if (and (stringp (cdr x))
-                             (file-name-absolute-p (cdr x))
-                             (not (tramp-file-name-p (cdr x))))
-                        (tramp-make-tramp-file-name method user host (cdr x))
-                      (cdr x))))
-                 (symbol-value 'tramp-backup-directory-alist))
-              (symbol-value 'backup-directory-alist))))
-
-         (bkup-backup-directory-info
-          ;; XEmacs case.
-          (when (boundp 'bkup-backup-directory-info)
-            (if (symbol-value 'tramp-bkup-backup-directory-info)
-                (mapcar
-                 (lambda (x)
-                   (nconc
-                    (list (car x))
-                    (list
-                     (if (and (stringp (car (cdr x)))
-                              (file-name-absolute-p (car (cdr x)))
-                              (not (tramp-file-name-p (car (cdr x)))))
-                         (tramp-make-tramp-file-name
-                          method user host (car (cdr x)))
-                       (car (cdr x))))
-                    (cdr (cdr x))))
-                 (symbol-value 'tramp-bkup-backup-directory-info))
-              (symbol-value 'bkup-backup-directory-info)))))
-
-      (tramp-run-real-handler 'find-backup-file-name (list filename)))))
-
-(defun tramp-handle-make-auto-save-file-name ()
+(defun tramp-sh-handle-make-auto-save-file-name ()
   "Like `make-auto-save-file-name' for Tramp files.
 Returns a file name in `tramp-auto-save-directory' for autosaving this file."
   (let ((tramp-auto-save-directory tramp-auto-save-directory)
@@ -3393,11 +3068,8 @@ Returns a file name in `tramp-auto-save-directory' for autosaving this file."
        (tramp-run-real-handler 'make-auto-save-file-name nil)
        (ad-activate 'make-auto-save-file-name)))))
 
-(defvar tramp-handle-write-region-hook nil
-  "Normal hook to be run at the end of `tramp-handle-write-region'.")
-
 ;; CCC grok LOCKNAME
-(defun tramp-handle-write-region
+(defun tramp-sh-handle-write-region
   (start end filename &optional append visit lockname confirm)
   "Like `write-region' for Tramp files."
   (setq filename (expand-file-name filename))
@@ -3410,7 +3082,7 @@ Returns a file name in `tramp-auto-save-directory' for autosaving this file."
     ;;  (unless (or (eq lockname nil)
     ;;              (string= lockname filename))
     ;;    (error
-    ;;     "tramp-handle-write-region: LOCKNAME must be nil or equal FILENAME"))
+    ;;     "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))
@@ -3482,7 +3154,7 @@ Returns a file name in `tramp-auto-save-directory' for autosaving this file."
          ;; filename does not exist (eq modes nil) it has been
          ;; renamed to the backup file.  This case `save-buffer'
          ;; handles permissions.
-         ;; Ensure, that it is still readable.
+         ;; Ensure that it is still readable.
          (when modes
            (set-file-modes
             tmpfile
@@ -3628,7 +3300,7 @@ Returns a file name in `tramp-auto-save-directory' for autosaving this file."
        (when (or (eq visit t) (stringp visit))
           (let ((file-attr (file-attributes filename)))
             (set-visited-file-modtime
-             ;; We must pass modtime explicitely, because filename can
+             ;; We must pass modtime explicitly, because filename can
              ;; be different from (buffer-file-name), f.e. if
              ;; `file-precious-flag' is set.
              (nth 5 file-attr))
@@ -3659,7 +3331,7 @@ Returns a file name in `tramp-auto-save-directory' for autosaving this file."
 ;; can reset the file name handlers, and we make a second run of
 ;; `vc-registered', which returns the expected result without sending
 ;; any other remote command.
-(defun tramp-handle-vc-registered (file)
+(defun tramp-sh-handle-vc-registered (file)
   "Like `vc-registered' for Tramp files."
   (tramp-compat-with-temp-message ""
     (with-parsed-tramp-file-name file nil
@@ -3669,7 +3341,7 @@ Returns a file name in `tramp-auto-save-directory' for autosaving this file."
        ;; There could be new files, created by the vc backend.  We
        ;; cannot reuse the old cache entries, therefore.
        (let (tramp-vc-registered-file-names
-             (tramp-cache-inhibit-cache (current-time))
+             (remote-file-name-inhibit-cache (current-time))
              (file-name-handler-alist
               `((,tramp-file-name-regexp . tramp-vc-file-name-handler))))
 
@@ -3735,7 +3407,7 @@ Fall back to normal file name handler if no Tramp handler exists."
       (with-parsed-tramp-file-name filename nil
        (cond
         ;; That's what we want: file names, for which checks are
-        ;; applied.  We assume, that VC uses only `file-exists-p' and
+        ;; applied.  We assume that VC uses only `file-exists-p' and
         ;; `file-readable-p' checks; otherwise we must extend the
         ;; list.  We do not perform any action, but return nil, in
         ;; order to keep `vc-registered' running.
@@ -3852,8 +3524,7 @@ This function expects to be in the right *tramp* buffer."
        (when (search-backward "tramp_executable " nil t)
          (skip-chars-forward "^ ")
          (skip-chars-forward " ")
-         (setq result (buffer-substring
-                       (point) (tramp-compat-line-end-position)))))
+         (setq result (buffer-substring (point) (point-at-eol)))))
     result)))
 
 (defun tramp-set-remote-path (vec)
@@ -4003,7 +3674,7 @@ process to set up.  VEC specifies the connection."
     ;; the single quotes makes it work under `rc', too.  We also unset
     ;; the variable $ENV because that is read by some sh
     ;; implementations (eg, bash when called as sh) on startup; this
-    ;; way, we avoid the startup file clobbering $PS1.  $PROMP_COMMAND
+    ;; way, we avoid the startup file clobbering $PS1.  $PROMPT_COMMAND
     ;; is another way to set the prompt in /bin/bash, it must be
     ;; discarded as well.
     (tramp-open-shell
@@ -4050,10 +3721,10 @@ process to set up.  VEC specifies the connection."
          (setq cs-encode (cdr cs))
          (unless cs-decode (setq cs-decode 'undecided))
          (unless cs-encode (setq cs-encode 'undecided))
-         (setq cs-encode (tramp-coding-system-change-eol-conversion
+         (setq cs-encode (tramp-compat-coding-system-change-eol-conversion
                           cs-encode 'unix))
          (when (search-forward "\r" nil t)
-           (setq cs-decode (tramp-coding-system-change-eol-conversion
+           (setq cs-decode (tramp-compat-coding-system-change-eol-conversion
                             cs-decode 'dos)))
          (tramp-compat-funcall
           'set-buffer-process-coding-system cs-decode cs-encode)
@@ -4065,9 +3736,7 @@ process to set up.  VEC specifies the connection."
        ;; because we're running on a non-MULE Emacs.  Let's try
        ;; stty, instead.
        (tramp-send-command vec "stty -onlcr" t))))
-  ;; Dump stty settings in the traces.
-  (when (>= tramp-verbose 9)
-    (tramp-send-command vec "stty -a" t))
+
   (tramp-send-command vec "set +o vi +o emacs" t)
 
   ;; Check whether the output of "uname -sr" has been changed.  If
@@ -4085,7 +3754,7 @@ process to set up.  VEC specifies the connection."
        ;; Keep the debug buffer.
        (rename-buffer
         (generate-new-buffer-name tramp-temp-buffer-name) 'unique)
-       (tramp-compat-funcall 'tramp-cleanup-connection vec)
+       (tramp-cleanup-connection vec)
        (if (= (point-min) (point-max))
            (kill-buffer nil)
          (rename-buffer (tramp-debug-buffer-name vec) 'unique))
@@ -4138,12 +3807,21 @@ process to set up.  VEC specifies the connection."
   (when (string-match "^IRIX64" (tramp-get-connection-property vec "uname" ""))
     (tramp-send-command vec "set +H" t))
 
+  ;; On BSD-like systems, ?\t is expanded to spaces.  Suppress this.
+  (when (string-match "BSD\\|Darwin"
+                     (tramp-get-connection-property vec "uname" ""))
+    (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))))
 
+  ;; Dump stty settings in the traces.
+  (when (>= tramp-verbose 9)
+    (tramp-send-command vec "stty -a" t))
+
   ;; Set the environment.
   (tramp-message vec 5 "Setting default environment")
 
@@ -4207,7 +3885,11 @@ 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")
+  '((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 "mimencode -b" "mimencode -u -b")
     (b64 "mmencode -b" "mmencode -u -b")
     (b64 "recode data..base64" "recode base64..data")
@@ -4386,9 +4068,17 @@ Goes through the list `tramp-inline-compress-commands'."
           vec 5
           "Checking local compress command `%s', `%s' for sanity"
           compress decompress)
-         (unless (zerop (tramp-call-local-coding-command
-                         (format "echo %s | %s | %s"
-                                 magic compress decompress) nil nil))
+         (unless
+             (zerop
+              (tramp-call-local-coding-command
+               (format
+                ;; Windows shells need the program file name after
+                ;; the pipe symbol be quoted if they use forward
+                ;; slashes as directory separators.
+                (if (memq system-type '(windows-nt))
+                    "echo %s | \"%s\" | \"%s\""
+                  "echo %s | %s | %s")
+                magic compress decompress) nil nil))
            (throw 'next nil))
          (tramp-message
           vec 5
@@ -4457,22 +4147,10 @@ Gateway hops are already opened."
       (let ((gw (pop target-alist))
            (hop (pop target-alist)))
        ;; Is the method prepared for gateways?
-       (unless (tramp-get-method-parameter
-                (tramp-file-name-method hop) 'tramp-default-port)
+       (unless (tramp-file-name-port hop)
          (tramp-error
           vec 'file-error
-          "Method `%s' is not supported for gateway access."
-          (tramp-file-name-method hop)))
-       ;; Add default port if needed.
-       (unless
-           (string-match
-            tramp-host-with-port-regexp (tramp-file-name-host hop))
-         (aset hop 2
-               (concat
-                (tramp-file-name-host hop) tramp-prefix-port-format
-                (number-to-string
-                 (tramp-get-method-parameter
-                  (tramp-file-name-method hop) 'tramp-default-port)))))
+          "Connection `%s' is not supported for gateway access." hop))
        ;; Open the gateway connection.
        (add-to-list
         'target-alist
@@ -4592,7 +4270,7 @@ connection if a previous connection has died for some reason."
                 (p (let ((default-directory
                            (tramp-compat-temporary-file-directory)))
                      (start-process
-                      (or process-name (tramp-buffer-name vec))
+                      (tramp-get-connection-name vec)
                       (tramp-get-connection-buffer vec)
                       tramp-encoding-shell))))
 
@@ -4600,7 +4278,7 @@ connection if a previous connection has died for some reason."
             vec 6 "%s" (mapconcat 'identity (process-command p) " "))
 
            ;; Check whether process is alive.
-           (tramp-set-process-query-on-exit-flag p nil)
+           (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)
 
@@ -4629,7 +4307,7 @@ connection if a previous connection has died for some reason."
                     ;; it is just a prefix for the ControlPath option
                     ;; of ssh; the real temporary file has another
                     ;; name, and it is created and protected by ssh.
-                    ;; It is also removed by ssh, when the connection
+                    ;; It is also removed by ssh when the connection
                     ;; is closed.
                     (tmpfile
                      (tramp-set-connection-property
@@ -4708,6 +4386,11 @@ function waits for output unless NOOUTPUT is set."
       ;; We mark the command string that it can be erased in the output buffer.
       (tramp-set-connection-property p "check-remote-echo" t)
       (setq command (format "%s%s%s" tramp-echo-mark command tramp-echo-mark)))
+    (when (string-match "<<'EOF'" command)
+      ;; Unset $PS1 when using here documents, in order to avoid
+      ;; multiple prompts.
+      (setq command (concat "(PS1= ; " command "\n)")))
+    ;; Send the command.
     (tramp-message vec 6 "%s" command)
     (tramp-send-string vec command)
     (unless nooutput (tramp-wait-for-output p))))
@@ -4731,8 +4414,7 @@ function waits for output unless NOOUTPUT is set."
            ;; A simple-minded busybox has sent " ^H" sequences.
            ;; Delete them.
            (goto-char (point-min))
-           (when (re-search-forward
-                  "^\\(.\b\\)+$" (tramp-compat-line-end-position) t)
+           (when (re-search-forward "^\\(.\b\\)+$" (point-at-eol) t)
              (forward-line 1)
              (delete-region (point-min) (point)))
            ;; Delete the prompt.
@@ -4794,84 +4476,13 @@ In case there is no valid Lisp expression, it raises an error"
     (condition-case nil
        (prog1 (read (current-buffer))
          ;; Error handling.
-         (when (re-search-forward "\\S-" (tramp-compat-line-end-position) t)
+         (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))))))
 
-(defun tramp-mode-string-to-int (mode-string)
-  "Converts a ten-letter `drwxrwxrwx'-style mode string into mode bits."
-  (let* (case-fold-search
-        (mode-chars (string-to-vector mode-string))
-         (owner-read (aref mode-chars 1))
-         (owner-write (aref mode-chars 2))
-         (owner-execute-or-setid (aref mode-chars 3))
-         (group-read (aref mode-chars 4))
-         (group-write (aref mode-chars 5))
-         (group-execute-or-setid (aref mode-chars 6))
-         (other-read (aref mode-chars 7))
-         (other-write (aref mode-chars 8))
-         (other-execute-or-sticky (aref mode-chars 9)))
-    (save-match-data
-      (logior
-       (cond
-       ((char-equal owner-read ?r) (tramp-compat-octal-to-decimal "00400"))
-       ((char-equal owner-read ?-) 0)
-       (t (error "Second char `%c' must be one of `r-'" owner-read)))
-       (cond
-       ((char-equal owner-write ?w) (tramp-compat-octal-to-decimal "00200"))
-       ((char-equal owner-write ?-) 0)
-       (t (error "Third char `%c' must be one of `w-'" owner-write)))
-       (cond
-       ((char-equal owner-execute-or-setid ?x)
-        (tramp-compat-octal-to-decimal "00100"))
-       ((char-equal owner-execute-or-setid ?S)
-        (tramp-compat-octal-to-decimal "04000"))
-       ((char-equal owner-execute-or-setid ?s)
-        (tramp-compat-octal-to-decimal "04100"))
-       ((char-equal owner-execute-or-setid ?-) 0)
-       (t (error "Fourth char `%c' must be one of `xsS-'"
-                 owner-execute-or-setid)))
-       (cond
-       ((char-equal group-read ?r) (tramp-compat-octal-to-decimal "00040"))
-       ((char-equal group-read ?-) 0)
-       (t (error "Fifth char `%c' must be one of `r-'" group-read)))
-       (cond
-       ((char-equal group-write ?w) (tramp-compat-octal-to-decimal "00020"))
-       ((char-equal group-write ?-) 0)
-       (t (error "Sixth char `%c' must be one of `w-'" group-write)))
-       (cond
-       ((char-equal group-execute-or-setid ?x)
-        (tramp-compat-octal-to-decimal "00010"))
-       ((char-equal group-execute-or-setid ?S)
-        (tramp-compat-octal-to-decimal "02000"))
-       ((char-equal group-execute-or-setid ?s)
-        (tramp-compat-octal-to-decimal "02010"))
-       ((char-equal group-execute-or-setid ?-) 0)
-       (t (error "Seventh char `%c' must be one of `xsS-'"
-                 group-execute-or-setid)))
-       (cond
-       ((char-equal other-read ?r)
-        (tramp-compat-octal-to-decimal "00004"))
-       ((char-equal other-read ?-) 0)
-       (t (error "Eighth char `%c' must be one of `r-'" other-read)))
-       (cond
-         ((char-equal other-write ?w) (tramp-compat-octal-to-decimal "00002"))
-        ((char-equal other-write ?-) 0)
-         (t (error "Nineth char `%c' must be one of `w-'" other-write)))
-       (cond
-       ((char-equal other-execute-or-sticky ?x)
-        (tramp-compat-octal-to-decimal "00001"))
-       ((char-equal other-execute-or-sticky ?T)
-        (tramp-compat-octal-to-decimal "01000"))
-       ((char-equal other-execute-or-sticky ?t)
-        (tramp-compat-octal-to-decimal "01001"))
-       ((char-equal other-execute-or-sticky ?-) 0)
-       (t (error "Tenth char `%c' must be one of `xtT-'"
-                 other-execute-or-sticky)))))))
-
 (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.
@@ -5034,30 +4645,6 @@ This is used internally by `tramp-file-mode-from-int'."
        (> size tramp-copy-size-limit)
        (null (tramp-get-inline-coding vec "remote-encoding" size)))))
 
-(defun tramp-local-host-p (vec)
-  "Return t if this points to the local host, nil otherwise."
-  ;; We cannot use `tramp-file-name-real-host'.  A port is an
-  ;; indication for an ssh tunnel or alike.
-  (let ((host (tramp-file-name-host vec)))
-    (and
-     (stringp host)
-     (string-match tramp-local-host-regexp host)
-     ;; The method shall be applied to one of the shell file name
-     ;; handler.  `tramp-local-host-p' is also called for "smb" and
-     ;; alike, where it must fail.
-     (tramp-get-method-parameter
-      (tramp-file-name-method vec) 'tramp-login-program)
-     ;; The local temp directory must be writable for the other user.
-     (file-writable-p
-      (tramp-make-tramp-file-name
-       (tramp-file-name-method vec)
-       (tramp-file-name-user vec)
-       host
-       (tramp-compat-temporary-file-directory)))
-     ;; On some systems, chown runs only for root.
-     (or (zerop (user-uid))
-        (zerop (tramp-get-remote-uid vec 'integer))))))
-
 ;; Variables local to connection.
 
 (defun tramp-get-remote-path (vec)
@@ -5074,11 +4661,12 @@ This is used internally by `tramp-file-mode-from-int'."
           (elt2 (memq 'tramp-own-remote-path remote-path))
           (default-remote-path
             (when elt1
-              (condition-case nil
-                  (tramp-send-command-and-read
-                   vec "echo \\\"`getconf PATH`\\\"")
-                ;; Default if "getconf" is not available.
-                (error
+              (or
+               (tramp-send-command-and-read
+                vec
+                "x=`getconf PATH 2>/dev/null` && echo \\\"$x\\\" || echo nil")
+               ;; Default if "getconf" is not available.
+               (progn
                  (tramp-message
                   vec 3
                   "`getconf PATH' not successful, using default value \"%s\"."
@@ -5088,7 +4676,6 @@ This is used internally by `tramp-file-mode-from-int'."
             (when elt2
               (condition-case nil
                   (tramp-send-command-and-read vec "echo \\\"$PATH\\\"")
-                ;; Default if "getconf" is not available.
                 (error
                  (tramp-message
                   vec 3 "$PATH not set, ignoring `tramp-own-remote-path'.")
@@ -5143,33 +4730,6 @@ This is used internally by `tramp-file-mode-from-int'."
          dir
        (tramp-error vec 'file-error "Directory %s not accessible" dir)))))
 
-(defun tramp-make-tramp-temp-file (vec)
-  "Create a temporary file on the remote host identified by VEC.
-Return the local name of the temporary file."
-  (let ((prefix
-        (tramp-make-tramp-file-name
-         (tramp-file-name-method vec)
-         (tramp-file-name-user vec)
-         (tramp-file-name-host vec)
-         (tramp-drop-volume-letter
-          (expand-file-name
-           tramp-temp-name-prefix (tramp-get-remote-tmpdir vec)))))
-       result)
-    (while (not result)
-      ;; `make-temp-file' would be the natural choice for
-      ;; implementation.  But it calls `write-region' internally,
-      ;; which also needs a temporary file - we would end in an
-      ;; infinite loop.
-      (setq result (make-temp-name prefix))
-      (if (file-exists-p result)
-         (setq result nil)
-       ;; This creates the file by side effect.
-       (set-file-times result)
-       (set-file-modes result (tramp-compat-octal-to-decimal "0700"))))
-
-    ;; Return the local part.
-    (with-parsed-tramp-file-name result nil localname)))
-
 (defun tramp-get-ls-command (vec)
   (with-connection-property vec "ls"
     (tramp-message vec 5 "Finding a suitable `ls' command")
@@ -5368,54 +4928,73 @@ 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."
-  (let ((coding
-        (with-connection-property vec prop
-          (tramp-find-inline-encoding vec)
-          (tramp-get-connection-property vec prop nil)))
-       (prop1 (if (string-match "encoding" prop)
-                  "inline-compress" "inline-decompress"))
-       compress)
-    ;; The connection property might have been cached.  So we must send
-    ;; the script to the remote side - maybe.
-    (when (and coding (symbolp coding) (string-match "remote" prop))
-      (let ((name (symbol-name coding)))
-       (while (string-match (regexp-quote "-") name)
-         (setq name (replace-match "_" nil t name)))
-       (tramp-maybe-send-script vec (symbol-value coding) name)
-       (setq coding name)))
-    (when coding
-      ;; Check for the `compress' command.
-      (setq compress (tramp-get-inline-compress vec prop1 size))
-      ;; Return the value.
-      (cond
-       ((and compress (symbolp coding))
-       (if (string-match "decompress" prop1)
+  ;; We must catch the errors, because we want to return `nil', when
+  ;; no inline coding is found.
+  (ignore-errors
+    (let ((coding
+          (with-connection-property vec prop
+            (tramp-find-inline-encoding vec)
+            (tramp-get-connection-property vec prop nil)))
+         (prop1 (if (string-match "encoding" prop)
+                    "inline-compress" "inline-decompress"))
+         compress)
+      ;; The connection property might have been cached.  So we must
+      ;; send the script to the remote side - maybe.
+      (when (and coding (symbolp coding) (string-match "remote" prop))
+       (let ((name (symbol-name coding)))
+         (while (string-match (regexp-quote "-") name)
+           (setq name (replace-match "_" nil t name)))
+         (tramp-maybe-send-script vec (symbol-value coding) name)
+         (setq coding name)))
+      (when coding
+       ;; Check for the `compress' command.
+       (setq compress (tramp-get-inline-compress vec prop1 size))
+       ;; Return the value.
+       (cond
+        ((and compress (symbolp coding))
+         (if (string-match "decompress" prop1)
+             `(lambda (beg end)
+                (,coding beg end)
+                (let ((coding-system-for-write 'binary)
+                      (coding-system-for-read 'binary))
+                  (apply
+                   'call-process-region (point-min) (point-max)
+                   (car (split-string ,compress)) t t nil
+                   (cdr (split-string ,compress)))))
            `(lambda (beg end)
-              (,coding beg end)
               (let ((coding-system-for-write 'binary)
                     (coding-system-for-read 'binary))
                 (apply
-                 'call-process-region (point-min) (point-max)
+                 'call-process-region beg end
                  (car (split-string ,compress)) t t nil
-                 (cdr (split-string ,compress)))))
-         `(lambda (beg end)
-            (let ((coding-system-for-write 'binary)
-                  (coding-system-for-read 'binary))
-              (apply
-               'call-process-region beg end
-               (car (split-string ,compress)) t t nil
-               (cdr (split-string ,compress))))
-            (,coding (point-min) (point-max)))))
-       ((symbolp coding)
-       coding)
-       ((and compress (string-match "decoding" prop))
-       (format "(%s | %s >%%s)" coding compress))
-       (compress
-       (format "(%s <%%s | %s)" compress coding))
-       ((string-match "decoding" prop)
-       (format "%s >%%s" coding))
-       (t
-       (format "%s <%%s" coding))))))
+                 (cdr (split-string ,compress))))
+              (,coding (point-min) (point-max)))))
+        ((symbolp coding)
+         coding)
+        ((and compress (string-match "decoding" prop))
+         (format
+          ;; Windows shells need the program file name after
+          ;; the pipe symbol be quoted if they use forward
+          ;; slashes as directory separators.
+          (if (and (string-match "local" prop)
+                   (memq system-type '(windows-nt)))
+              "(%s | \"%s\" >%%s)"
+            "(%s | %s >%%s)")
+          coding compress))
+        (compress
+         (format
+          ;; Windows shells need the program file name after
+          ;; the pipe symbol be quoted if they use forward
+          ;; slashes as directory separators.
+          (if (and (string-match "local" prop)
+                   (memq system-type '(windows-nt)))
+              "(%s <%%s | \"%s\")"
+            "(%s <%%s | %s)")
+          compress coding))
+        ((string-match "decoding" prop)
+         (format "%s >%%s" coding))
+        (t
+         (format "%s <%%s" coding)))))))
 
 ;;; Integration of eshell.el:
 
@@ -5499,7 +5078,7 @@ function cell is returned to be applied on a buffer."
 ;; * It makes me wonder if tramp couldn't fall back to ssh when scp
 ;;   isn't on the remote host.  (Mark A. Hershberger)
 ;; * Use lsh instead of ssh.  (Alfred M. Szmidt)
-;; * Optimize out-of-band copying, when both methods are scp-like (not
+;; * Optimize out-of-band copying when both methods are scp-like (not
 ;;   rsync).
 ;; * Keep a second connection open for out-of-band methods like scp or
 ;;   rsync.