* net/tramp.el (tramp-check-proper-method-and-host): Rename it from
[bpt/emacs.git] / lisp / net / tramp-sh.el
index 21c7479..e37c34e 100644 (file)
 
 ;;; Code:
 
-(eval-when-compile (require 'cl))      ; ignore-errors
 (require 'tramp)
 
-;; Pacify byte-compiler.  The function is needed on XEmacs only.  I'm
-;; not sure at all that this is the right way to do it, but let's hope
-;; it works for now, and wait for a guru to point out the Right Way to
-;; achieve this.
-;;(eval-when-compile
-;;  (unless (fboundp 'dired-insert-set-properties)
-;;    (fset 'dired-insert-set-properties 'ignore)))
-;; Gerd suggests this:
-(eval-when-compile (require 'dired))
-;; Note that dired is required at run-time, too, when it is needed.
-;; It is only needed on XEmacs for the function
-;; `dired-insert-set-properties'.
+;; Pacify byte-compiler.
+(eval-when-compile
+  (require 'cl)
+  (require 'dired))
+(defvar directory-sep-char)
+(defvar tramp-gw-tunnel-method)
+(defvar tramp-gw-socks-method)
 
 (defcustom tramp-inline-compress-start-size 4096
   "The minimum size of compressing where inline transfer.
@@ -109,69 +103,15 @@ detected as prompt when being sent on echoing hosts, therefore.")
     (tramp-copy-keep-date       t)))
 ;;;###tramp-autoload
 (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-shell         "/bin/sh")
-   (tramp-remote-shell-args    ("-c"))
-   (tramp-copy-program         "scp")
-   (tramp-copy-args            (("-P" "%p") ("-p" "%k")        ("-q") ("-r")))
-   (tramp-copy-keep-date       t)
-   (tramp-copy-recursive       t)
-   (tramp-gw-args              (("-o" "GlobalKnownHostsFile=/dev/null")
-                               ("-o" "UserKnownHostsFile=/dev/null")
-                               ("-o" "StrictHostKeyChecking=no")))
-   (tramp-default-port         22)))
-;;;###tramp-autoload
-(add-to-list 'tramp-methods
-  '("scp1"
-    (tramp-login-program        "ssh")
-    (tramp-login-args           (("-l" "%u") ("-p" "%p")
-                                ("-1") ("-e" "none") ("%h")))
-    (tramp-async-args           (("-q")))
-    (tramp-remote-shell         "/bin/sh")
-    (tramp-remote-shell-args    ("-c"))
-    (tramp-copy-program         "scp")
-    (tramp-copy-args            (("-1") ("-P" "%p") ("-p" "%k") ("-q") ("-r")))
-    (tramp-copy-keep-date       t)
-    (tramp-copy-recursive       t)
-    (tramp-gw-args              (("-o" "GlobalKnownHostsFile=/dev/null")
-                                ("-o" "UserKnownHostsFile=/dev/null")
-                                ("-o" "StrictHostKeyChecking=no")))
-    (tramp-default-port         22)))
-;;;###tramp-autoload
-(add-to-list 'tramp-methods
-  '("scp2"
-    (tramp-login-program        "ssh")
-    (tramp-login-args           (("-l" "%u") ("-p" "%p")
-                                ("-2") ("-e" "none") ("%h")))
-    (tramp-async-args           (("-q")))
-    (tramp-remote-shell         "/bin/sh")
-    (tramp-remote-shell-args    ("-c"))
-    (tramp-copy-program         "scp")
-    (tramp-copy-args            (("-2") ("-P" "%p") ("-p" "%k") ("-q") ("-r")))
-    (tramp-copy-keep-date       t)
-    (tramp-copy-recursive       t)
-    (tramp-gw-args              (("-o" "GlobalKnownHostsFile=/dev/null")
-                                ("-o" "UserKnownHostsFile=/dev/null")
-                                ("-o" "StrictHostKeyChecking=no")))
-    (tramp-default-port         22)))
-;;;###tramp-autoload
-(add-to-list 'tramp-methods
-  '("scpc"
+  '("scp"
     (tramp-login-program        "ssh")
-    (tramp-login-args           (("-l" "%u") ("-p" "%p")
-                                ("-o" "ControlPath=%t.%%r@%%h:%%p")
-                                ("-o" "ControlMaster=yes")
+    (tramp-login-args           (("-l" "%u") ("-p" "%p") ("%c")
                                 ("-e" "none") ("%h")))
     (tramp-async-args           (("-q")))
     (tramp-remote-shell         "/bin/sh")
     (tramp-remote-shell-args    ("-c"))
     (tramp-copy-program         "scp")
-    (tramp-copy-args            (("-P" "%p") ("-p" "%k") ("-q") ("-r")
-                                ("-o" "ControlPath=%t.%%r@%%h:%%p")
-                                ("-o" "ControlMaster=auto")))
+    (tramp-copy-args            (("-P" "%p") ("-p" "%k") ("-q") ("-r") ("%c")))
     (tramp-copy-keep-date       t)
     (tramp-copy-recursive       t)
     (tramp-gw-args              (("-o" "GlobalKnownHostsFile=/dev/null")
@@ -182,14 +122,14 @@ detected as prompt when being sent on echoing hosts, therefore.")
 (add-to-list 'tramp-methods
   '("scpx"
     (tramp-login-program        "ssh")
-    (tramp-login-args           (("-l" "%u") ("-p" "%p")
-                                ("-e" "none") ("-t" "-t")
-                                ("%h") ("/bin/sh")))
+    (tramp-login-args           (("-l" "%u") ("-p" "%p") ("%c")
+                                ("-e" "none") ("-t" "-t") ("%h") ("/bin/sh")))
     (tramp-async-args           (("-q")))
     (tramp-remote-shell         "/bin/sh")
     (tramp-remote-shell-args    ("-c"))
     (tramp-copy-program         "scp")
-    (tramp-copy-args            (("-P" "%p") ("-p" "%k") ("-q") ("-r")))
+    (tramp-copy-args            (("-P" "%p") ("-p" "%k")
+                                ("-q") ("-r") ("%c")))
     (tramp-copy-keep-date       t)
     (tramp-copy-recursive       t)
     (tramp-gw-args              (("-o" "GlobalKnownHostsFile=/dev/null")
@@ -200,42 +140,25 @@ detected as prompt when being sent on echoing hosts, therefore.")
 (add-to-list 'tramp-methods
   '("sftp"
     (tramp-login-program        "ssh")
-    (tramp-login-args           (("-l" "%u") ("-p" "%p") ("-e" "none") ("%h")))
+    (tramp-login-args           (("-l" "%u") ("-p" "%p") ("%c")
+                                ("-e" "none") ("%h")))
     (tramp-async-args           (("-q")))
     (tramp-remote-shell         "/bin/sh")
     (tramp-remote-shell-args    ("-c"))
-    (tramp-copy-program         "sftp")))
-;;;###tramp-autoload
+    (tramp-copy-program         "sftp")
+    (tramp-copy-args            ("%c"))))
+ ;;;###tramp-autoload
 (add-to-list 'tramp-methods
   '("rsync"
     (tramp-login-program        "ssh")
-    (tramp-login-args           (("-l" "%u") ("-p" "%p") ("-e" "none") ("%h")))
-    (tramp-async-args           (("-q")))
-    (tramp-remote-shell         "/bin/sh")
-    (tramp-remote-shell-args    ("-c"))
-    (tramp-copy-program         "rsync")
-    (tramp-copy-args            (("-e" "ssh") ("-t" "%k") ("-r")))
-    (tramp-copy-keep-date       t)
-    (tramp-copy-keep-tmpfile    t)
-    (tramp-copy-recursive       t)))
-;;;###tramp-autoload
-(add-to-list 'tramp-methods
-  `("rsyncc"
-    (tramp-login-program        "ssh")
-    (tramp-login-args           (("-l" "%u") ("-p" "%p")
-                                ("-o" "ControlPath=%t.%%r@%%h:%%p")
-                                ("-o" "ControlMaster=yes")
+    (tramp-login-args           (("-l" "%u") ("-p" "%p") ("%c")
                                 ("-e" "none") ("%h")))
     (tramp-async-args           (("-q")))
     (tramp-remote-shell         "/bin/sh")
     (tramp-remote-shell-args    ("-c"))
     (tramp-copy-program         "rsync")
     (tramp-copy-args            (("-t" "%k") ("-r")))
-    (tramp-copy-env             (("RSYNC_RSH")
-                                (,(concat
-                                   "ssh"
-                                   " -o ControlPath=%t.%%r@%%h:%%p"
-                                   " -o ControlMaster=auto"))))
+    (tramp-copy-env             (("RSYNC_RSH") ("ssh" "%c")))
     (tramp-copy-keep-date       t)
     (tramp-copy-keep-tmpfile    t)
     (tramp-copy-recursive       t)))
@@ -257,33 +180,8 @@ detected as prompt when being sent on echoing hosts, therefore.")
 (add-to-list 'tramp-methods
   '("ssh"
     (tramp-login-program        "ssh")
-    (tramp-login-args           (("-l" "%u") ("-p" "%p") ("-e" "none") ("%h")))
-    (tramp-async-args           (("-q")))
-    (tramp-remote-shell         "/bin/sh")
-    (tramp-remote-shell-args    ("-c"))
-    (tramp-gw-args              (("-o" "GlobalKnownHostsFile=/dev/null")
-                                ("-o" "UserKnownHostsFile=/dev/null")
-                                ("-o" "StrictHostKeyChecking=no")))
-    (tramp-default-port         22)))
-;;;###tramp-autoload
-(add-to-list 'tramp-methods
-  '("ssh1"
-    (tramp-login-program        "ssh")
-    (tramp-login-args           (("-l" "%u") ("-p" "%p")
-                                ("-1") ("-e" "none") ("%h")))
-    (tramp-async-args           (("-q")))
-    (tramp-remote-shell         "/bin/sh")
-    (tramp-remote-shell-args    ("-c"))
-    (tramp-gw-args              (("-o" "GlobalKnownHostsFile=/dev/null")
-                                ("-o" "UserKnownHostsFile=/dev/null")
-                                ("-o" "StrictHostKeyChecking=no")))
-    (tramp-default-port         22)))
-;;;###tramp-autoload
-(add-to-list 'tramp-methods
-  '("ssh2"
-    (tramp-login-program        "ssh")
-    (tramp-login-args           (("-l" "%u") ("-p" "%p")
-                                ("-2") ("-e" "none") ("%h")))
+    (tramp-login-args           (("-l" "%u") ("-p" "%p") ("%c")
+                                ("-e" "none") ("%h")))
     (tramp-async-args           (("-q")))
     (tramp-remote-shell         "/bin/sh")
     (tramp-remote-shell-args    ("-c"))
@@ -295,9 +193,8 @@ detected as prompt when being sent on echoing hosts, therefore.")
 (add-to-list 'tramp-methods
   '("sshx"
     (tramp-login-program        "ssh")
-    (tramp-login-args           (("-l" "%u") ("-p" "%p")
-                                ("-e" "none") ("-t" "-t")
-                                ("%h") ("/bin/sh")))
+    (tramp-login-args           (("-l" "%u") ("-p" "%p") ("%c")
+                                ("-e" "none") ("-t" "-t") ("%h") ("/bin/sh")))
     (tramp-async-args           (("-q")))
     (tramp-remote-shell         "/bin/sh")
     (tramp-remote-shell-args    ("-c"))
@@ -319,21 +216,24 @@ detected as prompt when being sent on echoing hosts, therefore.")
     (tramp-login-program        "su")
     (tramp-login-args           (("-") ("%u")))
     (tramp-remote-shell         "/bin/sh")
-    (tramp-remote-shell-args    ("-c"))))
+    (tramp-remote-shell-args    ("-c"))
+    (tramp-connection-timeout   10)))
 ;;;###tramp-autoload
 (add-to-list 'tramp-methods
   '("sudo"
     (tramp-login-program        "sudo")
     (tramp-login-args           (("-u" "%u") ("-s") ("-H") ("-p" "Password:")))
     (tramp-remote-shell         "/bin/sh")
-    (tramp-remote-shell-args    ("-c"))))
+    (tramp-remote-shell-args    ("-c"))
+    (tramp-connection-timeout   10)))
 ;;;###tramp-autoload
 (add-to-list 'tramp-methods
   '("ksu"
     (tramp-login-program        "ksu")
     (tramp-login-args           (("%u") ("-q")))
     (tramp-remote-shell         "/bin/sh")
-    (tramp-remote-shell-args    ("-c"))))
+    (tramp-remote-shell-args    ("-c"))
+    (tramp-connection-timeout   10)))
 ;;;###tramp-autoload
 (add-to-list 'tramp-methods
   '("krlogin"
@@ -350,14 +250,6 @@ detected as prompt when being sent on echoing hosts, therefore.")
     (tramp-remote-shell-args    ("-c"))
     (tramp-default-port         22)))
 ;;;###tramp-autoload
