]> code.delx.au - gnu-emacs/blobdiff - lisp/net/tramp-sh.el
* tramp-sh.el (tramp-sh-handle-file-acl): Do not redirect stderr
[gnu-emacs] / lisp / net / tramp-sh.el
index b82b4deb21a1df298a8da5017a1a2d9bf29af1dc..7f7558e93b5935cf45a1e4756c454fd47a5ec5c9 100644 (file)
@@ -67,7 +67,7 @@ files conditionalize this setup based on the TERM environment variable."
   :type 'string)
 
 ;;;###tramp-autoload
-(defcustom tramp-histfile-override t
+(defcustom tramp-histfile-override ".tramp_history"
   "When invoking a shell, override the HISTFILE with this value.
 When setting to a string, it redirects the shell history to that
 file.  Be careful when setting to \"/dev/null\"; this might
@@ -135,6 +135,7 @@ The string is used in `tramp-methods'.")
     (tramp-login-program        "rsh")
     (tramp-login-args           (("%h") ("-l" "%u")))
     (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-login   ("-l"))
     (tramp-remote-shell-args    ("-c"))
     (tramp-copy-program         "rcp")
     (tramp-copy-args            (("-p" "%k") ("-r")))
@@ -146,6 +147,7 @@ The string is used in `tramp-methods'.")
     (tramp-login-program        "remsh")
     (tramp-login-args           (("%h") ("-l" "%u")))
     (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-login   ("-l"))
     (tramp-remote-shell-args    ("-c"))
     (tramp-copy-program         "rcp")
     (tramp-copy-args            (("-p" "%k")))
@@ -158,6 +160,7 @@ The string is used in `tramp-methods'.")
                                 ("-e" "none") ("%h")))
     (tramp-async-args           (("-q")))
     (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-login   ("-l"))
     (tramp-remote-shell-args    ("-c"))
     (tramp-copy-program         "scp")
     (tramp-copy-args            (("-P" "%p") ("-p" "%k") ("-q") ("-r") ("%c")))
@@ -175,6 +178,7 @@ The string is used in `tramp-methods'.")
                                 ("-e" "none") ("-t" "-t") ("%h") ("/bin/sh")))
     (tramp-async-args           (("-q")))
     (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-login   ("-l"))
     (tramp-remote-shell-args    ("-c"))
     (tramp-copy-program         "scp")
     (tramp-copy-args            (("-P" "%p") ("-p" "%k")
@@ -193,6 +197,7 @@ The string is used in `tramp-methods'.")
                                 ("-e" "none") ("%h")))
     (tramp-async-args           (("-q")))
     (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-login   ("-l"))
     (tramp-remote-shell-args    ("-c"))
     (tramp-copy-program         "rsync")
     (tramp-copy-args            (("-t" "%k") ("-r")))
@@ -206,6 +211,7 @@ The string is used in `tramp-methods'.")
     (tramp-login-program        "rsh")
     (tramp-login-args           (("%h") ("-l" "%u")))
     (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-login   ("-l"))
     (tramp-remote-shell-args    ("-c"))))
 ;;;###tramp-autoload
 (add-to-list 'tramp-methods
@@ -213,6 +219,7 @@ The string is used in `tramp-methods'.")
     (tramp-login-program        "remsh")
     (tramp-login-args           (("%h") ("-l" "%u")))
     (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-login   ("-l"))
     (tramp-remote-shell-args    ("-c"))))
 ;;;###tramp-autoload
 (add-to-list 'tramp-methods
@@ -222,6 +229,7 @@ The string is used in `tramp-methods'.")
                                 ("-e" "none") ("%h")))
     (tramp-async-args           (("-q")))
     (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-login   ("-l"))
     (tramp-remote-shell-args    ("-c"))
     (tramp-gw-args              (("-o" "GlobalKnownHostsFile=/dev/null")
                                 ("-o" "UserKnownHostsFile=/dev/null")
@@ -235,6 +243,7 @@ The string is used in `tramp-methods'.")
                                 ("-e" "none") ("-t" "-t") ("%h") ("/bin/sh")))
     (tramp-async-args           (("-q")))
     (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-login   ("-l"))
     (tramp-remote-shell-args    ("-c"))
     (tramp-gw-args              (("-o" "GlobalKnownHostsFile=/dev/null")
                                 ("-o" "UserKnownHostsFile=/dev/null")
@@ -246,6 +255,7 @@ The string is used in `tramp-methods'.")
     (tramp-login-program        "telnet")
     (tramp-login-args           (("%h") ("%p") ("2>/dev/null")))
     (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-login   ("-l"))
     (tramp-remote-shell-args    ("-c"))
     (tramp-default-port         23)))
 ;;;###tramp-autoload