-(add-to-list 'tramp-methods
-  '("plink1"
-    (tramp-login-program        "plink")
-    (tramp-login-args           (("-l" "%u") ("-P" "%p") ("-1" "-ssh") ("%h")))
-    (tramp-remote-shell         "/bin/sh")
-    (tramp-remote-shell-args    ("-c"))
-    (tramp-default-port         22)))
-;;;###tramp-autoload
 (add-to-list 'tramp-methods
   `("plinkx"
     (tramp-login-program        "plink")
@@ -471,23 +363,12 @@ detected as prompt when being sent on echoing hosts, therefore.")
      (tramp-set-completion-function "rcp" tramp-completion-function-alist-rsh)
      (tramp-set-completion-function "remcp" tramp-completion-function-alist-rsh)
      (tramp-set-completion-function "scp" tramp-completion-function-alist-ssh)
-     (tramp-set-completion-function "scp1" tramp-completion-function-alist-ssh)
-     (tramp-set-completion-function "scp2" tramp-completion-function-alist-ssh)
-     (tramp-set-completion-function "scpc" tramp-completion-function-alist-ssh)
      (tramp-set-completion-function "scpx" tramp-completion-function-alist-ssh)
      (tramp-set-completion-function "sftp" tramp-completion-function-alist-ssh)
      (tramp-set-completion-function "rsync" tramp-completion-function-alist-ssh)
-     (tramp-set-completion-function
-      "rsyncc" tramp-completion-function-alist-ssh)
      (tramp-set-completion-function "rsh" tramp-completion-function-alist-rsh)
      (tramp-set-completion-function "remsh" tramp-completion-function-alist-rsh)
      (tramp-set-completion-function "ssh" tramp-completion-function-alist-ssh)
-     (tramp-set-completion-function "ssh1" tramp-completion-function-alist-ssh)
-     (tramp-set-completion-function "ssh2" tramp-completion-function-alist-ssh)
-     (tramp-set-completion-function
-      "ssh1_old" tramp-completion-function-alist-ssh)
-     (tramp-set-completion-function
-      "ssh2_old" tramp-completion-function-alist-ssh)
      (tramp-set-completion-function "sshx" tramp-completion-function-alist-ssh)
      (tramp-set-completion-function
       "telnet" tramp-completion-function-alist-telnet)
@@ -497,8 +378,6 @@ detected as prompt when being sent on echoing hosts, therefore.")
      (tramp-set-completion-function
       "krlogin" tramp-completion-function-alist-rsh)
      (tramp-set-completion-function "plink" tramp-completion-function-alist-ssh)
-     (tramp-set-completion-function
-      "plink1" tramp-completion-function-alist-ssh)
      (tramp-set-completion-function
       "plinkx" tramp-completion-function-alist-putty)
      (tramp-set-completion-function "pscp" tramp-completion-function-alist-ssh)
@@ -538,8 +417,9 @@ as given in your `~/.profile'."
                  (const :tag "Private Directories" tramp-own-remote-path)
                  (string :tag "Directory"))))
 
+;;;###tramp-autoload
 (defcustom tramp-remote-process-environment
-  `("HISTFILE=$HOME/.tramp_history" "HISTSIZE=1" "LC_ALL=C"
+  `("HISTFILE=$HOME/.tramp_history" "HISTSIZE=1" "TMOUT=0" "LC_ALL=C"
     ,(format "TERM=%s" tramp-terminal-type)
     "EMACS=t" ;; Deprecated.
     ,(format "INSIDE_EMACS='%s,tramp:%s'" emacs-version tramp-version)
@@ -884,6 +764,16 @@ while (my $data = <STDIN>) {
 Escape sequence %s is replaced with name of Perl binary.
 This string is passed to `format', so percent characters need to be doubled.")
 
+(defconst tramp-perl-pack
+  "%s -e 'binmode STDIN; binmode STDOUT; print pack(q{u*}, join q{}, <>)'"
+  "Perl program to use for encoding a file.
+Escape sequence %s is replaced with name of Perl binary.")
+
+(defconst tramp-perl-unpack
+  "%s -e 'binmode STDIN; binmode STDOUT; print unpack(q{u*}, join q{}, <>)'"
+  "Perl program to use for decoding a file.
+Escape sequence %s is replaced with name of Perl binary.")
+
 (defconst tramp-vc-registered-read-file-names
   "echo \"(\"
 while read file; do
@@ -905,90 +795,78 @@ existence, and file readability.  Input shall be read via
 here-document, otherwise the command could exceed maximum length
 of command line.")
 
-(defconst tramp-file-mode-type-map
-  '((0  . "-")  ; Normal file (SVID-v2 and XPG2)
-    (1  . "p")  ; fifo
-    (2  . "c")  ; character device
-    (3  . "m")  ; multiplexed character device (v7)
-    (4  . "d")  ; directory
-    (5  . "?")  ; Named special file (XENIX)
-    (6  . "b")  ; block device
-    (7  . "?")  ; multiplexed block device (v7)
-    (8  . "-")  ; regular file
-    (9  . "n")  ; network special file (HP-UX)
-    (10 . "l")  ; symlink
-    (11 . "?")  ; ACL shadow inode (Solaris, not userspace)
-    (12 . "s")  ; socket
-    (13 . "D")  ; door special (Solaris)
-    (14 . "w")) ; whiteout (BSD)
-  "A list of file types returned from the `stat' system call.
-This is used to map a mode number to a permission string.")
-
-;; New handlers should be added here.  The following operations can be
-;; handled using the normal primitives: file-name-sans-versions,
-;; get-file-buffer.
+;; New handlers should be added here.
 (defconst tramp-sh-file-name-handler-alist
-  '((load . tramp-handle-load)
-    (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-sh-handle-file-truename)
-    (file-exists-p . tramp-sh-handle-file-exists-p)
+  '(;; `access-file' performed by default handler.
+    (add-name-to-file . tramp-sh-handle-add-name-to-file)
+    ;; `byte-compiler-base-file-name' performed by default handler.
+    (copy-directory . tramp-sh-handle-copy-directory)
+    (copy-file . tramp-sh-handle-copy-file)
+    (delete-directory . tramp-sh-handle-delete-directory)
+    (delete-file . tramp-sh-handle-delete-file)
+    ;; `diff-latest-backup-file' performed by default handler.
+    (directory-file-name . tramp-handle-directory-file-name)
+    (directory-files . tramp-handle-directory-files)
+    (directory-files-and-attributes
+     . tramp-sh-handle-directory-files-and-attributes)
+    ;; `dired-call-process' performed by default handler.
+    (dired-compress-file . tramp-sh-handle-dired-compress-file)
+    (dired-recursive-delete-directory
+     . tramp-sh-handle-dired-recursive-delete-directory)
+    (dired-uncache . tramp-handle-dired-uncache)
+    (expand-file-name . tramp-sh-handle-expand-file-name)
     (file-accessible-directory-p . tramp-handle-file-accessible-directory-p)
+    (file-acl . tramp-sh-handle-file-acl)
+    (file-attributes . tramp-sh-handle-file-attributes)
     (file-directory-p . tramp-sh-handle-file-directory-p)
+    ;; `file-equal-p' performed by default handler.
     (file-executable-p . tramp-sh-handle-file-executable-p)
+    (file-exists-p . tramp-sh-handle-file-exists-p)
+    ;; `file-in-directory-p' performed by default handler.
+    (file-local-copy . tramp-sh-handle-file-local-copy)
+    (file-modes . tramp-handle-file-modes)
+    (file-name-all-completions . tramp-sh-handle-file-name-all-completions)
+    (file-name-as-directory . tramp-handle-file-name-as-directory)
+    (file-name-completion . tramp-handle-file-name-completion)
+    (file-name-directory . tramp-handle-file-name-directory)
+    (file-name-nondirectory . tramp-handle-file-name-nondirectory)
+    ;; `file-name-sans-versions' performed by default handler.
+    (file-newer-than-file-p . tramp-sh-handle-file-newer-than-file-p)
+    (file-notify-add-watch . tramp-sh-handle-file-notify-add-watch)
+    (file-notify-rm-watch . tramp-handle-file-notify-rm-watch)
+    (file-ownership-preserved-p . tramp-sh-handle-file-ownership-preserved-p)
     (file-readable-p . tramp-sh-handle-file-readable-p)
     (file-regular-p . tramp-handle-file-regular-p)
+    (file-remote-p . tramp-handle-file-remote-p)
+    (file-selinux-context . tramp-sh-handle-file-selinux-context)
     (file-symlink-p . tramp-handle-file-symlink-p)
+    (file-truename . tramp-sh-handle-file-truename)
     (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-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-sh-handle-add-name-to-file)
-    (copy-file . tramp-sh-handle-copy-file)
-    (copy-directory . tramp-sh-handle-copy-directory)
+    (find-backup-file-name . tramp-handle-find-backup-file-name)
+    ;; `find-file-noselect' performed by default handler.
+    ;; `get-file-buffer' performed by default handler.
+    (insert-directory . tramp-sh-handle-insert-directory)
+    (insert-file-contents . tramp-handle-insert-file-contents)
+    (insert-file-contents-literally
+     . tramp-sh-handle-insert-file-contents-literally)
+    (load . tramp-handle-load)
+    (make-auto-save-file-name . tramp-handle-make-auto-save-file-name)
+    (make-directory . tramp-sh-handle-make-directory)
+    (make-symbolic-link . tramp-sh-handle-make-symbolic-link)
+    (process-file . tramp-sh-handle-process-file)
     (rename-file . tramp-sh-handle-rename-file)
+    (set-file-acl . tramp-sh-handle-set-file-acl)
     (set-file-modes . tramp-sh-handle-set-file-modes)
+    (set-file-selinux-context . tramp-sh-handle-set-file-selinux-context)
     (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-sh-handle-executable-find)
-    (start-file-process . tramp-sh-handle-start-file-process)
-    (process-file . tramp-sh-handle-process-file)
+    (set-visited-file-modtime . tramp-sh-handle-set-visited-file-modtime)
     (shell-command . tramp-handle-shell-command)
-    (insert-directory . tramp-sh-handle-insert-directory)
-    (expand-file-name . tramp-sh-handle-expand-file-name)
+    (start-file-process . tramp-sh-handle-start-file-process)
     (substitute-in-file-name . tramp-handle-substitute-in-file-name)
-    (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-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-sh-handle-make-auto-save-file-name)
     (unhandled-file-name-directory . tramp-handle-unhandled-file-name-directory)
-    (dired-compress-file . tramp-sh-handle-dired-compress-file)
-    (dired-recursive-delete-directory
-     . tramp-sh-handle-dired-recursive-delete-directory)
-    (dired-uncache . tramp-handle-dired-uncache)
-    (set-visited-file-modtime . tramp-sh-handle-set-visited-file-modtime)
+    (vc-registered . tramp-sh-handle-vc-registered)
     (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)
-    (file-acl . tramp-sh-handle-file-acl)
-    (set-file-acl . tramp-sh-handle-set-file-acl)
-    (vc-registered . tramp-sh-handle-vc-registered))
+    (write-region . tramp-sh-handle-write-region))
   "Alist of handler functions.
 Operations not mentioned here will be handled by the normal Emacs functions.")
 
@@ -1054,7 +932,7 @@ target of the symlink differ."
        (tramp-shell-quote-argument l-localname))
        t))))
 