@@ -254,6 +264,7 @@ The string is used in `tramp-methods'.")
     (tramp-login-program        "telnet")
     (tramp-login-args           (("%h") ("%p") ("2>/dev/null")))
     (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-login   ("-l"))
     (tramp-remote-shell-args    ("-c"))
     (tramp-copy-program         "nc")
     ;; We use "-v" for better error tracking.
@@ -262,7 +273,7 @@ The string is used in `tramp-methods'.")
     ;; We use "-p" as required for newer busyboxes.  For older
     ;; busybox/nc versions, the value must be (("-l") ("%r")).  This
     ;; can be achieved by tweaking `tramp-connection-properties'.
-    (tramp-remote-copy-args     (("-l") ("-p" "%r")))
+    (tramp-remote-copy-args     (("-l") ("-p" "%r") ("2>/dev/null")))
     (tramp-default-port         23)))
 ;;;###tramp-autoload
 (add-to-list 'tramp-methods
@@ -270,6 +281,7 @@ The string is used in `tramp-methods'.")
     (tramp-login-program        "su")
     (tramp-login-args           (("-") ("%u")))
     (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-login   ("-l"))
     (tramp-remote-shell-args    ("-c"))
     (tramp-connection-timeout   10)))
 ;;;###tramp-autoload
@@ -280,6 +292,7 @@ The string is used in `tramp-methods'.")
     ;; Local $SHELL could be a nasty one, like zsh or fish.  Let's override it.
     (tramp-login-env            (("SHELL") ("/bin/sh")))
     (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-login   ("-l"))
     (tramp-remote-shell-args    ("-c"))
     (tramp-connection-timeout   10)))
 ;;;###tramp-autoload
@@ -288,6 +301,7 @@ The string is used in `tramp-methods'.")
     (tramp-login-program        "ksu")
     (tramp-login-args           (("%u") ("-q")))
     (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-login   ("-l"))
     (tramp-remote-shell-args    ("-c"))
     (tramp-connection-timeout   10)))
 ;;;###tramp-autoload
@@ -296,6 +310,7 @@ The string is used in `tramp-methods'.")
     (tramp-login-program        "krlogin")
     (tramp-login-args           (("%h") ("-l" "%u") ("-x")))
     (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-login   ("-l"))
     (tramp-remote-shell-args    ("-c"))))
 ;;;###tramp-autoload
 (add-to-list 'tramp-methods
@@ -310,6 +325,7 @@ The string is used in `tramp-methods'.")
                                    tramp-initial-end-of-output))
                                 ("/bin/sh") ("\"")))
     (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-login   ("-l"))
     (tramp-remote-shell-args    ("-c"))
     (tramp-default-port         22)))
 ;;;###tramp-autoload