-(defun tramp-sh-handle-file-truename (filename &optional counter prev-dirs)
+(defun tramp-sh-handle-file-truename (filename)
   "Like `file-truename' for Tramp files."
   (with-parsed-tramp-file-name (expand-file-name filename) nil
     (tramp-make-tramp-file-name method user host
@@ -1330,7 +1208,8 @@ target of the symlink differ."
     (let ((f (buffer-file-name))
          coding-system-used)
       (with-parsed-tramp-file-name f nil
-       (let* ((attr (file-attributes f))
+       (let* ((remote-file-name-inhibit-cache t)
+              (attr (file-attributes f))
               ;; '(-1 65535) means file doesn't exists yet.
               (modtime (or (nth 5 attr) '(-1 65535))))
          (when (boundp 'last-coding-system-used)
@@ -1355,14 +1234,14 @@ target of the symlink differ."
 
 ;; This function makes the same assumption as
 ;; `tramp-sh-handle-set-visited-file-modtime'.
-(defun tramp-sh-handle-verify-visited-file-modtime (buf)
+(defun tramp-sh-handle-verify-visited-file-modtime (&optional 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
 `visited-file-modtime' does not return 0.  Do not call this
 function directly, unless those two cases are already taken care
 of."
-  (with-current-buffer buf
+  (with-current-buffer (or buf (current-buffer))
     (let ((f (buffer-file-name)))
       ;; There is no file visiting the buffer, or the buffer has no
       ;; recorded last modification time, or there is no established
@@ -1434,7 +1313,7 @@ of."
              (utc (not (featurep 'xemacs))))
          (tramp-send-command-and-check
           v (format "%s touch -t %s %s"
-                    (if utc "TZ=UTC; export TZ;" "")
+                    (if utc "env TZ=UTC" "")
                     (if utc
                         (format-time-string "%Y%m%d%H%M.%S" time t)
                       (format-time-string "%Y%m%d%H%M.%S" time))
@@ -1444,7 +1323,7 @@ of."
     ;; without `set-file-times', this function is an alias for this.
     ;; We are local, so we don't need the UTC settings.
     (zerop
-     (tramp-compat-call-process
+     (tramp-call-process
       "touch" nil nil nil "-t"
       (format-time-string "%Y%m%d%H%M.%S" time)
       (tramp-shell-quote-argument filename)))))
@@ -1478,7 +1357,7 @@ be non-negative integers."
       ;; `set-file-uid-gid'.  On W32 "chown" might not work.
       (let ((uid (or (and (natnump uid) uid) (tramp-get-local-uid 'integer)))
            (gid (or (and (natnump gid) gid) (tramp-get-local-gid 'integer))))
-       (tramp-compat-call-process
+       (tramp-call-process
         "chown" nil nil nil
          (format "%d:%d" uid gid) (tramp-shell-quote-argument filename))))))
 
@@ -1952,7 +1831,7 @@ tramp-sh-handle-file-name-all-completions: internal error accessing `%s': `%s'"
      'copy-file (list filename newname ok-if-already-exists keep-date)))))
 
 (defun tramp-sh-handle-copy-directory
-  (dirname newname &optional keep-date parents copy-contents)
+  (dirname newname &optional keep-date parents _copy-contents)
   "Like `copy-directory' for Tramp files."
   (let ((t1 (tramp-tramp-file-p dirname))
        (t2 (tramp-tramp-file-p newname)))
@@ -2026,8 +1905,7 @@ file names."
        (t2 (tramp-tramp-file-p newname))
        (length (nth 7 (file-attributes (file-truename filename))))
        (attributes (and preserve-extended-attributes
-                        (apply 'file-extended-attributes (list filename))))
-       pr tm)
+                        (apply 'file-extended-attributes (list filename)))))
 
     (with-parsed-tramp-file-name (if t1 filename newname) nil
       (when (and (not ok-if-already-exists) (file-exists-p newname))
@@ -2298,7 +2176,7 @@ The method used must be an out-of-band method."
         (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)
+        options source target)
 
     (with-parsed-tramp-file-name (if t1 filename newname) nil
       (if (and t1 t2)
@@ -2366,9 +2244,14 @@ The method used must be an out-of-band method."
              user (or user "")
              port (or port "")
              spec (format-spec-make
-                   ?h host ?u user ?p port
                    ?t (tramp-get-connection-property
-                       (tramp-get-connection-process v) "temp-file" "")
+                       (tramp-get-connection-process v) "temp-file" ""))
+             options (format-spec
+                      (if tramp-use-ssh-controlmaster-options
+                          tramp-ssh-controlmaster-options "")
+                      spec)
+             spec (format-spec-make
+                   ?h host ?u user ?p port ?c options
                    ?k (if keep-date " " ""))
              copy-program (tramp-get-method-parameter
                            method 'tramp-copy-program)
@@ -2399,9 +2282,7 @@ The method used must be an out-of-band method."
                (tramp-get-method-parameter method 'tramp-copy-env))))
 
        ;; Check for program.
-       (unless (let ((default-directory
-                       (tramp-compat-temporary-file-directory)))
-                 (executable-find copy-program))
+       (unless (executable-find copy-program)
          (tramp-error
           v 'file-error "Cannot find copy program: %s" copy-program))
 
@@ -2418,7 +2299,7 @@ The method used must be an out-of-band method."
                 v "process-buffer" (current-buffer))
                (while copy-env
                  (tramp-message
-                  orig-vec 5 "%s=\"%s\"" (car copy-env) (cadr copy-env))
+                  orig-vec 6 "%s=\"%s\"" (car copy-env) (cadr copy-env))
                  (setenv (pop copy-env) (pop copy-env)))
 
                ;; Use an asynchronous process.  By this, password can
@@ -2545,7 +2426,7 @@ This is like `dired-recursive-delete-directory' for Tramp files."
         (tramp-error
          v 'file-error "Failed to recursively delete %s" filename))))
 
-(defun tramp-sh-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.
@@ -2619,8 +2500,8 @@ This is like `dired-recursive-delete-directory' for Tramp files."
                        'file-name-nondirectory (list localname)))
         (setq localname (tramp-run-real-handler
                         'file-name-directory (list localname))))
-      (unless full-directory-p
-        (setq switches (add-to-list 'switches "-d" 'append)))
+      (unless (or full-directory-p (member "-d" switches))
+        (setq switches (append switches '("-d"))))
       (setq switches (mapconcat 'tramp-shell-quote-argument switches " "))
       (when wildcard
        (setq switches (concat switches " " wildcard)))
@@ -2630,10 +2511,13 @@ This is like `dired-recursive-delete-directory' for Tramp files."
        (if full-directory-p "yes" "no"))
       ;; If `full-directory-p', we just say `ls -l FILENAME'.
       ;; Else we chdir to the parent directory, then say `ls -ld BASENAME'.
+      ;; "--dired" returns byte positions.  Therefore, the file names
+      ;; must be encoded, which is guaranteed by "LC_ALL=en_US.utf8
+      ;; LC_CTYPE=''".
       (if full-directory-p
          (tramp-send-command
           v
-          (format "%s %s %s 2>/dev/null"
+          (format "env LC_ALL=en_US.utf8 LC_CTYPE='' %s %s %s 2>/dev/null"
                   (tramp-get-ls-command v)
                   switches
                   (if wildcard
@@ -2649,7 +2533,7 @@ This is like `dired-recursive-delete-directory' for Tramp files."
          (tramp-run-real-handler 'file-name-directory (list localname))))
        (tramp-send-command
         v
-        (format "%s %s %s"
+        (format "env LC_ALL=en_US.utf8 LC_CTYPE='' %s %s %s 2>/dev/null"
                 (tramp-get-ls-command v)
                 switches
                 (if (or wildcard
@@ -2695,6 +2579,13 @@ This is like `dired-recursive-delete-directory' for Tramp files."
          (while (re-search-forward tramp-color-escape-sequence-regexp nil t)
            (replace-match "")))
 
+       ;; Decode the output, it could be multibyte.
+       (decode-coding-region
+        beg (point-max)
+        (or file-name-coding-system
+            (and (boundp 'default-file-name-coding-system)
+                 (symbol-value 'default-file-name-coding-system))))
+
        ;; The inserted file could be from somewhere else.
        (when (and (not wildcard) (not full-directory-p))
          (goto-char (point-max))
@@ -2772,17 +2663,12 @@ the result will be a local, non-Tramp, filename."
 
 ;;; Remote commands:
 
-(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)))
-
 (defun tramp-process-sentinel (proc event)
   "Flush file caches."
   (unless (memq (process-status proc) '(run open))
     (let ((vec (tramp-get-connection-property proc "vector" nil)))
       (when vec
-       (tramp-message vec 5 "Sentinel called: `%s' `%s'" proc event)
+       (tramp-message vec 5 "Sentinel called: `%S' `%s'" proc event)
         (tramp-flush-connection-property proc)
         (tramp-flush-directory-property vec "")))))
 
@@ -2808,7 +2694,11 @@ the result will be a local, non-Tramp, filename."
           (or (null program) tramp-process-connection-type))
          (bmp (and (buffer-live-p buffer) (buffer-modified-p buffer)))
          (name1 name)
-         (i 0))
+         (i 0)
+         ;; We do not want to raise an error when
+         ;; `start-file-process' has been started several time in
+         ;; `eshell' and friends.
+         (tramp-current-connection nil))
 
       (unless buffer
        ;; BUFFER can be nil.  We use a temporary buffer.
@@ -2824,6 +2714,8 @@ the result will be a local, non-Tramp, filename."
 
       (with-current-buffer (tramp-get-connection-buffer v)
        (unwind-protect
+           ;; We catch this event.  Otherwise, `start-process' could
+           ;; be called on the local host.
            (save-excursion
              (save-restriction
                ;; Activate narrowing in order to save BUFFER
@@ -2837,31 +2729,34 @@ the result will be a local, non-Tramp, filename."
                  (narrow-to-region (point-max) (point-max))
                  ;; We call `tramp-maybe-open-connection', in order
                  ;; to cleanup the prompt afterwards.
-                 (tramp-maybe-open-connection v)
-                 (widen)
-                 (delete-region mark (point))
-                 (narrow-to-region (point-max) (point-max))
-                 ;; Now do it.
-                 (if command
-                     ;; Send the command.
-                     (tramp-send-command v command nil t) ; nooutput
-                   ;; Check, whether a pty is associated.
-                   (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 query flag for this process.  We ignore errors,
-                 ;; because the process could have finished already.
-                 (ignore-errors
-                   (tramp-compat-set-process-query-on-exit-flag p t))
-                 ;; Return process.
-                 p)))
+                 (catch 'suppress
+                   (tramp-maybe-open-connection v)
+                   (widen)
+                   (delete-region mark (point))
+                   (narrow-to-region (point-max) (point-max))
+                   ;; Now do it.
+                   (if command
+                       ;; Send the command.
+                       (tramp-send-command v command nil t) ; nooutput
+                     ;; Check, whether a pty is associated.
+                     (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 query flag and process marker for this
+                   ;; process.  We ignore errors, because the process
+                   ;; could have finished already.
+                   (ignore-errors
+                     (tramp-compat-set-process-query-on-exit-flag p t)
+                     (set-marker (process-mark p) (point)))
+                   ;; Return process.
+                   p))))
 
          ;; Save exit.
          (if (string-match tramp-temp-buffer-name (buffer-name))
-             (progn
+             (ignore-errors
                (set-process-buffer (tramp-get-connection-process v) nil)
                (kill-buffer (current-buffer)))
            (set-buffer-modified-p bmp))
@@ -3005,40 +2900,39 @@ the result will be a local, non-Tramp, filename."
           (rem-enc
            (save-excursion
              (with-tramp-progress-reporter
-              v 3 (format "Encoding remote file %s" filename)
+              v 3
+              (format "Encoding remote file `%s' with `%s'" filename rem-enc)
               (tramp-barf-unless-okay
                v (format rem-enc (tramp-shell-quote-argument localname))
                "Encoding remote file failed"))
 
-             (if (functionp loc-dec)
-                 ;; If local decoding is a function, we call it.  We
-                 ;; must disable multibyte, because
-                 ;; `uudecode-decode-region' doesn't handle it
-                 ;; correctly.
-                 (with-temp-buffer
-                   (set-buffer-multibyte nil)
-                   (insert-buffer-substring (tramp-get-buffer v))
-                   (with-tramp-progress-reporter
-                       v 3 (format "Decoding remote file %s with function %s"
-                                   filename loc-dec)
+             (with-tramp-progress-reporter
+                 v 3 (format "Decoding local file `%s' with `%s'"
+                             tmpfile loc-dec)
+               (if (functionp loc-dec)
+                   ;; If local decoding is a function, we call it.
+                   ;; We must disable multibyte, because
+                   ;; `uudecode-decode-region' doesn't handle it
+                   ;; correctly.
+                   (with-temp-buffer
+                     (set-buffer-multibyte nil)
+                     (insert-buffer-substring (tramp-get-buffer v))
                      (funcall loc-dec (point-min) (point-max))
                      ;; Unset `file-name-handler-alist'.  Otherwise,
                      ;; epa-file gets confused.
                      (let (file-name-handler-alist
                            (coding-system-for-write 'binary))
-                       (write-region (point-min) (point-max) tmpfile))))
-
-               ;; If tramp-decoding-function is not defined for this
-               ;; method, we invoke tramp-decoding-command instead.
-               (let ((tmpfile2 (tramp-compat-make-temp-file filename)))
-                 ;; Unset `file-name-handler-alist'.  Otherwise,
-                 ;; epa-file gets confused.
-                 (let (file-name-handler-alist
-                       (coding-system-for-write 'binary))
-                   (write-region (point-min) (point-max) tmpfile2))
-                 (with-tramp-progress-reporter
-                     v 3 (format "Decoding remote file %s with command %s"
-                                 filename loc-dec)
+                       (write-region (point-min) (point-max) tmpfile)))
+
+                 ;; If tramp-decoding-function is not defined for this
+                 ;; method, we invoke tramp-decoding-command instead.
+                 (let ((tmpfile2 (tramp-compat-make-temp-file filename)))
+                   ;; Unset `file-name-handler-alist'.  Otherwise,
+                   ;; epa-file gets confused.
+                   (let (file-name-handler-alist
+                         (coding-system-for-write 'binary))
+                     (with-current-buffer (tramp-get-buffer v)
+                       (write-region (point-min) (point-max) tmpfile2)))
                    (unwind-protect
                        (tramp-call-local-coding-command
                         loc-dec tmpfile2 tmpfile)
@@ -3077,55 +2971,13 @@ the result will be a local, non-Tramp, filename."
        (inhibit-file-name-operation 'insert-file-contents))
     (unwind-protect
        (progn
-         (fset 'find-buffer-file-type (lambda (filename) t))
+         (fset 'find-buffer-file-type (lambda (_filename) t))
          (insert-file-contents filename visit beg end replace))
       ;; Save exit.
       (if find-buffer-file-type-function
          (fset 'find-buffer-file-type find-buffer-file-type-function)
        (fmakunbound 'find-buffer-file-type)))))
 
-(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)
-       (buffer-file-name
-        (tramp-subst-strs-in-string
-         '(("_" . "|")
-           ("/" . "_a")
-           (":" . "_b")
-           ("|" . "__")
-           ("[" . "_l")
-           ("]" . "_r"))
-         (buffer-file-name))))
-    ;; File name must be unique.  This is ensured with Emacs 22 (see
-    ;; UNIQUIFY element of `auto-save-file-name-transforms'); but for
-    ;; all other cases we must do it ourselves.
-    (when (boundp 'auto-save-file-name-transforms)
-      (mapc
-       (lambda (x)
-        (when (and (string-match (car x) buffer-file-name)
-                   (not (car (cddr x))))
-          (setq tramp-auto-save-directory
-                (or tramp-auto-save-directory
-                    (tramp-compat-temporary-file-directory)))))
-       (symbol-value 'auto-save-file-name-transforms)))
-    ;; Create directory.
-    (when tramp-auto-save-directory
-      (setq buffer-file-name
-           (expand-file-name buffer-file-name tramp-auto-save-directory))
-      (unless (file-exists-p tramp-auto-save-directory)
-       (make-directory tramp-auto-save-directory t)))
-    ;; Run plain `make-auto-save-file-name'.  There might be an advice when
-    ;; it is not a magic file name operation (since Emacs 22).
-    ;; We must deactivate it temporarily.
-    (if (not (ad-is-active 'make-auto-save-file-name))
-       (tramp-run-real-handler 'make-auto-save-file-name nil)
-      ;; else
-      (ad-deactivate 'make-auto-save-file-name)
-      (prog1
-       (tramp-run-real-handler 'make-auto-save-file-name nil)
-       (ad-activate 'make-auto-save-file-name)))))
-
 ;; CCC grok LOCKNAME
 (defun tramp-sh-handle-write-region
   (start end filename &optional append visit lockname confirm)
@@ -3263,28 +3115,25 @@ Returns a file name in `tramp-auto-save-directory' for autosaving this file."
                  (with-temp-buffer
                    (set-buffer-multibyte nil)
                    ;; Use encoding function or command.
-                   (if (functionp loc-enc)
-                       (with-tramp-progress-reporter
-                           v 3 (format "Encoding region using function `%s'"
-                                       loc-enc)
-                         (let ((coding-system-for-read 'binary))
-                           (insert-file-contents-literally tmpfile))
-                         ;; The following `let' is a workaround for the
-                         ;; base64.el that comes with pgnus-0.84.  If
-                         ;; both of the following conditions are
+                   (with-tramp-progress-reporter
+                       v 3 (format "Encoding local file `%s' using `%s'"
+                                   tmpfile loc-enc)
+                     (if (functionp loc-enc)
+                         ;; The following `let' is a workaround for
+                         ;; the base64.el that comes with pgnus-0.84.
+                         ;; If both of the following conditions are
                          ;; satisfied, it tries to write to a local
                          ;; file in default-directory, but at this
                          ;; point, default-directory is remote.
                          ;; (`call-process-region' can't write to
                          ;; remote files, it seems.)  The file in
                          ;; question is a tmp file anyway.
-                         (let ((default-directory
+                         (let ((coding-system-for-read 'binary)
+                               (default-directory
                                  (tramp-compat-temporary-file-directory)))
-                           (funcall loc-enc (point-min) (point-max))))
+                           (insert-file-contents-literally tmpfile)
+                           (funcall loc-enc (point-min) (point-max)))
 
-                     (with-tramp-progress-reporter
-                         v 3 (format "Encoding region using command `%s'"
-                                     loc-enc)
                        (unless (zerop (tramp-call-local-coding-command
                                        loc-enc tmpfile t))
                          (tramp-error
@@ -3297,8 +3146,8 @@ Returns a file name in `tramp-auto-save-directory' for autosaving this file."
                    ;; writes to remote file.  Because this happens on
                    ;; the remote host, we cannot use the function.
                    (with-tramp-progress-reporter
-                       v 3
-                       (format "Decoding region into remote file %s" filename)
+                       v 3 (format "Decoding remote file `%s' using `%s'"
+                                   filename rem-dec)
                      (goto-char (point-max))
                      (unless (bolp) (newline))
                      (tramp-send-command
@@ -3318,7 +3167,7 @@ Returns a file name in `tramp-auto-save-directory' for autosaving this file."
                        (erase-buffer)
                        (and
                         ;; cksum runs locally, if possible.
-                        (zerop (tramp-compat-call-process "cksum" tmpfile t))
+                        (zerop (tramp-call-process "cksum" tmpfile t))
                         ;; cksum runs remotely.
                         (tramp-send-command-and-check
                          v
@@ -3437,7 +3286,8 @@ Returns a file name in `tramp-auto-save-directory' for autosaving this file."
        ;; `process-file-side-effects' in order to keep the cache when
        ;; `process-file' calls appear.
        (let (process-file-side-effects)
-         (tramp-run-real-handler 'vc-registered (list file)))))))
+         (ignore-errors
+           (tramp-run-real-handler 'vc-registered (list file))))))))
 
 ;;;###tramp-autoload
 (defun tramp-sh-file-name-handler (operation &rest args)
@@ -3484,6 +3334,114 @@ Fall back to normal file name handler if no Tramp handler exists."
         ;; Default file name handlers, we don't care.
         (t (tramp-run-real-handler operation args)))))))
 
+(defun tramp-sh-handle-file-notify-add-watch (file-name flags _callback)
+  "Like `file-notify-add-watch' for Tramp files."
+  (setq file-name (expand-file-name file-name))
+  (with-parsed-tramp-file-name file-name nil
+    (let* ((default-directory (file-name-directory file-name))
+          command events filter p)
+      (cond
+       ;; gvfs-monitor-dir.
+       ((setq command (tramp-get-remote-gvfs-monitor-dir v))
+       (setq filter 'tramp-sh-file-gvfs-monitor-dir-process-filter
+             p (start-file-process
+                "gvfs-monitor-dir" (generate-new-buffer " *gvfs-monitor-dir*")
+                command localname)))
+       ;; inotifywait.
+       ((setq command (tramp-get-remote-inotifywait v))
+       (setq filter 'tramp-sh-file-inotifywait-process-filter
+             events
+             (cond
+              ((and (memq 'change flags) (memq 'attribute-change flags))
+               "create,modify,move,delete,attrib")
+              ((memq 'change flags) "create,modify,move,delete")
+              ((memq 'attribute-change flags) "attrib"))
+             p (start-file-process
+                 "inotifywait" (generate-new-buffer " *inotifywait*")
+                 command "-mq" "-e" events localname)))
+       ;; None.
+       (t (tramp-error
+          v 'file-notify-error
+          "No file notification program found on %s"
+          (file-remote-p file-name))))
+      ;; Return the process object as watch-descriptor.
+      (if (not (processp p))
+         (tramp-error
+          v 'file-notify-error "`%s' failed to start on remote host" command)
+       (tramp-compat-set-process-query-on-exit-flag p nil)
+       (set-process-filter p filter)
+       p))))
+
+(defun tramp-sh-file-gvfs-monitor-dir-process-filter (proc string)
+  "Read output from \"gvfs-monitor-dir\" and add corresponding file-notify events."
+  (let ((remote-prefix
+        (with-current-buffer (process-buffer proc)
+          (file-remote-p default-directory)))
+       (rest-string (tramp-compat-process-get proc 'rest-string)))
+    (when rest-string
+      (tramp-message proc 10 "Previous string:\n%s" rest-string))
+    (tramp-message proc 6 "%S\n%s" proc string)
+    (setq string (concat rest-string string)
+         ;; Attribute change is returned in unused wording.
+         string (tramp-compat-replace-regexp-in-string
+                 "ATTRIB CHANGED" "ATTRIBUTE_CHANGED" string))
+
+    (while (string-match
+           (concat "^[\n\r]*"
+                   "Directory Monitor Event:[\n\r]+"
+                   "Child = \\([^\n\r]+\\)[\n\r]+"
+                   "\\(Other = \\([^\n\r]+\\)[\n\r]+\\)?"
+                   "Event = \\([^[:blank:]]+\\)[\n\r]+")
+           string)
+      (let ((object
+            (list
+             proc
+             (intern-soft
+              (tramp-compat-replace-regexp-in-string
+               "_" "-" (downcase (match-string 4 string))))
+             ;; File names are returned as absolute paths.  We must
+             ;; add the remote prefix.
+             (concat remote-prefix (match-string 1 string))
+             (when (match-string 3 string)
+               (concat remote-prefix (match-string 3 string))))))
+       (setq string (replace-match "" nil nil string))
+       ;; Usually, we would add an Emacs event now.  Unfortunately,
+       ;; `unread-command-events' does not accept several events at
+       ;; once.  Therefore, we apply the callback directly.
+       (tramp-compat-funcall 'file-notify-callback object)))
+
+    ;; Save rest of the string.
+    (when (zerop (length string)) (setq string nil))
+    (when string (tramp-message proc 10 "Rest string:\n%s" string))
+    (tramp-compat-process-put proc 'rest-string string)))
+
+(defun tramp-sh-file-inotifywait-process-filter (proc string)
+  "Read output from \"inotifywait\" and add corresponding file-notify events."
+  (tramp-message proc 6 "%S\n%s" proc string)
+  (dolist (line (split-string string "[\n\r]+" 'omit-nulls))
+    ;; Check, whether there is a problem.
+    (unless
+       (string-match
+        (concat "^[^[:blank:]]+"
+                "[[:blank:]]+\\([^[:blank:]]+\\)+"
+                "\\([[:blank:]]+\\([^\n\r]+\\)\\)?")
+        line)
+      (tramp-error proc 'file-notify-error "%s" line))
+
+    (let ((object
+          (list
+           proc
+           (mapcar
+            (lambda (x)
+              (intern-soft
+               (tramp-compat-replace-regexp-in-string "_" "-" (downcase x))))
+            (split-string (match-string 1 line) "," 'omit-nulls))
+           (match-string 3 line))))
+      ;; Usually, we would add an Emacs event now.  Unfortunately,
+      ;; `unread-command-events' does not accept several events at
+      ;; once.  Therefore, we apply the callback directly.
+      (tramp-compat-funcall 'file-notify-callback object))))
+
 ;;; Internal Functions:
 
 (defun tramp-maybe-send-script (vec script name)
@@ -3496,6 +3454,9 @@ Only send the definition if it has not already been done."
     (unless (member name scripts)
       (with-tramp-progress-reporter vec 5 (format "Sending script `%s'" name)
        ;; The script could contain a call of Perl.  This is masked with `%s'.
+       (when (and (string-match "%s" script)
+                  (not (tramp-get-remote-perl vec)))
+         (tramp-error vec 'file-error "No Perl available on remote host"))
        (tramp-barf-unless-okay
         vec
         (format "%s () {\n%s\n}" name
@@ -3598,7 +3559,7 @@ This function expects to be in the right *tramp* buffer."
 I.e., for each directory in `tramp-remote-path', it is tested
 whether it exists and if so, it is added to the environment
 variable PATH."
-  (tramp-message vec 5 (format "Setting $PATH environment variable"))
+  (tramp-message vec 5 "Setting $PATH environment variable")
   (tramp-send-command
    vec (format "PATH=%s; export PATH"
               (mapconcat 'identity (tramp-get-remote-path vec) ":"))))
@@ -3731,13 +3692,7 @@ file exists and nonzero exit status otherwise."
       (unless (string-equal shell default-shell)
        (tramp-message
         vec 5 "Starting remote shell `%s' for tilde expansion" shell)
-       (tramp-open-shell vec shell))
-
-      ;; Busyboxes tend to behave strange.  We check for the existence.
-      (with-tramp-connection-property vec "busybox"
-       (tramp-send-command vec (format "%s --version" shell) t)
-       (let ((case-fold-search t))
-         (and (string-match "busybox" (buffer-string)) t))))))
+       (tramp-open-shell vec shell)))))
 
 ;; Utility functions.
 
@@ -3745,12 +3700,16 @@ file exists and nonzero exit status otherwise."
   "Wait for shell prompt and barf if none appears.
 Looks at process PROC to see if a shell prompt appears in TIMEOUT
 seconds.  If not, it produces an error message with the given ERROR-ARGS."
-  (unless
-      (tramp-wait-for-regexp
-       proc timeout
-       (format
-       "\\(%s\\|%s\\)\\'" shell-prompt-pattern tramp-shell-prompt-pattern))
-    (apply 'tramp-error-with-buffer nil proc 'file-error error-args)))
+  (let ((vec (tramp-get-connection-property proc "vector" nil)))
+    (condition-case nil
+       (tramp-wait-for-regexp
+        proc timeout
+        (format
+         "\\(%s\\|%s\\)\\'" shell-prompt-pattern tramp-shell-prompt-pattern))
+      (error
+       (delete-process proc)
+       (apply 'tramp-error-with-buffer
+             (tramp-get-connection-buffer vec) vec 'file-error error-args)))))
 
 (defun tramp-open-connection-setup-interactive-shell (proc vec)
   "Set up an interactive shell.
@@ -3846,11 +3805,12 @@ process to set up.  VEC specifies the connection."
          vec "uname"
          (tramp-send-command-and-read vec "echo \\\"`uname -sr`\\\""))))
     (when (and (stringp old-uname) (not (string-equal old-uname new-uname)))
-      (tramp-cleanup vec)
       (tramp-message
        vec 3
        "Connection reset, because remote host changed from `%s' to `%s'"
        old-uname new-uname)
+      ;; We want to keep the password.
+      (tramp-cleanup-connection vec t t)
       (throw 'uname-changed (tramp-maybe-open-connection vec))))
 
   ;; Check whether the remote host suffers from buggy
@@ -3925,11 +3885,6 @@ process to set up.  VEC specifies the connection."
       (tramp-send-command
        vec (format "unset %s" (mapconcat 'identity unset " ")) t))))
 
-;; CCC: We should either implement a Perl version of base64 encoding
-;; and decoding.  Then we just use that in the last item.  The other
-;; alternative is to use the Perl version of UU encoding.  But then
-;; we need a Lisp version of uuencode.
-;;
 ;; Old text from documentation of tramp-methods:
 ;; Using a uuencode/uudecode inline method is discouraged, please use one
 ;; of the base64 methods instead since base64 encoding is much more
@@ -3946,11 +3901,9 @@ process to set up.  VEC specifies the connection."
 (autoload 'uudecode-decode-region "uudecode")
 
 (defconst tramp-local-coding-commands
-  '((b64 base64-encode-region base64-decode-region)
+  `((b64 base64-encode-region base64-decode-region)
     (uu  tramp-uuencode-region uudecode-decode-region)
-    (pack
-     "perl -e 'binmode STDIN; binmode STDOUT; print pack(q{u*}, join q{}, <>)'"
-     "perl -e 'binmode STDIN; binmode STDOUT; print unpack(q{u*}, join q{}, <>)'"))
+    (pack ,(format tramp-perl-pack "perl") ,(format tramp-perl-unpack "perl")))
   "List of local coding commands for inline transfer.
 Each item is a list that looks like this:
 
@@ -3985,9 +3938,7 @@ with the encoded or decoded results, respectively.")
     (uu  "uuencode xxx" "uudecode -o -")
     (uu  "uuencode xxx" "uudecode -p")
     (uu  "uuencode xxx" tramp-uudecode)
-    (pack
-     "perl -e 'binmode STDIN; binmode STDOUT; print pack(q{u*}, join q{}, <>)'"
-     "perl -e 'binmode STDIN; binmode STDOUT; print unpack(q{u*}, join q{}, <>)'"))
+    (pack tramp-perl-pack tramp-perl-unpack))
   "List of remote coding commands for inline transfer.
 Each item is a list that looks like this:
 
@@ -4128,7 +4079,7 @@ INPUT can also be nil which means `/dev/null'.
 OUTPUT can be a string (which specifies a filename), or t (which
 means standard output and thus the current buffer), or nil (which
 means discard it)."
-  (tramp-compat-call-process
+  (tramp-call-process
    tramp-encoding-shell
    (when (and input (not (string-match "%s" cmd))) input)
    (if (eq output t) t nil)
@@ -4136,7 +4087,7 @@ means discard it)."
    tramp-encoding-command-switch
    (concat
     (if (string-match "%s" cmd) (format cmd input) cmd)
-    (if (stringp output) (concat "" output) ""))))
+    (if (stringp output) (concat " >" output) ""))))
 
 (defconst tramp-inline-compress-commands
   '(("gzip" "gzip -d")
@@ -4165,7 +4116,7 @@ Goes through the list `tramp-inline-compress-commands'."
                decompress (nth 1 item))
          (tramp-message
           vec 5
-          "Checking local compress command `%s', `%s' for sanity"
+          "Checking local compress commands `%s', `%s' for sanity"
           compress decompress)
          (unless
              (zerop
@@ -4181,7 +4132,7 @@ Goes through the list `tramp-inline-compress-commands'."
            (throw 'next nil))
          (tramp-message
           vec 5
-          "Checking remote compress command `%s', `%s' for sanity"
+          "Checking remote compress commands `%s', `%s' for sanity"
           compress decompress)
          (unless (tramp-send-command-and-check
                   vec (format "echo %s | %s | %s" magic compress decompress) t)
@@ -4261,15 +4212,16 @@ Gateway hops are already opened."
                  ?h (or (tramp-file-name-host (car target-alist)) ""))))
          (with-parsed-tramp-file-name proxy l
            ;; Add the hop.
-           (add-to-list 'target-alist l)
+           (push l target-alist)
            ;; Start next search.
            (setq choices tramp-default-proxies-alist)))))
 
     ;; Handle gateways.
-    (when (string-match
-          (format
-           "^\\(%s\\|%s\\)$" tramp-gw-tunnel-method tramp-gw-socks-method)
-          (tramp-file-name-method (car target-alist)))
+    (when (and (boundp 'tramp-gw-tunnel-method) (boundp 'tramp-gw-socks-method)
+              (string-match
+               (format
+                "^\\(%s\\|%s\\)$" tramp-gw-tunnel-method tramp-gw-socks-method)
+               (tramp-file-name-method (car target-alist))))
       (let ((gw (pop target-alist))
            (hop (pop target-alist)))
        ;; Is the method prepared for gateways?
@@ -4278,11 +4230,11 @@ Gateway hops are already opened."
           vec 'file-error
           "Connection `%s' is not supported for gateway access." hop))
        ;; Open the gateway connection.
-       (add-to-list
-        'target-alist
+       (push
         (vector
          (tramp-file-name-method hop) (tramp-file-name-user hop)
-         (tramp-compat-funcall 'tramp-gw-open-connection vec gw hop) nil nil))
+         (tramp-compat-funcall 'tramp-gw-open-connection vec gw hop) nil nil)
+        target-alist)
        ;; For the password prompt, we need the correct values.
        ;; Therefore, we must remember the gateway vector.  But we
        ;; cannot do it as connection property, because it shouldn't
@@ -4330,75 +4282,74 @@ Gateway hops are already opened."
     ;; Result.
     target-alist))
 
-(defvar tramp-current-connection nil
-  "Last connection timestamp.")
-
 (defun tramp-maybe-open-connection (vec)
   "Maybe open a connection VEC.
 Does not do anything if a connection is already open, but re-opens the
 connection if a previous connection has died for some reason."
-  (catch 'uname-changed
-    (let ((p (tramp-get-connection-process vec))
-         (process-name (tramp-get-connection-property vec "process-name" nil))
-         (process-environment (copy-sequence process-environment))
-         (pos (with-current-buffer (tramp-get-connection-buffer vec) (point))))
-
-      ;; If Tramp opens the same connection within a short time frame,
-      ;; there is a problem.  We shall signal this.
-      (unless (or (and p (processp p) (memq (process-status p) '(run open)))
-                 (not (equal (butlast (append vec nil))
-                             (car tramp-current-connection)))
-                 (> (tramp-time-diff
-                     (current-time) (cdr tramp-current-connection))
-                    5))
-       (throw 'suppress 'suppress))
-
-      ;; If too much time has passed since last command was sent, look
-      ;; whether process is still alive.  If it isn't, kill it.  When
-      ;; using ssh, it can sometimes happen that the remote end has
-      ;; hung up but the local ssh client doesn't recognize this until
-      ;; it tries to send some data to the remote end.  So that's why
-      ;; we try to send a command from time to time, then look again
-      ;; whether the process is really alive.
-      (condition-case nil
-         (when (and (> (tramp-time-diff
-                        (current-time)
-                        (tramp-get-connection-property
-                         p "last-cmd-time" '(0 0 0)))
-                       60)
-                    p (processp p) (memq (process-status p) '(run open)))
-           (tramp-send-command vec "echo are you awake" t t)
-           (unless (and (memq (process-status p) '(run open))
-                        (tramp-wait-for-output p 10))
-             ;; The error will be caught locally.
-             (tramp-error vec 'file-error "Awake did fail")))
-       (file-error
-        (tramp-cleanup vec)
-        (setq p nil)))
-
-      ;; New connection must be opened.
-      (condition-case err
-         (unless (and p (processp p) (memq (process-status p) '(run open)))
-
-           ;; We call `tramp-get-buffer' in order to get a debug
-           ;; buffer for messages from the beginning.
-           (tramp-get-buffer vec)
-
-           ;; If `non-essential' is non-nil, don't reopen a new connection.
-           (when (and (boundp 'non-essential) (symbol-value 'non-essential))
-             (throw 'non-essential 'non-essential))
-
-           (with-tramp-progress-reporter
-               vec 3
-               (if (zerop (length (tramp-file-name-user vec)))
-                   (format "Opening connection for %s using %s"
-                           (tramp-file-name-host vec)
-                           (tramp-file-name-method vec))
-                 (format "Opening connection for %s@%s using %s"
-                         (tramp-file-name-user vec)
+  (tramp-check-proper-method-and-host vec)
+
+  (let ((p (tramp-get-connection-process vec))
+       (process-name (tramp-get-connection-property vec "process-name" nil))
+       (process-environment (copy-sequence process-environment))
+       (pos (with-current-buffer (tramp-get-connection-buffer vec) (point))))
+
+    ;; If Tramp opens the same connection within a short time frame,
+    ;; there is a problem.  We shall signal this.
+    (unless (or (and p (processp p) (memq (process-status p) '(run open)))
+               (not (equal (butlast (append vec nil) 2)
+                           (car tramp-current-connection)))
+               (> (tramp-time-diff
+                   (current-time) (cdr tramp-current-connection))
+                  (or tramp-connection-min-time-diff 0)))
+      (throw 'suppress 'suppress))
+
+    ;; If too much time has passed since last command was sent, look
+    ;; whether process is still alive.  If it isn't, kill it.  When
+    ;; using ssh, it can sometimes happen that the remote end has hung
+    ;; up but the local ssh client doesn't recognize this until it
+    ;; tries to send some data to the remote end.  So that's why we
+    ;; try to send a command from time to time, then look again
+    ;; whether the process is really alive.
+    (condition-case nil
+       (when (and (> (tramp-time-diff
+                      (current-time)
+                      (tramp-get-connection-property
+                       p "last-cmd-time" '(0 0 0)))
+                     60)
+                  p (processp p) (memq (process-status p) '(run open)))
+         (tramp-send-command vec "echo are you awake" t t)
+         (unless (and (memq (process-status p) '(run open))
+                      (tramp-wait-for-output p 10))
+           ;; The error will be caught locally.
+           (tramp-error vec 'file-error "Awake did fail")))
+      (file-error
+       (tramp-cleanup-connection vec t)
+       (setq p nil)))
+
+    ;; New connection must be opened.
+    (condition-case err
+       (unless (and p (processp p) (memq (process-status p) '(run open)))
+
+         ;; We call `tramp-get-buffer' in order to get a debug buffer
+         ;; for messages from the beginning.
+         (tramp-get-buffer vec)
+
+         ;; If `non-essential' is non-nil, don't reopen a new connection.
+         (when (and (boundp 'non-essential) (symbol-value 'non-essential))
+           (throw 'non-essential 'non-essential))
+
+         (with-tramp-progress-reporter
+             vec 3
+             (if (zerop (length (tramp-file-name-user vec)))
+                 (format "Opening connection for %s using %s"
                          (tramp-file-name-host vec)
-                         (tramp-file-name-method vec)))
+                         (tramp-file-name-method vec))
+               (format "Opening connection for %s@%s using %s"
+                       (tramp-file-name-user vec)
+                       (tramp-file-name-host vec)
+                       (tramp-file-name-method vec)))
 
+           (catch 'uname-changed
              ;; Start new process.
              (when (and p (processp p))
                (delete-process p))
@@ -4407,6 +4358,10 @@ connection if a previous connection has died for some reason."
              (setenv "PROMPT_COMMAND")
              (setenv "PS1" tramp-initial-end-of-output)
              (let* ((target-alist (tramp-compute-multi-hops vec))
+                    ;; We will apply `tramp-ssh-controlmaster-options'
+                    ;; only for the first hop.
+                    (options (if tramp-use-ssh-controlmaster-options
+                                 tramp-ssh-controlmaster-options ""))
                     (process-connection-type tramp-process-connection-type)
                     (process-adaptive-read-buffering nil)
                     (coding-system-for-read nil)
@@ -4428,7 +4383,7 @@ connection if a previous connection has died for some reason."
                (set-process-sentinel p 'tramp-process-sentinel)
                (tramp-compat-set-process-query-on-exit-flag p nil)
                (setq tramp-current-connection
-                     (cons (butlast (append vec nil)) (current-time))
+                     (cons (butlast (append vec nil) 2) (current-time))
                      tramp-current-host (system-name))
 
                (tramp-message
@@ -4436,8 +4391,8 @@ connection if a previous connection has died for some reason."
 
                ;; Check whether process is alive.
                (tramp-barf-if-no-shell-prompt
-                p 60
-                "Couldn't find local shell prompt %s" tramp-encoding-shell)
+                p 10
+                "Couldn't find local shell prompt for %s" tramp-encoding-shell)
 
                ;; Now do all the connections as specified.
                (while target-alist
@@ -4455,6 +4410,9 @@ connection if a previous connection has died for some reason."
                         (async-args
                          (tramp-get-method-parameter
                           l-method 'tramp-async-args))
+                        (connection-timeout
+                         (tramp-get-method-parameter
+                          l-method 'tramp-connection-timeout))
                         (gw-args
                          (tramp-get-method-parameter l-method 'tramp-gw-args))
                         (gw (tramp-get-file-property hop "" "gateway" nil))
@@ -4468,14 +4426,16 @@ connection if a previous connection has died for some reason."
                         ;; temporary file has another name, and it is
                         ;; created and protected by ssh.  It is also
                         ;; removed by ssh when the connection is
-                        ;; closed.
+                        ;; closed.  The temporary file name is cached
+                        ;; in the main connection process, therefore
+                        ;; we cannot use `tramp-get-connection-process'.
                         (tmpfile
-                         (tramp-set-connection-property
-                          p "temp-file"
-                          (make-temp-name
-                           (expand-file-name
-                            tramp-temp-name-prefix
-                            (tramp-compat-temporary-file-directory)))))
+                         (with-tramp-connection-property
+                             (get-process (tramp-buffer-name vec)) "temp-file"
+                           (make-temp-name
+                            (expand-file-name
+                             tramp-temp-name-prefix
+                             (tramp-compat-temporary-file-directory)))))
                         spec r-shell)
 
                    ;; Add arguments for asynchronous processes.
@@ -4509,8 +4469,10 @@ connection if a previous connection has died for some reason."
                     l-host (or l-host "")
                     l-user (or l-user "")
                     l-port (or l-port "")
+                    spec (format-spec-make ?t tmpfile)
+                    options (format-spec options spec)
                     spec (format-spec-make
-                          ?h l-host ?u l-user ?p l-port ?t tmpfile)
+                          ?h l-host ?u l-user ?p l-port ?c options)
                     command
                     (concat
                      ;; We do not want to see the trailing local
@@ -4533,20 +4495,22 @@ connection if a previous connection has died for some reason."
                    (tramp-message vec 3 "Sending command `%s'" command)
                    (tramp-send-command vec command t t)
                    (tramp-process-actions
-                    p vec pos tramp-actions-before-shell 60)
+                    p vec pos tramp-actions-before-shell
+                    (or connection-timeout tramp-connection-timeout))
                    (tramp-message
                     vec 3 "Found remote shell prompt on `%s'" l-host))
                  ;; Next hop.
-                 (setq target-alist (cdr target-alist)))
+                 (setq options ""
+                       target-alist (cdr target-alist)))
 
                ;; Make initial shell settings.
-               (tramp-open-connection-setup-interactive-shell p vec))))
+               (tramp-open-connection-setup-interactive-shell p vec)))))
 
-       ;; When the user did interrupt, we must cleanup.
-       (quit
-        (tramp-cleanup vec)
-        ;; Propagate the quit signal.
-        (signal (car err) (cdr err)))))))
+      ;; When the user did interrupt, we must cleanup.
+      (quit
+       (tramp-cleanup-connection vec t)
+       ;; Propagate the quit signal.
+       (signal (car err) (cdr err))))))
 
 (defun tramp-send-command (vec command &optional neveropen nooutput)
   "Send the COMMAND to connection VEC.
@@ -4560,6 +4524,9 @@ 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)))
+    ;; Some busyboxes tend to close the connection when we use the
+    ;; following syntax for here-documents.  This we cannot test; it
+    ;; shall be set via `tramp-connection-properties'.
     (when (and (string-match "<<'EOF'" command)
               (not (tramp-get-connection-property vec "busybox" nil)))
       ;; Unset $PS1 when using here documents, in order to avoid
@@ -4739,76 +4706,6 @@ Return ATTR."
             (tramp-get-device vec))
     attr))
 
-(defun tramp-check-cached-permissions (vec access)
-  "Check `file-attributes' caches for VEC.
-Return t if according to the cache access type ACCESS is known to
-be granted."
-  (let ((result nil)
-        (offset (cond
-                 ((eq ?r access) 1)
-                 ((eq ?w access) 2)
-                 ((eq ?x access) 3))))
-    (dolist (suffix '("string" "integer") result)
-      (setq
-       result
-       (or
-        result
-        (let ((file-attr
-               (tramp-get-file-property
-                vec (tramp-file-name-localname vec)
-                (concat "file-attributes-" suffix) nil))
-              (remote-uid
-               (tramp-get-connection-property
-                vec (concat "uid-" suffix) nil))
-              (remote-gid
-               (tramp-get-connection-property
-                vec (concat "gid-" suffix) nil)))
-          (and
-           file-attr
-           (or
-            ;; Not a symlink
-            (eq t (car file-attr))
-            (null (car file-attr)))
-           (or
-            ;; World accessible.
-            (eq access (aref (nth 8 file-attr) (+ offset 6)))
-            ;; User accessible and owned by user.
-            (and
-             (eq access (aref (nth 8 file-attr) offset))
-             (equal remote-uid (nth 2 file-attr)))
-            ;; Group accessible and owned by user's
-            ;; principal group.
-            (and
-             (eq access (aref (nth 8 file-attr) (+ offset 3)))
-             (equal remote-gid (nth 3 file-attr)))))))))))
-
-(defun tramp-file-mode-from-int (mode)
-  "Turn an integer representing a file mode into an ls(1)-like string."
-  (let ((type  (cdr
-                (assoc (logand (lsh mode -12) 15) tramp-file-mode-type-map)))
-       (user   (logand (lsh mode -6) 7))
-       (group  (logand (lsh mode -3) 7))
-       (other  (logand (lsh mode -0) 7))
-       (suid   (> (logand (lsh mode -9) 4) 0))
-       (sgid   (> (logand (lsh mode -9) 2) 0))
-       (sticky (> (logand (lsh mode -9) 1) 0)))
-    (setq user  (tramp-file-mode-permissions user  suid "s"))
-    (setq group (tramp-file-mode-permissions group sgid "s"))
-    (setq other (tramp-file-mode-permissions other sticky "t"))
-    (concat type user group other)))
-
-(defun tramp-file-mode-permissions (perm suid suid-text)
-  "Convert a permission bitset into a string.
-This is used internally by `tramp-file-mode-from-int'."
-  (let ((r (> (logand perm 4) 0))
-       (w (> (logand perm 2) 0))
-       (x (> (logand perm 1) 0)))
-    (concat (or (and r "r") "-")
-           (or (and w "w") "-")
-           (or (and suid x suid-text)  ; suid, execute
-               (and suid (upcase suid-text)) ; suid, !execute
-               (and x "x") "-"))))     ; !suid
-
 (defun tramp-shell-case-fold (string)
   "Converts STRING to shell glob pattern which ignores case."
   (mapconcat
@@ -5039,6 +4936,17 @@ This is used internally by `tramp-file-mode-from-int'."
     (tramp-message vec 5 "Finding a suitable `trash' command")
     (tramp-find-executable vec "trash" (tramp-get-remote-path vec))))
 
+(defun tramp-get-remote-gvfs-monitor-dir (vec)
+  (with-tramp-connection-property vec "gvfs-monitor-dir"
+    (tramp-message vec 5 "Finding a suitable `gvfs-monitor-dir' command")
+    (tramp-find-executable
+     vec "gvfs-monitor-dir" (tramp-get-remote-path vec) t t)))
+
+(defun tramp-get-remote-inotifywait (vec)
+  (with-tramp-connection-property vec "inotifywait"
+    (tramp-message vec 5 "Finding a suitable `inotifywait' command")
+    (tramp-find-executable vec "inotifywait" (tramp-get-remote-path vec) t t)))
+
 (defun tramp-get-remote-id (vec)
   (with-tramp-connection-property vec "id"
     (tramp-message vec 5 "Finding POSIX `id' command")
@@ -5077,14 +4985,6 @@ This is used internally by `tramp-file-mode-from-int'."
       ;; The command might not always return a number.
       (if (and (equal id-format 'integer) (not (integerp res))) -1 res))))
 
-(defun tramp-get-local-uid (id-format)
-  (if (equal id-format 'integer) (user-uid) (user-login-name)))
-
-(defun tramp-get-local-gid (id-format)
-  (if (and (fboundp 'group-gid) (equal id-format 'integer))
-      (tramp-compat-funcall 'group-gid)
-    (nth 3 (tramp-compat-file-attributes "~/" id-format))))
-
 ;; Some predefined connection properties.
 (defun tramp-get-inline-compress (vec prop size)
   "Return the compress command related to PROP.
@@ -5161,10 +5061,12 @@ function cell is returned to be applied on a buffer."
           ;; 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)")
+          (cond
+           ((and (string-match "local" prop)
+                 (memq system-type '(windows-nt)))
+              "(%s | \"%s\")")
+           ((string-match "local" prop) "(%s | %s)")
+           (t "(%s | %s >%%s)"))
           coding compress))
         (compress
          (format
@@ -5177,7 +5079,9 @@ function cell is returned to be applied on a buffer."
             "(%s <%%s | %s)")
           compress coding))
         ((string-match "decoding" prop)
-         (format "%s >%%s" coding))
+         (cond
+          ((string-match "local" prop) (format "%s" coding))
+          (t (format "%s >%%s" coding))))
         (t
          (format "%s <%%s" coding)))))))