@@ -323,6 +339,7 @@ The string is used in `tramp-methods'.")
                                    tramp-initial-end-of-output))
                                 ("/bin/sh") ("\"")))
     (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-login   ("-l"))
     (tramp-remote-shell-args    ("-c"))))
 ;;;###tramp-autoload
 (add-to-list 'tramp-methods
@@ -336,6 +353,7 @@ The string is used in `tramp-methods'.")
                                    tramp-initial-end-of-output))
                                 ("/bin/sh") ("\"")))
     (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-login   ("-l"))
     (tramp-remote-shell-args    ("-c"))
     (tramp-copy-program         "pscp")
     (tramp-copy-args            (("-l" "%u") ("-P" "%p") ("-scp") ("-p" "%k")
@@ -355,6 +373,7 @@ The string is used in `tramp-methods'.")
                                    tramp-initial-end-of-output))
                                 ("/bin/sh") ("\"")))
     (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-login   ("-l"))
     (tramp-remote-shell-args    ("-c"))
     (tramp-copy-program         "pscp")
     (tramp-copy-args            (("-l" "%u") ("-P" "%p") ("-sftp") ("-p" "%k")
@@ -367,6 +386,7 @@ The string is used in `tramp-methods'.")
     (tramp-login-program        "fsh")
     (tramp-login-args           (("%h") ("-l" "%u") ("sh" "-i")))
     (tramp-remote-shell         "/bin/sh")
+    (tramp-remote-shell-login   ("-l"))
     (tramp-remote-shell-args    ("-i") ("-c"))
     (tramp-copy-program         "fcp")
     (tramp-copy-args            (("-p" "%k")))
@@ -496,7 +516,6 @@ as given in your `~/.profile'."
 (defcustom tramp-remote-process-environment
   `("TMOUT=0" "LC_CTYPE=''"
     ,(format "TERM=%s" tramp-terminal-type)
-    "EMACS=t" ;; Deprecated.
     ,(format "INSIDE_EMACS='%s,tramp:%s'" emacs-version tramp-version)
     "CDPATH=" "HISTORY=" "MAIL=" "MAILCHECK=" "MAILPATH=" "PAGER=cat"
     "autocorrect=" "correct=")
@@ -1175,15 +1194,19 @@ target of the symlink differ."
     (tramp-message vec 5 "file attributes with ls: %s" localname)
     (tramp-send-command
      vec
-     (format "(%s %s || %s -h %s) && %s %s %s"
+     (format "(%s %s || %s -h %s) && %s %s %s %s"
             (tramp-get-file-exists-command vec)
             (tramp-shell-quote-argument localname)
             (tramp-get-test-command vec)
             (tramp-shell-quote-argument localname)
             (tramp-get-ls-command vec)
+            ;; On systems which have no quoting style, file names
+            ;; with special characters could fail.
+            (if (tramp-get-ls-command-with-quoting-style vec)
+                "--quoting-style=c" "")
             (if (eq id-format 'integer) "-ildn" "-ild")
             (tramp-shell-quote-argument localname)))
-    ;; parse `ls -l' output ...
+    ;; Parse `ls -l' output ...
     (with-current-buffer (tramp-get-buffer vec)
       (when (> (buffer-size) 0)
         (goto-char (point-min))
@@ -1222,11 +1245,14 @@ target of the symlink differ."
         ;; From the file modes, figure out other stuff.
         (setq symlinkp (eq ?l (aref res-filemodes 0)))
         (setq dirp (eq ?d (aref res-filemodes 0)))
-        ;; if symlink, find out file name pointed to
+        ;; If symlink, find out file name pointed to.
         (when symlinkp
           (search-forward "-> ")
-          (setq res-symlink-target (buffer-substring (point) (point-at-eol))))
-        ;; return data gathered
+          (setq res-symlink-target
+               (if (tramp-get-ls-command-with-quoting-style vec)
+                   (read (current-buffer))
+                 (buffer-substring (point) (point-at-eol)))))
+        ;; Return data gathered.
         (list
          ;; 0. t for directory, string (name linked to) for symbolic
          ;; link, or nil.
@@ -1249,9 +1275,9 @@ target of the symlink differ."
          ;; 8. File modes, as a string of ten letters or dashes as in ls -l.
          res-filemodes
          ;; 9. t if file's gid would change if file were deleted and
-         ;; recreated.  Will be set in `tramp-convert-file-attributes'
+         ;; recreated.  Will be set in `tramp-convert-file-attributes'.
          t
-         ;; 10. inode number.
+         ;; 10. Inode number.
          res-inode
          ;; 11. Device number.  Will be replaced by a virtual device number.
          -1
@@ -1275,16 +1301,21 @@ target of the symlink differ."
   (tramp-send-command-and-read
    vec
    (format
-    ;; On Opsware, pdksh (which is the true name of ksh there) doesn't
-    ;; parse correctly the sequence "((".  Therefore, we add a space.
-    "( (%s %s || %s -h %s) && %s -c '((\"%%N\") %%h %s %s %%Xe0 %%Ye0 %%Ze0 %%se0 \"%%A\" t %%ie0 -1)' \"%s\" || echo nil)"
+    (concat
+     ;; On Opsware, pdksh (which is the true name of ksh there)
+     ;; doesn't parse correctly the sequence "((".  Therefore, we add
+     ;; a space.  Apostrophes in the stat output are masked as "//",
+     ;; in order to make a proper shell escape of them in file names.
+     "( (%s %s || %s -h %s) && (%s -c "
+     "'((//%%N//) %%h %s %s %%Xe0 %%Ye0 %%Ze0 %%se0 //%%A// t %%ie0 -1)' "
+     "%s | sed -e 's/\"/\\\\\"/g' -e 's/\\/\\//\"/g') || echo nil)")
     (tramp-get-file-exists-command vec)
     (tramp-shell-quote-argument localname)
     (tramp-get-test-command vec)
     (tramp-shell-quote-argument localname)
     (tramp-get-remote-stat vec)
-    (if (eq id-format 'integer) "%ue0" "\"%U\"")
-    (if (eq id-format 'integer) "%ge0" "\"%G\"")
+    (if (eq id-format 'integer) "%ue0" "//%U//")
+    (if (eq id-format 'integer) "%ge0" "//%G//")
     (tramp-shell-quote-argument localname))))
 
 (defun tramp-sh-handle-set-visited-file-modtime (&optional time-list)
@@ -1376,6 +1407,7 @@ of."
 (defun tramp-sh-handle-set-file-modes (filename mode)
   "Like `set-file-modes' for Tramp files."
   (with-parsed-tramp-file-name filename nil
+    (tramp-flush-file-property v (file-name-directory localname))
     (tramp-flush-file-property v localname)
     ;; FIXME: extract the proper text from chmod's stderr.
     (tramp-barf-unless-okay
@@ -1390,6 +1422,7 @@ of."
   (if (tramp-tramp-file-p filename)
       (with-parsed-tramp-file-name filename nil
        (when (tramp-get-remote-touch v)
+         (tramp-flush-file-property v (file-name-directory localname))
          (tramp-flush-file-property v localname)
          (let ((time (if (or (null time) (equal time '(0 0)))
                          (current-time)
@@ -1448,12 +1481,14 @@ be non-negative integers."
                  (tramp-shell-quote-argument localname))))))
 
       ;; We handle also the local part, because there doesn't exist
-      ;; `set-file-uid-gid'.  On W32 "chown" might not work.
-      (let ((uid (or (and (natnump uid) uid) (tramp-get-local-uid 'integer)))
-           (gid (or (and (natnump gid) gid) (tramp-get-local-gid 'integer))))
-       (tramp-call-process
-        nil "chown" nil nil nil
-         (format "%d:%d" uid gid) (tramp-shell-quote-argument filename))))))
+      ;; `set-file-uid-gid'.  On W32 "chown" might not work.  We add a
+      ;; timeout for this.
+      (with-timeout (5 nil)
+       (let ((uid (or (and (natnump uid) uid) (tramp-get-local-uid 'integer)))
+             (gid (or (and (natnump gid) gid) (tramp-get-local-gid 'integer))))
+         (tramp-call-process
+          nil "chown" nil nil nil
+          (format "%d:%d" uid gid) (tramp-shell-quote-argument filename)))))))
 
 (defun tramp-remote-selinux-p (vec)
   "Check, whether SELINUX is enabled on the remote host."
@@ -1522,7 +1557,7 @@ be non-negative integers."
       (when (and (tramp-remote-acl-p v)
                 (tramp-send-command-and-check
                  v (format
-                    "getfacl -ac %s 2>/dev/null"
+                    "getfacl -ac %s"
                     (tramp-shell-quote-argument localname))))
        (with-current-buffer (tramp-get-connection-buffer v)
          (goto-char (point-max))
@@ -1547,7 +1582,7 @@ be non-negative integers."
        (progn
          (tramp-set-file-property v localname "file-acl" acl-string)
          t)
-      ;; In case of errors, we return `nil'.
+      ;; In case of errors, we return nil.
       (tramp-set-file-property v localname "file-acl-string" 'undef)
       nil)))
 
@@ -1717,14 +1752,13 @@ be non-negative integers."
     (concat
      ;; We must care about file names with spaces, or starting with
      ;; "-"; this would confuse xargs.  "ls -aQ" might be a solution,
-     ;; but it does not work on all remote systems.  Therefore, we
-     ;; use \000 as file separator.
-     ;; Apostrophes in the stat output are masked as ?/ characters, in
-     ;; order to make a proper shell escape of them in file names.
+     ;; but it does not work on all remote systems.  Apostrophes in
+     ;; the stat output are masked as "//", in order to make a proper
+     ;; shell escape of them in file names.
      "cd %s && echo \"(\"; (%s %s -a | "
      "xargs %s -c "
-     "'(/%%n/ (/%%N/) %%h %s %s %%Xe0 %%Ye0 %%Ze0 %%se0 /%%A/ t %%ie0 -1)' "
-     "-- 2>/dev/null | sed -e 's/\"/\\\\\"/g' -e 's/\\//\"/g'); echo \")\"")
+     "'(//%%n// (//%%N//) %%h %s %s %%Xe0 %%Ye0 %%Ze0 %%se0 //%%A// t %%ie0 -1)' "
+     "-- 2>/dev/null | sed -e 's/\"/\\\\\"/g' -e 's/\\/\\//\"/g'); echo \")\"")
     (tramp-shell-quote-argument localname)
     (tramp-get-ls-command vec)
     ;; On systems which have no quoting style, file names with
@@ -1732,8 +1766,8 @@ be non-negative integers."
     (if (tramp-get-ls-command-with-quoting-style vec)
        "--quoting-style=shell" "")
     (tramp-get-remote-stat vec)
-    (if (eq id-format 'integer) "%ue0" "/%U/")
-    (if (eq id-format 'integer) "%ge0" "/%G/"))))
+    (if (eq id-format 'integer) "%ue0" "//%U//")
+    (if (eq id-format 'integer) "%ge0" "//%G//"))))
 
 ;; This function should return "foo/" for directories and "bar" for
 ;; files.
@@ -1945,7 +1979,7 @@ tramp-sh-handle-file-name-all-completions: internal error accessing `%s': `%s'"
        (t2 (tramp-tramp-file-p newname)))
     (with-parsed-tramp-file-name (if t1 dirname newname) nil
       (if (and (not copy-contents)
-              (tramp-get-method-parameter method 'tramp-copy-recursive)
+              (tramp-get-method-parameter v 'tramp-copy-recursive)
               ;; When DIRNAME and NEWNAME are remote, they must have
               ;; the same method.
               (or (null t1) (null t2)
@@ -2112,15 +2146,17 @@ FILENAME is the source file, NEWNAME the target file.
 KEEP-DATE is non-nil if NEWNAME should have the same timestamp as FILENAME."
   ;; We must disable multibyte, because binary data shall not be
   ;; converted.  We don't want the target file to be compressed, so we
-  ;; let-bind `jka-compr-inhibit' to t.
-  ;; We remove `tramp-file-name-handler' from
+  ;; let-bind `jka-compr-inhibit' to t.  `epa-file-handler' shall not
+  ;; be called either.  We remove `tramp-file-name-handler' from
   ;; `inhibit-file-name-handlers'; otherwise the file name handler for
   ;; `insert-file-contents' might be deactivated in some corner cases.
   (let ((coding-system-for-read 'binary)
        (coding-system-for-write 'binary)
        (jka-compr-inhibit t)
+       (inhibit-file-name-operation 'write-region)
        (inhibit-file-name-handlers
-        (remq 'tramp-file-name-handler inhibit-file-name-handlers)))
+        (cons 'epa-file-handler
+              (remq 'tramp-file-name-handler inhibit-file-name-handlers))))
     (with-temp-file newname
       (set-buffer-multibyte nil)
       (insert-file-contents-literally filename)))
@@ -2365,7 +2401,7 @@ The method used must be an out-of-band method."
                       (tramp-get-connection-property v "login-as" nil)))
 
        ;; Check for listener port.
-       (when (tramp-get-method-parameter method 'tramp-remote-copy-args)
+       (when (tramp-get-method-parameter v 'tramp-remote-copy-args)
          (setq listener (number-to-string (+ 50000 (random 10000))))
          (while
              (zerop (tramp-call-process v "nc" nil nil nil "-z" host listener))
@@ -2382,10 +2418,9 @@ The method used must be an out-of-band method."
              spec (format-spec-make
                    ?h host ?u user ?p port ?r listener ?c options
                    ?k (if keep-date " " ""))
-             copy-program (tramp-get-method-parameter
-                           method 'tramp-copy-program)
+             copy-program (tramp-get-method-parameter v 'tramp-copy-program)
              copy-keep-date (tramp-get-method-parameter
-                             method 'tramp-copy-keep-date)
+                             v 'tramp-copy-keep-date)
 
              copy-args
              (delete
@@ -2394,9 +2429,7 @@ The method used must be an out-of-band method."
               ;; for the whole keep-date sublist.
               " "
               (dolist
-                  (x
-                   (tramp-get-method-parameter method 'tramp-copy-args)
-                   copy-args)
+                  (x (tramp-get-method-parameter v 'tramp-copy-args) copy-args)
                 (setq copy-args
                       (append
                        copy-args
@@ -2410,16 +2443,12 @@ The method used must be an out-of-band method."
                (lambda (x)
                  (setq x (mapcar (lambda (y) (format-spec y spec)) x))
                  (unless (member "" x) (mapconcat 'identity x " ")))
-               (tramp-get-method-parameter method 'tramp-copy-env)))
+               (tramp-get-method-parameter v 'tramp-copy-env)))
 
              remote-copy-program
-             (tramp-get-method-parameter method 'tramp-remote-copy-program))
+             (tramp-get-method-parameter v 'tramp-remote-copy-program))
 
-       (dolist
-           (x
-            (or
-             (tramp-get-connection-property v "remote-copy-args" nil)
-             (tramp-get-method-parameter method 'tramp-remote-copy-args)))
+       (dolist (x (tramp-get-method-parameter v 'tramp-remote-copy-args))
          (setq remote-copy-args
                (append
                 remote-copy-args
@@ -2450,10 +2479,10 @@ The method used must be an out-of-band method."
                 " "))
          (tramp-send-command v remote-copy-program)
          (with-timeout
-             (1 (tramp-error
-                 v 'file-error
-                 "Listener process not running on remote host: `%s'"
-                 remote-copy-program))
+             (60 (tramp-error
+                  v 'file-error
+                  "Listener process not running on remote host: `%s'"
+                  remote-copy-program))
            (tramp-send-command v (format "netstat -l | grep -q :%s" listener))
            (while (not (tramp-send-command-and-check v nil))
              (tramp-send-command
@@ -2884,10 +2913,15 @@ the result will be a local, non-Tramp, file name."
                       (setq i (+ i 250))))
                   (cdr args)))
           ;; Use a human-friendly prompt, for example for `shell'.
-          (prompt (format "PS1=%s"
-                          (format "%s %s"
-                                  (file-remote-p default-directory)
-                                  tramp-initial-end-of-output)))
+          ;; We discard hops, if existing, that's why we cannot use
+          ;; `file-remote-p'.
+          (prompt (format "PS1=%s %s"
+                          (tramp-make-tramp-file-name
+                           (tramp-file-name-method v)
+                           (tramp-file-name-user v)
+                           (tramp-file-name-host v)
+                           (tramp-file-name-localname v))
+                          tramp-initial-end-of-output))
           ;; We use as environment the difference to toplevel
           ;; `process-environment'.
           env
@@ -3093,9 +3127,9 @@ the result will be a local, non-Tramp, file name."
       (when tmpinput (delete-file tmpinput))
 
       ;; `process-file-side-effects' has been introduced with GNU
-      ;; Emacs 23.2.  If set to `nil', no remote file will be changed
+      ;; Emacs 23.2.  If set to nil, no remote file will be changed
       ;; by `program'.  If it doesn't exist, we assume its default
-      ;; value `t'.
+      ;; value t.
       (unless (and (boundp 'process-file-side-effects)
                   (not (symbol-value 'process-file-side-effects)))
         (tramp-flush-directory-property v ""))
@@ -3195,7 +3229,8 @@ the result will be a local, non-Tramp, file name."
         (if (fboundp 'find-buffer-file-type)
             (symbol-function 'find-buffer-file-type)
           nil))
-       (inhibit-file-name-handlers '(jka-compr-handler image-file-handler))
+       (inhibit-file-name-handlers
+        '(epa-file-handler image-file-handler jka-compr-handler))
        (inhibit-file-name-operation 'insert-file-contents))
     (unwind-protect
        (progn
@@ -3318,8 +3353,7 @@ the result will be a local, non-Tramp, file name."
              (if (and (not (stringp start))
                       (= (or end (point-max)) (point-max))
                       (= (or start (point-min)) (point-min))
-                      (tramp-get-method-parameter
-                       method 'tramp-copy-keep-tmpfile))
+                      (tramp-get-method-parameter v 'tramp-copy-keep-tmpfile))
                  (progn
                    (setq tramp-temp-buffer-file-name tmpfile)
                    (condition-case err
@@ -3741,17 +3775,6 @@ Only send the definition if it has not already been done."
        (tramp-set-connection-property
         (tramp-get-connection-process vec) "scripts" (cons name scripts))))))
 
-(defun tramp-set-auto-save ()
-  (when (and ;; ange-ftp has its own auto-save mechanism
-            (eq (tramp-find-foreign-file-name-handler (buffer-file-name))
-                'tramp-sh-file-name-handler)
-             auto-save-default)
-    (auto-save-mode 1)))
-(add-hook 'find-file-hooks 'tramp-set-auto-save t)
-(add-hook 'tramp-unload-hook
-         (lambda ()
-           (remove-hook 'find-file-hooks 'tramp-set-auto-save)))
-
 (defun tramp-run-test (switch filename)
   "Run `test' on the remote system, given a SWITCH and a FILENAME.
 Returns the exit code of the `test' program."
@@ -3948,12 +3971,7 @@ file exists and nonzero exit status otherwise."
 (defun tramp-find-shell (vec)
   "Opens a shell on the remote host which groks tilde expansion."
   (with-current-buffer (tramp-get-buffer vec)
-    (let ((default-shell
-           (or
-            (tramp-get-connection-property
-             (tramp-get-connection-process vec) "remote-shell" nil)
-            (tramp-get-method-parameter
-             (tramp-file-name-method vec) 'tramp-remote-shell)))
+    (let ((default-shell (tramp-get-method-parameter vec 'tramp-remote-shell))
          shell)
       (setq shell
            (with-tramp-connection-property vec "remote-shell"
@@ -4012,15 +4030,11 @@ seconds.  If not, it produces an error message with the given ERROR-ARGS."
 Mainly sets the prompt and the echo correctly.  PROC is the shell
 process to set up.  VEC specifies the connection."
   (let ((tramp-end-of-output tramp-initial-end-of-output))
-    (tramp-open-shell
-     vec
-     (or (tramp-get-connection-property vec "remote-shell" nil)
-        (tramp-get-method-parameter
-         (tramp-file-name-method vec) 'tramp-remote-shell)))
+    (tramp-open-shell vec (tramp-get-method-parameter vec 'tramp-remote-shell))
 
-    ;; Disable echo.
+    ;; Disable tab and echo expansion.
     (tramp-message vec 5 "Setting up remote shell environment")
-    (tramp-send-command vec "stty -inlcr -echo kill '^U' erase '^H'" t)
+    (tramp-send-command vec "stty tab0 -inlcr -echo kill '^U' erase '^H'" t)
     ;; Check whether the echo has really been disabled.  Some
     ;; implementations, like busybox of embedded GNU/Linux, don't
     ;; support disabling.
@@ -4553,15 +4567,9 @@ Gateway hops are already opened."
     ;; Foreign and out-of-band methods are not supported for multi-hops.
     (when (cdr target-alist)
       (setq choices target-alist)
-      (while choices
-       (setq item (pop choices))
-       (when
-           (or
-            (not
-             (tramp-get-method-parameter
-              (tramp-file-name-method item) 'tramp-login-program))
-            (tramp-get-method-parameter
-             (tramp-file-name-method item) 'tramp-copy-program))
+      (while (setq item (pop choices))
+       (when (or (not (tramp-get-method-parameter item 'tramp-login-program))
+                 (tramp-get-method-parameter item 'tramp-copy-program))
          (tramp-error
           vec 'file-error
           "Method `%s' is not supported for multi-hops."
@@ -4578,8 +4586,7 @@ Gateway hops are already opened."
           ;; There are multi-hops.
           (cdr target-alist)
           ;; The host name is used for the remote shell command.
-          (member
-           '("%h") (tramp-get-method-parameter method 'tramp-login-args))
+          (member '("%h") (tramp-get-method-parameter v 'tramp-login-args))
           ;; The host is local.  We cannot use `tramp-local-host-p'
           ;; here, because it opens a connection as well.
           (string-match tramp-local-host-regexp host))
@@ -4596,8 +4603,7 @@ Gateway hops are already opened."
   (cond
    ;; No options to be computed.
    ((or (null tramp-use-ssh-controlmaster-options)
-       (null (assoc "%c" (tramp-get-method-parameter
-                          (tramp-file-name-method vec) 'tramp-login-args))))
+       (null (assoc "%c" (tramp-get-method-parameter vec 'tramp-login-args))))
     "")
 
    ;; There is already a value to be used.
@@ -4615,19 +4621,15 @@ Gateway hops are already opened."
                (setq tramp-ssh-controlmaster-options "-o ControlMaster=auto")))
            (unless (zerop (length tramp-ssh-controlmaster-options))
              (with-temp-buffer
-               ;; When we use a non-existing host name, we could run
-               ;; into DNS timeouts.  So we use "localhost" with an
-               ;; improper port, expecting nobody runs sshd on the
-               ;; telnet port.
+               ;; We use a non-existing IP address, in order to avoid
+               ;; useless connections, and DNS timeouts.
                (tramp-call-process
-                vec "ssh" nil t nil
-                "-p" "23" "-o" "ControlPath=%C" "localhost")
+                vec "ssh" nil t nil "-o" "ControlPath=%C" "0.0.0.1")
                (goto-char (point-min))
                (setq tramp-ssh-controlmaster-options
-                     (if (search-forward-regexp "unknown.+key" nil t)
-                         (concat tramp-ssh-controlmaster-options
-                                 " -o ControlPath='tramp.%%r@%%h:%%p'")
-                       (concat tramp-ssh-controlmaster-options
+                     (concat tramp-ssh-controlmaster-options
+                             (if (search-forward-regexp "unknown.+key" nil t)
+                                 " -o ControlPath='tramp.%%r@%%h:%%p'"
                                " -o ControlPath='tramp.%%C'"))))
              (with-temp-buffer
                (tramp-call-process vec "ssh" nil t nil "-o" "ControlPersist")
@@ -4760,22 +4762,18 @@ connection if a previous connection has died for some reason."
                         (l-host (tramp-file-name-host hop))
                         (l-port nil)
                         (login-program
-                         (tramp-get-method-parameter
-                          l-method 'tramp-login-program))
+                         (tramp-get-method-parameter hop 'tramp-login-program))
                         (login-args
-                         (tramp-get-method-parameter
-                          l-method 'tramp-login-args))
+                         (tramp-get-method-parameter hop 'tramp-login-args))
                         (login-env
-                         (tramp-get-method-parameter
-                          l-method 'tramp-login-env))
+                         (tramp-get-method-parameter hop 'tramp-login-env))
                         (async-args
-                         (tramp-get-method-parameter
-                          l-method 'tramp-async-args))
+                         (tramp-get-method-parameter hop 'tramp-async-args))
                         (connection-timeout
                          (tramp-get-method-parameter
-                          l-method 'tramp-connection-timeout))
+                          hop 'tramp-connection-timeout))
                         (gw-args
-                         (tramp-get-method-parameter l-method 'tramp-gw-args))
+                         (tramp-get-method-parameter hop 'tramp-gw-args))
                         (gw (let ((tramp-verbose 0))
                               (tramp-get-file-property hop "" "gateway" nil)))
                         (g-method (and gw (tramp-file-name-method gw)))
@@ -4963,8 +4961,8 @@ function waits for output unless NOOUTPUT is set."
   (vec command &optional subshell dont-suppress-err)
   "Run COMMAND and check its exit status.
 Sends `echo $?' along with the COMMAND for checking the exit status.
-If COMMAND is nil, just sends `echo $?'.  Returns `t' if the exit
-status is 0, and `nil' otherwise.
+If COMMAND is nil, just sends `echo $?'.  Returns t if the exit
+status is 0, and nil otherwise.
 
 If the optional argument SUBSHELL is non-nil, the command is
 executed in a subshell, ie surrounded by parentheses.  If
@@ -5113,14 +5111,17 @@ Return ATTR."
    ""))
 
 (defun tramp-make-copy-program-file-name (vec)
-  "Create a file name suitable to be passed to `scp' or `nc' and workalikes."
+  "Create a file name suitable for `scp', `pscp', or `nc' and workalikes."
   (let ((method (tramp-file-name-method vec))
        (user (tramp-file-name-user vec))
        (host (tramp-file-name-real-host vec))
-       (localname (tramp-shell-quote-argument
-                   (tramp-file-name-localname vec))))
+       (localname (tramp-file-name-localname vec)))
+    (when (string-match tramp-ipv6-regexp host)
+      (setq host (format "[%s]" host)))
+    (unless (string-match "ftp$" method)
+      (setq localname (tramp-shell-quote-argument localname)))
     (cond
-     ((tramp-get-method-parameter method 'tramp-remote-copy-program)
+     ((tramp-get-method-parameter vec 'tramp-remote-copy-program)
       localname)
      ((not (zerop (length user)))
       (shell-quote-argument (format "%s@%s:%s" user host localname)))
@@ -5130,7 +5131,7 @@ Return ATTR."
   "Return t if this is an out-of-band method, nil otherwise."
   (and
    ;; It shall be an out-of-band method.
-   (tramp-get-method-parameter (tramp-file-name-method vec) 'tramp-copy-program)
+   (tramp-get-method-parameter vec 'tramp-copy-program)
    ;; There must be a size, otherwise the file doesn't exist.
    (numberp size)
    ;; Either the file size is large enough, or (in rare cases) there
@@ -5172,13 +5173,15 @@ Return ATTR."
              (tramp-send-command-and-read
               vec
               (format
-               "%s -l %s 'echo %s \\\"$PATH\\\"'"
-               (tramp-get-method-parameter
-                (tramp-file-name-method vec) 'tramp-remote-shell)
+               "%s %s %s 'echo %s \\\"$PATH\\\"'"
+               (tramp-get-method-parameter vec 'tramp-remote-shell)
+               (mapconcat
+                'identity
+                (tramp-get-method-parameter vec 'tramp-remote-shell-login)
+                " ")
                (mapconcat
                 'identity
-                (tramp-get-method-parameter
-                 (tramp-file-name-method vec) 'tramp-remote-shell-args)
+                (tramp-get-method-parameter vec 'tramp-remote-shell-args)
                 " ")
                (tramp-shell-quote-argument tramp-end-of-heredoc))
               nil (regexp-quote tramp-end-of-heredoc)))))
@@ -5541,7 +5544,7 @@ If no corresponding command is found, nil is returned.
 Otherwise, either a string is returned which contains a `%s' mark
 to be used for the respective input or output file; or a Lisp
 function cell is returned to be applied on a buffer."
-  ;; We must catch the errors, because we want to return `nil', when
+  ;; We must catch the errors, because we want to return nil, when
   ;; no inline coding is found.
   (ignore-errors
     (let ((coding
@@ -5575,7 +5578,7 @@ function cell is returned to be applied on a buffer."
                       (default-directory
                         (tramp-compat-temporary-file-directory)))
                   (apply
-                   'call-process-region (point-min) (point-max)
+                   'tramp-call-process-region ,vec (point-min) (point-max)
                    (car (split-string ,compress)) t t nil
                    (cdr (split-string ,compress)))))
            `(lambda (beg end)
@@ -5584,7 +5587,7 @@ function cell is returned to be applied on a buffer."
                     (default-directory
                       (tramp-compat-temporary-file-directory)))
                 (apply
-                 'call-process-region beg end
+                 'tramp-call-process-region ,vec beg end
                  (car (split-string ,compress)) t t nil
                  (cdr (split-string ,compress))))
               (,coding (point-min) (point-max)))))
@@ -5630,8 +5633,6 @@ function cell is returned to be applied on a buffer."
 ;; * Don't use globbing for directories with many files, as this is
 ;;   likely to produce long command lines, and some shells choke on
 ;;   long command lines.
-;; * Make it work for different encodings, and for different file name
-;;   encodings, too.  (Daniel Pittman)
 ;; * Don't search for perl5 and perl.  Instead, only search for perl and
 ;;   then look if it's the right version (with `perl -v').
 ;; * When editing a remote CVS controlled file as a different user, VC