emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/tramp 47402cc: Tramp ELPA version 2.4.2 released.


From: Michael Albinus
Subject: [elpa] externals/tramp 47402cc: Tramp ELPA version 2.4.2 released.
Date: Sun, 30 Jun 2019 04:52:57 -0400 (EDT)

branch: externals/tramp
commit 47402ccb360728680e00db74b0cfe2d478e3c8cb
Author: Michael Albinus <address@hidden>
Commit: Michael Albinus <address@hidden>

    Tramp ELPA version 2.4.2 released.
---
 test/tramp-tests.el  | 183 +++++++++++--------
 texi/tramp.texi      |  54 ++++--
 texi/trampver.texi   |   8 +-
 tramp-adb.el         |  46 ++---
 tramp-archive.el     |  47 ++---
 tramp-cmds.el        |  15 +-
 tramp-compat.el      |  21 ++-
 tramp-ftp.el         |   4 +-
 tramp-gvfs.el        | 503 ++++++++++++++++++++++++++-------------------------
 tramp-integration.el |  72 ++++----
 tramp-loaddefs.el    |   2 +-
 tramp-sh.el          |  72 +++-----
 tramp-smb.el         |  24 +--
 tramp-sudoedit.el    |   7 +-
 tramp.el             | 355 +++++++++++++++++-------------------
 tramp.info           | 189 ++++++++++---------
 trampver.el          |   9 +-
 17 files changed, 825 insertions(+), 786 deletions(-)

diff --git a/test/tramp-tests.el b/test/tramp-tests.el
index 5b7d149..3d0faaf 100644
--- a/test/tramp-tests.el
+++ b/test/tramp-tests.el
@@ -19,8 +19,6 @@
 
 ;;; Commentary:
 
-;; The tests require a recent ert.el from Emacs 24.4.
-
 ;; Some of the tests require access to a remote host files.  Since
 ;; this could be problematic, a mock-up connection method "mock" is
 ;; used.  Emulating a remote connection, it simply calls "sh -i".
@@ -55,6 +53,7 @@
 (declare-function tramp-get-remote-path "tramp-sh")
 (declare-function tramp-get-remote-perl "tramp-sh")
 (declare-function tramp-get-remote-stat "tramp-sh")
+(declare-function tramp-list-tramp-buffers "tramp-cmds")
 (declare-function tramp-method-out-of-band-p "tramp-sh")
 (declare-function tramp-smb-get-localname "tramp-smb")
 (defvar auto-save-file-name-transforms)
@@ -168,18 +167,19 @@ properly.  BODY shall not contain a timeout."
   (declare (indent 1) (debug (natnump body)))
   `(let ((tramp-verbose (max (or ,verbose 0) (or tramp-verbose 0)))
         (tramp-message-show-message t)
-        (tramp-debug-on-error t)
         (debug-ignored-errors
-         (cons "^make-symbolic-link not supported$" debug-ignored-errors))
+         (append
+          '("^make-symbolic-link not supported$"
+            "^error with add-name-to-file")
+          debug-ignored-errors))
         inhibit-message)
      (unwind-protect
         (let ((tramp--test-instrument-test-case-p t)) ,@body)
        ;; Unwind forms.
        (when (and (null tramp--test-instrument-test-case-p) (> tramp-verbose 
3))
         (dolist (buf (tramp-list-tramp-buffers))
-          (message ";; %s" buf)
           (with-current-buffer buf
-            (message "%s" (buffer-string))))))))
+            (message ";; %s\n%s" buf (buffer-string))))))))
 
 (defsubst tramp--test-message (fmt-string &rest arguments)
   "Emit a message into ERT *Messages*."
@@ -411,9 +411,6 @@ properly.  BODY shall not contain a timeout."
 
 (ert-deftest tramp-test02-file-name-dissect ()
   "Check remote file name components."
-  ;; `user-error' has appeared in Emacs 24.3.
-  (skip-unless (fboundp 'user-error))
-
   (let ((tramp-default-method "default-method")
        (tramp-default-user "default-user")
        (tramp-default-host "default-host")
@@ -864,9 +861,6 @@ properly.  BODY shall not contain a timeout."
 (ert-deftest tramp-test02-file-name-dissect-simplified ()
   "Check simplified file name components."
   :tags '(:expensive-test)
-  ;; `user-error' has appeared in Emacs 24.3.
-  (skip-unless (fboundp 'user-error))
-
   (let ((tramp-default-method "default-method")
        (tramp-default-user "default-user")
        (tramp-default-host "default-host")
@@ -1198,9 +1192,6 @@ properly.  BODY shall not contain a timeout."
 (ert-deftest tramp-test02-file-name-dissect-separate ()
   "Check separate file name components."
   :tags '(:expensive-test)
-  ;; `user-error' has appeared in Emacs 24.3.
-  (skip-unless (fboundp 'user-error))
-
   (let ((tramp-default-method "default-method")
        (tramp-default-user "default-user")
        (tramp-default-host "default-host")
@@ -1890,8 +1881,6 @@ properly.  BODY shall not contain a timeout."
   "Check host name rules for host-less methods."
   (skip-unless (tramp--test-enabled))
   (skip-unless (tramp--test-sh-p))
-  ;; `user-error' has appeared in Emacs 24.3.
-  (skip-unless (fboundp 'user-error))
 
   ;; Host names must match rules in case the command template of a
   ;; method doesn't use them.
@@ -1915,8 +1904,6 @@ properly.  BODY shall not contain a timeout."
 (ert-deftest tramp-test03-file-name-method-rules ()
   "Check file name rules for some methods."
   (skip-unless (tramp--test-enabled))
-  ;; `user-error' has appeared in Emacs 24.3.
-  (skip-unless (fboundp 'user-error))
 
   ;; Multi hops are allowed for inline methods only.
   (should-error
@@ -2345,6 +2332,7 @@ This checks also `file-name-as-directory', 
`file-name-directory',
           ;; Run the test.
           (advice-add 'write-region :before advice)
           (setq-local file-precious-flag t)
+          (setq-local backup-inhibited t)
           (insert "bar")
           (should (null (save-buffer)))
           (should-not (cl-member tmp-name written-files :test #'string=)))
@@ -2958,17 +2946,16 @@ This tests also `file-directory-p' and 
`file-accessible-directory-p'."
        (ignore-errors (delete-directory tmp-name2 'recursive))))))
 
 ;; Method "smb" supports `make-symbolic-link' only if the remote host
-;; has CIFS capabilities.  tramp-adb.el and tramp-gvfs.el do not
-;; support symbolic links at all.
+;; has CIFS capabilities.  tramp-adb.el, tramp-gvfs.el and
+;; tramp-rclone.el do not support symbolic links at all.
 (defmacro tramp--test-ignore-make-symbolic-link-error (&rest body)
   "Run BODY, ignoring \"make-symbolic-link not supported\" file error."
-  (declare (indent defun) (debug t))
+  (declare (indent defun) (debug (body)))
   `(condition-case err
        (progn ,@body)
-     ((error quit debug)
-      (unless (and (eq (car err) 'file-error)
-                  (string-equal (error-message-string err)
-                                "make-symbolic-link not supported"))
+     (file-error
+      (unless (string-equal (error-message-string err)
+                           "make-symbolic-link not supported")
        (signal (car err) (cdr err))))))
 
 (ert-deftest tramp-test18-file-attributes ()
@@ -3175,13 +3162,12 @@ This tests also `file-executable-p', `file-writable-p' 
and `set-file-modes'."
 ;; Method "smb" could run into "NT_STATUS_REVISION_MISMATCH" error.
 (defmacro tramp--test-ignore-add-name-to-file-error (&rest body)
   "Run BODY, ignoring \"error with add-name-to-file\" file error."
-  (declare (indent defun) (debug t))
+  (declare (indent defun) (debug (body)))
   `(condition-case err
        (progn ,@body)
-     ((error quit debug)
-      (unless (and (eq (car err) 'file-error)
-                  (string-match "^error with add-name-to-file"
-                                (error-message-string err)))
+     (file-error
+      (unless (string-match "^error with add-name-to-file"
+                           (error-message-string err))
        (signal (car err) (cdr err))))))
 
 (ert-deftest tramp-test21-file-links ()
@@ -4171,7 +4157,8 @@ This tests also `make-symbolic-link', `file-truename' and 
`add-name-to-file'."
          (should (numberp (process-get proc 'remote-pid)))
          (should (interrupt-process proc))
          ;; Let the process accept the interrupt.
-         (while (accept-process-output proc nil nil 0))
+         (with-timeout (10 (tramp--test-timeout-handler))
+           (while (accept-process-output proc nil nil 0)))
          (should-not (process-live-p proc))
          ;; An interrupted process cannot be interrupted, again.
          (should-error (interrupt-process proc) :type 'error))
@@ -4286,9 +4273,10 @@ This tests also `make-symbolic-link', `file-truename' 
and `add-name-to-file'."
        (ignore-errors (delete-file tmp-name)))
 
       ;; Test `async-shell-command-width'.  Since Emacs 27.1.
-      (when (and (boundp 'async-shell-command-width)
-                (zerop (call-process "tput" nil nil nil "cols"))
-                 (zerop (process-file "tput" nil nil nil "cols")))
+      (when (ignore-errors
+             (and (boundp 'async-shell-command-width)
+                  (zerop (call-process "tput" nil nil nil "cols"))
+                   (zerop (process-file "tput" nil nil nil "cols"))))
        (let (async-shell-command-width)
          (should
           (string-equal
@@ -5483,6 +5471,37 @@ Use the `ls' command."
 (defconst tramp--test-asynchronous-requests-timeout 300
   "Timeout for `tramp-test43-asynchronous-requests'.")
 
+(defmacro tramp--test-with-proper-process-name-and-buffer (proc &rest body)
+  "Set \"process-name\" and \"process-buffer\" connection properties.
+This is needed in timer functions as well as process filters and sentinels."
+  (declare (indent 1) (debug (processp body)))
+  `(let* ((v (tramp-get-connection-property ,proc "vector" nil))
+         (pname (tramp-get-connection-property v "process-name" nil))
+         (pbuffer (tramp-get-connection-property v "process-buffer" nil)))
+     (tramp--test-message
+      "tramp--test-with-proper-process-name-and-buffer before %s %s"
+      (tramp-get-connection-property v "process-name" nil)
+      (tramp-get-connection-property v "process-buffer" nil))
+     (if (process-name ,proc)
+        (tramp-set-connection-property v "process-name" (process-name ,proc))
+       (tramp-flush-connection-property v "process-name"))
+     (if (process-buffer ,proc)
+        (tramp-set-connection-property
+         v "process-buffer" (process-buffer ,proc))
+       (tramp-flush-connection-property v "process-buffer"))
+     (tramp--test-message
+      "tramp--test-with-proper-process-name-and-buffer changed %s %s"
+      (tramp-get-connection-property v "process-name" nil)
+      (tramp-get-connection-property v "process-buffer" nil))
+     (unwind-protect
+        (progn ,@body)
+       (if pname
+          (tramp-set-connection-property v "process-name" pname)
+        (tramp-flush-connection-property v "process-name"))
+       (if pbuffer
+          (tramp-set-connection-property v "process-buffer" pbuffer)
+        (tramp-flush-connection-property v "process-buffer")))))
+
 ;; This test is inspired by Bug#16928.
 (ert-deftest tramp-test43-asynchronous-requests ()
   "Check parallel asynchronous requests.
@@ -5492,6 +5511,7 @@ process sentinels.  They shall not disturb each other."
   ;; we mark it as unstable.
   :tags '(:expensive-test :unstable)
   (skip-unless (tramp--test-enabled))
+  (skip-unless nil)
   ;; Prior Emacs 27, `shell-file-name' was hard coded as "/bin/sh" for
   ;; remote processes in Emacs.  That doesn't work for tramp-adb.el.
   (skip-unless (or (and (tramp--test-adb-p) (tramp--test-emacs27-p))
@@ -5503,12 +5523,14 @@ process sentinels.  They shall not disturb each other."
     (let* (;; For the watchdog.
           (default-directory (expand-file-name temporary-file-directory))
           (shell-file-name (if (tramp--test-adb-p) "/system/bin/sh" "/bin/sh"))
+          ;; It doesn't work on w32 systems.
           (watchdog
-            (start-process-shell-command
-             "*watchdog*" nil
-             (format
-             "sleep %d; kill -USR1 %d"
-             tramp--test-asynchronous-requests-timeout (emacs-pid))))
+           (unless (tramp--test-windows-nt)
+              (start-process-shell-command
+               "*watchdog*" nil
+               (format
+               "sleep %d; kill -USR1 %d"
+               tramp--test-asynchronous-requests-timeout (emacs-pid)))))
            (tmp-name (tramp--test-make-temp-name))
            (default-directory tmp-name)
            ;; Do not cache Tramp properties.
@@ -5532,10 +5554,10 @@ process sentinels.  They shall not disturb each other."
              ((getenv "EMACS_HYDRA_CI") 10)
              (t 1)))
            ;; We must distinguish due to performance reasons.
-           (timer-operation
-            (cond
-             ((tramp--test-mock-p) #'vc-registered)
-             (t #'file-attributes)))
+           ;; (timer-operation
+           ;;  (cond
+           ;;   ((tramp--test-mock-p) #'vc-registered)
+           ;;   (t #'file-attributes)))
           ;; This is when all timers start.  We check inside the
           ;; timer function, that we don't exceed timeout.
           (timer-start (current-time))
@@ -5553,25 +5575,31 @@ process sentinels.  They shall not disturb each other."
              (run-at-time
               0 timer-repeat
               (lambda ()
-                (when (> (- (time-to-seconds) (time-to-seconds timer-start))
-                         tramp--test-asynchronous-requests-timeout)
-                  (tramp--test-timeout-handler))
-                (when buffers
-                  (let ((time (float-time))
-                        (default-directory tmp-name)
-                        (file
-                         (buffer-name (nth (random (length buffers)) 
buffers))))
-                    (tramp--test-message
-                     "Start timer %s %s" file (current-time-string))
-                    (funcall timer-operation file)
-                    ;; Adjust timer if it takes too much time.
-                    (tramp--test-message
-                     "Stop timer %s %s" file (current-time-string))
-                    (when (> (- (float-time) time) timer-repeat)
-                      (setq timer-repeat (* 1.5 timer-repeat))
-                      (setf (timer--repeat-delay timer) timer-repeat)
+                (tramp--test-with-proper-process-name-and-buffer
+                    (get-buffer-process
+                     (tramp-get-buffer
+                      (tramp-dissect-file-name
+                       tramp-test-temporary-file-directory)))
+                  (when (> (- (time-to-seconds) (time-to-seconds timer-start))
+                           tramp--test-asynchronous-requests-timeout)
+                    (tramp--test-timeout-handler))
+                  (when buffers
+                    (let ((time (float-time))
+                          (default-directory tmp-name)
+                          (file
+                           (buffer-name
+                            (nth (random (length buffers)) buffers))))
+                      (tramp--test-message
+                       "Start timer %s %s" file (current-time-string))
+                      ;; (funcall timer-operation file)
                       (tramp--test-message
-                      "Increase timer %s" timer-repeat)))))))
+                       "Stop timer %s %s" file (current-time-string))
+                      ;; Adjust timer if it takes too much time.
+                      (when (> (- (float-time) time) timer-repeat)
+                        (setq timer-repeat (* 1.1 timer-repeat))
+                        (setf (timer--repeat-delay timer) timer-repeat)
+                        (tramp--test-message
+                         "Increase timer %s" timer-repeat))))))))
 
             ;; Create temporary buffers.  The number of buffers
             ;; corresponds to the number of processes; it could be
@@ -5598,27 +5626,28 @@ process sentinels.  They shall not disturb each other."
                 (set-process-filter
                  proc
                  (lambda (proc string)
-                   (tramp--test-message
-                    "Process filter %s %s %s" proc string 
(current-time-string))
-                   (with-current-buffer (process-buffer proc)
-                     (insert string))
-                   (when (< (process-get proc 'bar) 2)
-                    (dired-uncache (process-get proc 'foo))
-                     (should (file-attributes (process-get proc 'foo))))))
+                  (tramp--test-with-proper-process-name-and-buffer proc
+                     (tramp--test-message
+                      "Process filter %s %s %s"
+                     proc string (current-time-string))
+                     (with-current-buffer (process-buffer proc)
+                       (insert string))
+                     (when (< (process-get proc 'bar) 2)
+                      (dired-uncache (process-get proc 'foo))
+                       (should (file-attributes (process-get proc 'foo)))))))
                 ;; Add process sentinel.  It shall not perform remote
                 ;; operations, triggering Tramp processes.  This blocks.
                 (set-process-sentinel
                  proc
                  (lambda (proc _state)
-                   (tramp--test-message
-                    "Process sentinel %s %s" proc (current-time-string))))))
+                  (tramp--test-with-proper-process-name-and-buffer proc
+                     (tramp--test-message
+                      "Process sentinel %s %s" proc (current-time-string)))))))
 
             ;; Send a string to the processes.  Use a random order of
             ;; the buffers.  Mix with regular operation.
             (let ((buffers (copy-sequence buffers)))
               (while buffers
-               ;; Activate timer.
-               (sit-for 0.01 'nodisp)
                 (let* ((buf (nth (random (length buffers)) buffers))
                        (proc (get-buffer-process buf))
                        (file (process-get proc 'foo))
@@ -5632,9 +5661,7 @@ process sentinels.  They shall not disturb each other."
                     (should (file-attributes file)))
                   ;; Send string to process.
                   (process-send-string proc (format "%s\n" (buffer-name buf)))
-                  (while (accept-process-output proc 0 nil 0))
-                  ;; Give the watchdog a chance.
-                  (read-event nil nil 0.01)
+                  (while (accept-process-output nil 0))
                   (tramp--test-message
                    "Continue action %d %s %s" count buf (current-time-string))
                   ;; Regular operation post process action.
@@ -5972,8 +5999,8 @@ Since it unloads Tramp, it shall be the last test to run."
 ;; * Fix `tramp-test29-start-file-process' and
 ;;   `tramp-test30-make-process' on MS Windows (`process-send-eof'?).
 ;; * Implement `tramp-test31-interrupt-process' for `adb'.
-;; * Fix Bug#16928 in `tramp-test43-asynchronous-requests'.  Looks
-;;   like it is resolved now.  Remove `:unstable' tag?
+;; * Fix Bug#16928 in `tramp-test43-asynchronous-requests'.  A remote
+;;   file name operation cannot run in the timer.  Remove `:unstable' tag?
 ;; * Fix `tramp-test44-threads'.
 
 (provide 'tramp-tests)
diff --git a/texi/tramp.texi b/texi/tramp.texi
index 3e66e5d..f67ed48 100644
--- a/texi/tramp.texi
+++ b/texi/tramp.texi
@@ -309,21 +309,43 @@ behind the scenes when you open a file with @value{tramp}.
 @chapter Obtaining @value{tramp}
 @cindex obtaining @value{tramp}
 @cindex GNU ELPA
+@vindex tramp-version
 
 @value{tramp} is included as part of Emacs (since Emacs 22.1).
 
 @value{tramp} is also freely packaged for download on the Internet at
-@uref{https://ftp.gnu.org/gnu/tramp/}.
+@uref{https://ftp.gnu.org/gnu/tramp/}.  The version number of
+@value{tramp} can be obtained by the variable @code{tramp-version}.
+For released @value{tramp} versions, this is a three-number string
+like ``2.4.2''.
+
+A @value{tramp} release, which is packaged with Emacs, could differ
+slightly from the corresponding standalone release.  This is because
+it isn't always possible to synchronize release dates between Emacs
+and @value{tramp}.  Such version numbers have the Emacs version number
+as suffix, like ``2.3.5.26.3''.  This means @value{tramp} 2.3.5 as
+integrated in Emacs 26.3.  A complete list of @value{tramp} versions
+packaged with Emacs can be retrieved by
+
+@vindex customize-package-emacs-version-alist
+@lisp
+(assoc 'Tramp customize-package-emacs-version-alist)
+@end lisp
 
-@value{tramp} is available as @uref{https://elpa.gnu.org, GNU ELPA}
-package.
+@value{tramp} is also available as @uref{https://elpa.gnu.org, GNU
+ELPA} package.  Besides the standalone releases, further minor version
+of @value{tramp} will appear on GNU ELPA, until the next @value{tramp}
+release appears.  These minor versions have a four-number string, like
+``2.4.2.1''.
 
 @value{tramp} development versions are available on Git servers.
-Development versions contain new and incomplete features.
+Development versions contain new and incomplete features.  The
+development version of @value{tramp} is always the version number of
+the next release, plus the suffix ``-pre'', like ``2.4.3-pre''.
 
-One way to obtain from Git server is to visit the Savannah project
-page at the following URL and then clicking on the Git link in the
-navigation bar at the top.
+One way to obtain @value{tramp} from Git server is to visit the
+Savannah project page at the following URL and then clicking on the
+Git link in the navigation bar at the top.
 
 @noindent
 @uref{https://savannah.gnu.org/projects/tramp/}
@@ -382,7 +404,7 @@ $ autoconf
 
 
 @c Installation chapter is necessary only in case of standalone
-@c installation.  Text taken from trampinst.texi.
+@c installation.
 @ifset installchapter
 @include trampinst.texi
 @end ifset
@@ -3419,18 +3441,21 @@ Shell archives
 @cindex @file{shar} file archive suffix
 @cindex file archive suffix @file{shar}
 
-@item @samp{.tar}, @samp{.tbz}, @samp{.tgz}, @samp{.tlz}, @samp{.txz} ---
+@item @samp{.tar}, @samp{.tbz}, @samp{.tgz}, @samp{.tlz}, @samp{.txz},
+@samp{.tzst} ---
 (Compressed) tape archives
 @cindex @file{tar} file archive suffix
 @cindex @file{tbz} file archive suffix
 @cindex @file{tgz} file archive suffix
 @cindex @file{tlz} file archive suffix
 @cindex @file{txz} file archive suffix
+@cindex @file{tzst} file archive suffix
 @cindex file archive suffix @file{tar}
 @cindex file archive suffix @file{tbz}
 @cindex file archive suffix @file{tgz}
 @cindex file archive suffix @file{tlz}
 @cindex file archive suffix @file{txz}
+@cindex file archive suffix @file{tzst}
 
 @item @samp{.warc} ---
 Web archives
@@ -3465,8 +3490,8 @@ File archives could also be compressed, identified by an 
additional
 compression suffix.  Valid compression suffixes are listed in the
 constant @code{tramp-archive-compression-suffixes}.  They are
 @samp{.bz2}, @samp{.gz}, @samp{.lrz}, @samp{.lz}, @samp{.lz4},
-@samp{.lzma}, @samp{.lzo}, @samp{.uu}, @samp{.xz} and @samp{.Z}.  A
-valid archive file name would be
+@samp{.lzma}, @samp{.lzo}, @samp{.uu}, @samp{.xz}, @samp{.Z}, and
+@samp{.zst}.  A valid archive file name would be
 @file{/path/to/dir/file.tar.gz/dir/file}.  Even several suffixes in a
 row are possible, like @file{/path/to/dir/file.tar.gz.uu/dir/file}.
 
@@ -4179,10 +4204,8 @@ directory to the cache:
 
 @lisp
 @group
-@c `with-eval-after-load' has been introduced with Emacs 24.4.  Shall
-@c be used when appropriate.
-(eval-after-load "filecache"
-  '(file-cache-add-directory
+(with-eval-after-load 'filecache
+  (file-cache-add-directory
     "@trampfn{ssh,news@@news.my.domain,/opt/news/etc/}"))
 @end group
 @end lisp
@@ -4462,6 +4485,7 @@ root-directory, it is most likely sufficient to make the
 
 @node Traces and Profiles
 @chapter How to Customize Traces
+@vindex tramp-verbose
 
 @value{tramp} messages are raised with verbosity levels ranging from 0
 to 10.  @value{tramp} does not display all messages; only those with a
diff --git a/texi/trampver.texi b/texi/trampver.texi
index 7d94937..6cc6429 100644
--- a/texi/trampver.texi
+++ b/texi/trampver.texi
@@ -5,10 +5,12 @@
 @c Copyright (C) 2003-2019 Free Software Foundation, Inc.
 @c See file doclicense.texi for copying conditions.
 
-@c In the Tramp GIT, the version number is auto-frobbed from tramp.el,
-@c and the bug report address is auto-frobbed from configure.ac.
-@set trampver 0
+@c In the Tramp GIT, the version numbers are auto-frobbed from
+@c tramp.el, and the bug report address is auto-frobbed from
+@c configure.ac.
+@set trampver 2.4.2
 @set tramp-bug-report-address tramp-devel@@gnu.org
+@set emacsver 24.4
 
 @c Other flags from configuration.
 @set instprefix /usr/local
diff --git a/tramp-adb.el b/tramp-adb.el
index 9a214c3..186b67c 100644
--- a/tramp-adb.el
+++ b/tramp-adb.el
@@ -257,17 +257,15 @@ pass to the OPERATION."
              (setq thisstep (pop steps))
              (tramp-message
               v 5 "Check %s"
-              (mapconcat #'identity
-                         (append '("") (reverse result) (list thisstep))
-                         "/"))
+              (string-join
+               (append '("") (reverse result) (list thisstep)) "/"))
              (setq symlink-target
                    (tramp-compat-file-attribute-type
                     (file-attributes
                      (tramp-make-tramp-file-name
-                      v (mapconcat #'identity
-                                   (append
-                                    '("") (reverse result) (list thisstep))
-                                   "/")))))
+                      v
+                      (string-join
+                       (append '("") (reverse result) (list thisstep)) "/")))))
              (cond ((string= "." thisstep)
                     (tramp-message v 5 "Ignoring step `.'"))
                    ((string= ".." thisstep)
@@ -302,9 +300,9 @@ pass to the OPERATION."
            ;; Combine list to form string.
            (setq result
                  (if result
-                     (mapconcat #'identity (cons "" result) "/")
+                     (string-join (cons "" result) "/")
                    "/"))
-           (when (and is-dir (or (string= "" result)
+           (when (and is-dir (or (string-empty-p result)
                                  (not (string= (substring result -1) "/"))))
              (setq result (concat result "/"))))
 
@@ -479,7 +477,7 @@ Emacs dired can't find files."
                 #'tramp-adb-ls-output-time-less-p
               #'tramp-adb-ls-output-name-less-p))))
       (delete-region (point-min) (point-max))
-      (insert "  " (mapconcat #'identity sorted-lines "\n  ")))
+      (insert "  " (string-join sorted-lines "\n  ")))
     ;; Add final newline.
     (goto-char (point-max))
     (unless (bolp) (insert "\n"))))
@@ -1232,7 +1230,7 @@ connection if a previous connection has died for some 
reason."
                 (prompt (md5 (concat (prin1-to-string process-environment)
                                      (current-time-string)))))
            (tramp-message
-            vec 6 "%s" (mapconcat #'identity (process-command p) " "))
+            vec 6 "%s" (string-join (process-command p) " "))
            ;; Wait for initial prompt.  On some devices, it needs an
            ;; initial RET, in order to get it.
             (sleep-for 0.1)
@@ -1294,25 +1292,21 @@ connection if a previous connection has died for some 
reason."
 
 ;; Default settings for connection-local variables.
 (defconst tramp-adb-connection-local-default-profile
-  ;; `w32-shell-name' is derived from `shell-file-name'.  Don't let it
-  ;; be confused.
-  (unless (eq system-type 'windows-nt)
-    '((shell-file-name . "/system/bin/sh")
-      (shell-command-switch . "-c")))
+  '((shell-file-name . "/system/bin/sh")
+    (shell-command-switch . "-c"))
   "Default connection-local variables for remote adb connections.")
 
 ;; `connection-local-set-profile-variables' and
 ;; `connection-local-set-profiles' exists since Emacs 26.1.
-(eval-after-load "shell"
-  '(progn
-     (tramp-compat-funcall
-      'connection-local-set-profile-variables
-      'tramp-adb-connection-local-default-profile
-      tramp-adb-connection-local-default-profile)
-     (tramp-compat-funcall
-      'connection-local-set-profiles
-      `(:application tramp :protocol ,tramp-adb-method)
-      'tramp-adb-connection-local-default-profile)))
+(with-eval-after-load 'shell
+  (tramp-compat-funcall
+   'connection-local-set-profile-variables
+   'tramp-adb-connection-local-default-profile
+   tramp-adb-connection-local-default-profile)
+  (tramp-compat-funcall
+   'connection-local-set-profiles
+   `(:application tramp :protocol ,tramp-adb-method)
+   'tramp-adb-connection-local-default-profile))
 
 (add-hook 'tramp-unload-hook
          (lambda ()
diff --git a/tramp-archive.el b/tramp-archive.el
index e6ae73a..82fd327 100644
--- a/tramp-archive.el
+++ b/tramp-archive.el
@@ -77,8 +77,8 @@
 ;; File archives could also be compressed, identified by an additional
 ;; compression suffix.  Valid compression suffixes are listed in the
 ;; constant `tramp-archive-compression-suffixes'.  They are ".bz2",
-;; ".gz", ".lrz", ".lz", ".lz4", ".lzma", ".lzo", ".uu", ".xz" and
-;; ".Z".  A valid archive file name would be
+;; ".gz", ".lrz", ".lz", ".lz4", ".lzma", ".lzo", ".uu", ".xz", ".Z",
+;; and ".zst".  A valid archive file name would be
 ;; "/path/to/dir/file.tar.gz/dir/file".  Even several suffixes in a
 ;; row are possible, like "/path/to/dir/file.tar.gz.uu/dir/file".
 
@@ -154,7 +154,7 @@
     "rar" ;; RAR archives.
     "rpm" ;; Red Hat packages.
     "shar" ;; Shell archives.  Not in libarchive testsuite.
-    "tar" "tbz" "tgz" "tlz" "txz" ;; (Compressed) tape archives.
+    "tar" "tbz" "tgz" "tlz" "txz" "tzst" ;; (Compressed) tape archives.
     "warc" ;; Web archives.
     "xar" ;; macOS XAR archives.  Not in libarchive testsuite.
     "xpi" ;; XPInstall Mozilla addons.  Not in libarchive testsuite.
@@ -169,7 +169,7 @@ It must be supported by libarchive(3).")
 
 ;;;###autoload
 (defconst tramp-archive-compression-suffixes
-  '("bz2" "gz" "lrz" "lz" "lz4" "lzma" "lzo" "uu" "xz" "Z")
+  '("bz2" "gz" "lrz" "lz" "lz4" "lzma" "lzo" "uu" "xz" "Z" "zst")
   "List of suffixes which indicate a compressed file.
 It must be supported by libarchive(3).")
 
@@ -372,14 +372,13 @@ pass to the OPERATION."
 ;; `tramp-archive-file-name-handler' must be placed before `url-file-handler'.
 (when url-handler-mode (tramp-register-file-name-handlers))
 
-(eval-after-load 'url-handler
-  '(progn
-     (add-hook 'url-handler-mode-hook #'tramp-register-file-name-handlers)
-     (add-hook
-      'tramp-archive-unload-hook
-      (lambda ()
-       (remove-hook
-        'url-handler-mode-hook #'tramp-register-file-name-handlers)))))
+(with-eval-after-load 'url-handler
+  (add-hook 'url-handler-mode-hook #'tramp-register-file-name-handlers)
+  (add-hook
+   'tramp-archive-unload-hook
+   (lambda ()
+     (remove-hook
+      'url-handler-mode-hook #'tramp-register-file-name-handlers))))
 
 
 ;; File name conversions.
@@ -475,17 +474,19 @@ name is kept in slot `hop'"
 
 (defun tramp-archive-cleanup-hash ()
   "Remove local copies of archives, used by GVFS."
-  (maphash
-   (lambda (key value)
-     ;; Unmount local copy.
-     (ignore-errors
-       (tramp-message (car value) 3 "Unmounting %s" (or (cdr value) key))
-       (tramp-gvfs-unmount (car value)))
-     ;; Delete local copy.
-     (ignore-errors (delete-file (cdr value)))
-     (remhash key tramp-archive-hash))
-   tramp-archive-hash)
-  (clrhash tramp-archive-hash))
+  ;; Don't check for a proper method.
+  (let ((non-essential t))
+    (maphash
+     (lambda (key value)
+       ;; Unmount local copy.
+       (ignore-errors
+        (tramp-message (car value) 3 "Unmounting %s" (or (cdr value) key))
+        (tramp-gvfs-unmount (car value)))
+       ;; Delete local copy.
+       (ignore-errors (delete-file (cdr value)))
+       (remhash key tramp-archive-hash))
+     tramp-archive-hash)
+    (clrhash tramp-archive-hash)))
 
 (add-hook 'tramp-cleanup-all-connections-hook #'tramp-archive-cleanup-hash)
 (add-hook 'kill-emacs-hook #'tramp-archive-cleanup-hash)
diff --git a/tramp-cmds.el b/tramp-cmds.el
index f1e1d82..007b98f 100644
--- a/tramp-cmds.el
+++ b/tramp-cmds.el
@@ -116,6 +116,12 @@ When called interactively, a Tramp connection has to be 
selected."
       (delete-process (tramp-get-connection-process vec)))
     (tramp-flush-connection-properties vec)
 
+    ;; Cancel timer.
+    (dolist (timer timer-list)
+      (when (and (eq (timer--function timer) 'tramp-timeout-session)
+                (tramp-file-name-equal-p vec (car (timer--args timer))))
+       (cancel-timer timer)))
+
     ;; Remove buffers.
     (dolist
        (buf (list (get-buffer (tramp-buffer-name vec))
@@ -163,9 +169,12 @@ This includes password cache, file cache, connection 
cache, buffers."
                (delete (car proxies) tramp-default-proxies-alist)
                proxies tramp-default-proxies-alist)
        (setq proxies (cdr proxies)))))
-    (when (and tramp-default-proxies-alist tramp-save-ad-hoc-proxies)
-      (customize-save-variable
-       'tramp-default-proxies-alist tramp-default-proxies-alist))
+  (when (and tramp-default-proxies-alist tramp-save-ad-hoc-proxies)
+    (customize-save-variable
+     'tramp-default-proxies-alist tramp-default-proxies-alist))
+
+  ;; Cancel timers.
+  (cancel-function-timers 'tramp-timeout-session)
 
   ;; Remove buffers.
   (dolist (name (tramp-list-tramp-buffers))
diff --git a/tramp-compat.el b/tramp-compat.el
index 7c13adf..6b855e6 100644
--- a/tramp-compat.el
+++ b/tramp-compat.el
@@ -36,8 +36,10 @@
 
 (require 'auth-source)
 (require 'format-spec)
+(require 'ls-lisp)  ;; Due to `tramp-handle-insert-directory'.
 (require 'parse-time)
 (require 'shell)
+(require 'subr-x)
 
 (declare-function tramp-handle-temporary-file-directory "tramp")
 
@@ -80,7 +82,7 @@ Add the extension of F, if existing."
      ((fboundp 'w32-window-exists-p)
       (tramp-compat-funcall 'w32-window-exists-p process-name process-name))
 
-     ;; GNU Emacs 23.
+     ;; GNU Emacs 23+.
      ((and (fboundp 'list-system-processes) (fboundp 'process-attributes))
       (let (result)
        (dolist (pid (tramp-compat-funcall 'list-system-processes) result)
@@ -96,10 +98,6 @@ Add the extension of F, if existing."
                                     process-name))))
              (setq result t)))))))))
 
-;; `default-toplevel-value' has been declared in Emacs 24.4.
-(unless (fboundp 'default-toplevel-value)
-  (defalias 'default-toplevel-value #'symbol-value))
-
 ;; `file-attribute-*' are introduced in Emacs 25.1.
 
 (defalias 'tramp-compat-file-attribute-type
@@ -315,6 +313,14 @@ A nil value for either argument stands for the current 
time."
                 tree))
        (nreverse elems)))))
 
+;; `progress-reporter-update' got argument SUFFIX in Emacs 27.1.
+(defalias 'tramp-compat-progress-reporter-update
+  (if (equal (tramp-compat-funcall 'func-arity #'progress-reporter-update)
+            '(1 . 3))
+      #'progress-reporter-update
+    (lambda (reporter &optional value _suffix)
+      (progress-reporter-update reporter value))))
+
 (add-hook 'tramp-unload-hook
          (lambda ()
            (unload-feature 'tramp-loaddefs 'force)
@@ -322,9 +328,4 @@ A nil value for either argument stands for the current 
time."
 
 (provide 'tramp-compat)
 
-;;; TODO:
-
-;; * When we get rid of Emacs 24, replace "(mapconcat #'identity" by
-;;   "(string-join".
-
 ;;; tramp-compat.el ends here
diff --git a/tramp-ftp.el b/tramp-ftp.el
index 3e06ced..fa76a95 100644
--- a/tramp-ftp.el
+++ b/tramp-ftp.el
@@ -54,8 +54,8 @@ present for backward compatibility."
     (setq file-name-handler-alist
          (delete a1 (delete a2 file-name-handler-alist)))))
 
-(eval-after-load "ange-ftp"
-  '(tramp-disable-ange-ftp))
+(with-eval-after-load 'ange-ftp
+  (tramp-disable-ange-ftp))
 
 ;;;###tramp-autoload
 (defun tramp-ftp-enable-ange-ftp ()
diff --git a/tramp-gvfs.el b/tramp-gvfs.el
index 17c2e79..e3da20a 100644
--- a/tramp-gvfs.el
+++ b/tramp-gvfs.el
@@ -724,12 +724,7 @@ is no information where to trace the message.")
     (tramp-message tramp-gvfs-dbus-event-vector 6 "%S" event)
     (tramp-error tramp-gvfs-dbus-event-vector 'file-error "%s" (cadr err))))
 
-;; `dbus-event-error-hooks' has been renamed to
-;; `dbus-event-error-functions' in Emacs 24.3.
-(add-hook
- (if (boundp 'dbus-event-error-functions)
-     'dbus-event-error-functions 'dbus-event-error-hooks)
- #'tramp-gvfs-dbus-event-error)
+(add-hook 'dbus-event-error-functions #'tramp-gvfs-dbus-event-error)
 
 
 ;; File name primitives.
@@ -933,76 +928,74 @@ file names."
 
 (defun tramp-gvfs-get-directory-attributes (directory)
   "Return GVFS attributes association list of all files in DIRECTORY."
-  (ignore-errors
-    ;; Don't modify `last-coding-system-used' by accident.
-    (let ((last-coding-system-used last-coding-system-used)
-         result)
-      (with-parsed-tramp-file-name directory nil
-       (with-tramp-file-property v localname "directory-attributes"
-         (tramp-message v 5 "directory gvfs attributes: %s" localname)
-         ;; Send command.
-         (tramp-gvfs-send-command
-          v "gvfs-ls" "-h" "-n" "-a"
-          (mapconcat #'identity tramp-gvfs-file-attributes ",")
-          (tramp-gvfs-url-file-name directory))
-         ;; Parse output.
-         (with-current-buffer (tramp-get-connection-buffer v)
-           (goto-char (point-min))
-           (while (looking-at
-                   (concat "^\\(.+\\)[[:blank:]]"
-                           "\\([[:digit:]]+\\)[[:blank:]]"
-                           "(\\(.+?\\))"
-                           tramp-gvfs-file-attributes-with-gvfs-ls-regexp))
-             (let ((item (list (cons "type" (match-string 3))
-                               (cons "standard::size" (match-string 2))
-                               (cons "name" (match-string 1)))))
-               (goto-char (1+ (match-end 3)))
-               (while (looking-at
-                       (concat
-                        tramp-gvfs-file-attributes-with-gvfs-ls-regexp
-                        "\\(" tramp-gvfs-file-attributes-with-gvfs-ls-regexp
-                        "\\|" "$" "\\)"))
-                 (push (cons (match-string 1) (match-string 2)) item)
-                 (goto-char (match-end 2)))
-               ;; Add display name as head.
-               (push
-                (cons (cdr (or (assoc "standard::display-name" item)
-                               (assoc "name" item)))
-                      (nreverse item))
-                result))
-             (forward-line)))
-         result)))))
+  ;; Don't modify `last-coding-system-used' by accident.
+  (let ((last-coding-system-used last-coding-system-used)
+       result)
+    (with-parsed-tramp-file-name directory nil
+      (with-tramp-file-property v localname "directory-attributes"
+       (tramp-message v 5 "directory gvfs attributes: %s" localname)
+       ;; Send command.
+       (tramp-gvfs-send-command
+        v "gvfs-ls" "-h" "-n" "-a"
+        (string-join tramp-gvfs-file-attributes ",")
+        (tramp-gvfs-url-file-name directory))
+       ;; Parse output.
+       (with-current-buffer (tramp-get-connection-buffer v)
+         (goto-char (point-min))
+         (while (looking-at
+                 (concat "^\\(.+\\)[[:blank:]]"
+                         "\\([[:digit:]]+\\)[[:blank:]]"
+                         "(\\(.+?\\))"
+                         tramp-gvfs-file-attributes-with-gvfs-ls-regexp))
+           (let ((item (list (cons "type" (match-string 3))
+                             (cons "standard::size" (match-string 2))
+                             (cons "name" (match-string 1)))))
+             (goto-char (1+ (match-end 3)))
+             (while (looking-at
+                     (concat
+                      tramp-gvfs-file-attributes-with-gvfs-ls-regexp
+                      "\\(" tramp-gvfs-file-attributes-with-gvfs-ls-regexp
+                      "\\|" "$" "\\)"))
+               (push (cons (match-string 1) (match-string 2)) item)
+               (goto-char (match-end 2)))
+             ;; Add display name as head.
+             (push
+              (cons (cdr (or (assoc "standard::display-name" item)
+                             (assoc "name" item)))
+                    (nreverse item))
+              result))
+           (forward-line)))
+       result))))
 
 (defun tramp-gvfs-get-root-attributes (filename &optional file-system)
   "Return GVFS attributes association list of FILENAME.
 If FILE-SYSTEM is non-nil, return file system attributes."
-  (ignore-errors
-    ;; Don't modify `last-coding-system-used' by accident.
-    (let ((last-coding-system-used last-coding-system-used)
-         result)
-      (with-parsed-tramp-file-name filename nil
-       (with-tramp-file-property
-           v localname
-           (if file-system "file-system-attributes" "file-attributes")
-         (tramp-message
-          v 5 "file%s gvfs attributes: %s"
-          (if file-system " system" "") localname)
-         ;; Send command.
-         (if file-system
-             (tramp-gvfs-send-command
-              v "gvfs-info" "--filesystem" (tramp-gvfs-url-file-name filename))
+  ;; Don't modify `last-coding-system-used' by accident.
+  (let ((last-coding-system-used last-coding-system-used)
+       result)
+    (with-parsed-tramp-file-name filename nil
+      (with-tramp-file-property
+         v localname
+         (if file-system "file-system-attributes" "file-attributes")
+       (tramp-message
+        v 5 "file%s gvfs attributes: %s"
+        (if file-system " system" "") localname)
+       ;; Send command.
+       (if file-system
            (tramp-gvfs-send-command
-            v "gvfs-info" (tramp-gvfs-url-file-name filename)))
-         ;; Parse output.
-         (with-current-buffer (tramp-get-connection-buffer v)
-           (goto-char (point-min))
-           (while (re-search-forward
-                   (if file-system
-                       tramp-gvfs-file-system-attributes-regexp
-                     tramp-gvfs-file-attributes-with-gvfs-info-regexp)
-                   nil t)
-             (push (cons (match-string 1) (match-string 2)) result))
-           result))))))
+            v "gvfs-info" "--filesystem" (tramp-gvfs-url-file-name filename))
+         (tramp-gvfs-send-command
+          v "gvfs-info" (tramp-gvfs-url-file-name filename)))
+       ;; Parse output.
+       (with-current-buffer (tramp-get-connection-buffer v)
+         (goto-char (point-min))
+         (while (re-search-forward
+                 (if file-system
+                     tramp-gvfs-file-system-attributes-regexp
+                   tramp-gvfs-file-attributes-with-gvfs-info-regexp)
+                 nil t)
+           (push (cons (match-string 1) (match-string 2)) result))
+         result)))))
 
 (defun tramp-gvfs-get-file-attributes (filename)
   "Return GVFS attributes association list of FILENAME."
@@ -1020,123 +1013,122 @@ If FILE-SYSTEM is non-nil, return file system 
attributes."
 (defun tramp-gvfs-handle-file-attributes (filename &optional id-format)
   "Like `file-attributes' for Tramp files."
   (unless id-format (setq id-format 'integer))
-  (ignore-errors
-    (let ((attributes (tramp-gvfs-get-file-attributes filename))
-         dirp res-symlink-target res-numlinks res-uid res-gid res-access
-         res-mod res-change res-size res-filemodes res-inode res-device)
-      (when attributes
-       ;; ... directory or symlink
-       (setq dirp (if (equal "directory" (cdr (assoc "type" attributes))) t))
+  (let ((attributes (tramp-gvfs-get-file-attributes filename))
+       dirp res-symlink-target res-numlinks res-uid res-gid res-access
+       res-mod res-change res-size res-filemodes res-inode res-device)
+    (when attributes
+      ;; ... directory or symlink
+      (setq dirp (if (equal "directory" (cdr (assoc "type" attributes))) t))
+      (setq res-symlink-target
+           (cdr (assoc "standard::symlink-target" attributes)))
+      (when (stringp res-symlink-target)
        (setq res-symlink-target
-             (cdr (assoc "standard::symlink-target" attributes)))
-       (when (stringp res-symlink-target)
-         (setq res-symlink-target
-               ;; Parse unibyte codes "\xNN".  We assume they are
-               ;; non-ASCII codepoints in the range #x80 through #xff.
-               ;; Convert them to multibyte.
-               (decode-coding-string
-                (replace-regexp-in-string
-                 "\\\\x\\([[:xdigit:]]\\{2\\}\\)"
-                 (lambda (x)
-                   (unibyte-string (string-to-number (match-string 1 x) 16)))
-                 res-symlink-target)
-                'utf-8)))
-       ;; ... number links
-       (setq res-numlinks
-             (string-to-number
-              (or (cdr (assoc "unix::nlink" attributes)) "0")))
-       ;; ... uid and gid
-       (setq res-uid
-             (if (eq id-format 'integer)
-                 (string-to-number
-                  (or (cdr (assoc "unix::uid" attributes))
-                      (eval-when-compile
-                        (format "%s" tramp-unknown-id-integer))))
-               (or (cdr (assoc "owner::user" attributes))
-                   (cdr (assoc "unix::uid" attributes))
-                   tramp-unknown-id-string)))
-       (setq res-gid
-             (if (eq id-format 'integer)
-                 (string-to-number
-                  (or (cdr (assoc "unix::gid" attributes))
-                      (eval-when-compile
-                        (format "%s" tramp-unknown-id-integer))))
-               (or (cdr (assoc "owner::group" attributes))
-                   (cdr (assoc "unix::gid" attributes))
-                   tramp-unknown-id-string)))
-       ;; ... last access, modification and change time
-       (setq res-access
-             (seconds-to-time
-              (string-to-number
-               (or (cdr (assoc "time::access" attributes)) "0"))))
-       (setq res-mod
-             (seconds-to-time
-              (string-to-number
-               (or (cdr (assoc "time::modified" attributes)) "0"))))
-       (setq res-change
-             (seconds-to-time
-              (string-to-number
-               (or (cdr (assoc "time::changed" attributes)) "0"))))
-       ;; ... size
-       (setq res-size
-             (string-to-number
-              (or (cdr (assoc "standard::size" attributes)) "0")))
-       ;; ... file mode flags
-       (setq res-filemodes
-             (let ((n (cdr (assoc "unix::mode" attributes))))
-               (if n
-                   (tramp-file-mode-from-int (string-to-number n))
-                 (format
-                  "%s%s%s%s------"
-                  (if dirp "d" (if res-symlink-target "l" "-"))
-                  (if (equal (cdr (assoc "access::can-read" attributes))
-                             "FALSE")
-                      "-" "r")
-                  (if (equal (cdr (assoc "access::can-write" attributes))
-                             "FALSE")
-                      "-" "w")
-                  (if (equal (cdr (assoc "access::can-execute" attributes))
-                             "FALSE")
-                      "-" "x")))))
-       ;; ... inode and device
-       (setq res-inode
-             (let ((n (cdr (assoc "unix::inode" attributes))))
-               (if n
-                   (string-to-number n)
-                 (tramp-get-inode (tramp-dissect-file-name filename)))))
-       (setq res-device
-             (let ((n (cdr (assoc "unix::device" attributes))))
-               (if n
-                   (string-to-number n)
-                 (tramp-get-device (tramp-dissect-file-name filename)))))
-
-       ;; Return data gathered.
-       (list
-        ;; 0. t for directory, string (name linked to) for
-        ;; symbolic link, or nil.
-        (or dirp res-symlink-target)
-        ;; 1. Number of links to file.
-        res-numlinks
-        ;; 2. File uid.
-        res-uid
-        ;; 3. File gid.
-        res-gid
-        ;; 4. Last access time, as a list of integers.
-        ;; 5. Last modification time, likewise.
-        ;; 6. Last status change time, likewise.
-        res-access res-mod res-change
-        ;; 7. Size in bytes (-1, if number is out of range).
-        res-size
-        ;; 8. File modes.
-        res-filemodes
-        ;; 9. t if file's gid would change if file were deleted
-        ;; and recreated.
-        nil
-        ;; 10. Inode number.
-        res-inode
-        ;; 11. Device number.
-        res-device
-        )))))
+             ;; Parse unibyte codes "\xNN".  We assume they are
+             ;; non-ASCII codepoints in the range #x80 through #xff.
+             ;; Convert them to multibyte.
+             (decode-coding-string
+              (replace-regexp-in-string
+               "\\\\x\\([[:xdigit:]]\\{2\\}\\)"
+               (lambda (x)
+                 (unibyte-string (string-to-number (match-string 1 x) 16)))
+               res-symlink-target)
+              'utf-8)))
+      ;; ... number links
+      (setq res-numlinks
+           (string-to-number
+            (or (cdr (assoc "unix::nlink" attributes)) "0")))
+      ;; ... uid and gid
+      (setq res-uid
+           (if (eq id-format 'integer)
+               (string-to-number
+                (or (cdr (assoc "unix::uid" attributes))
+                    (eval-when-compile
+                      (format "%s" tramp-unknown-id-integer))))
+             (or (cdr (assoc "owner::user" attributes))
+                 (cdr (assoc "unix::uid" attributes))
+                 tramp-unknown-id-string)))
+      (setq res-gid
+           (if (eq id-format 'integer)
+               (string-to-number
+                (or (cdr (assoc "unix::gid" attributes))
+                    (eval-when-compile
+                      (format "%s" tramp-unknown-id-integer))))
+             (or (cdr (assoc "owner::group" attributes))
+                 (cdr (assoc "unix::gid" attributes))
+                 tramp-unknown-id-string)))
+      ;; ... last access, modification and change time
+      (setq res-access
+           (seconds-to-time
+            (string-to-number
+             (or (cdr (assoc "time::access" attributes)) "0"))))
+      (setq res-mod
+           (seconds-to-time
+            (string-to-number
+             (or (cdr (assoc "time::modified" attributes)) "0"))))
+      (setq res-change
+           (seconds-to-time
+            (string-to-number
+             (or (cdr (assoc "time::changed" attributes)) "0"))))
+      ;; ... size
+      (setq res-size
+           (string-to-number
+            (or (cdr (assoc "standard::size" attributes)) "0")))
+      ;; ... file mode flags
+      (setq res-filemodes
+           (let ((n (cdr (assoc "unix::mode" attributes))))
+             (if n
+                 (tramp-file-mode-from-int (string-to-number n))
+               (format
+                "%s%s%s%s------"
+                (if dirp "d" (if res-symlink-target "l" "-"))
+                (if (equal (cdr (assoc "access::can-read" attributes))
+                           "FALSE")
+                    "-" "r")
+                (if (equal (cdr (assoc "access::can-write" attributes))
+                           "FALSE")
+                    "-" "w")
+                (if (equal (cdr (assoc "access::can-execute" attributes))
+                           "FALSE")
+                    "-" "x")))))
+      ;; ... inode and device
+      (setq res-inode
+           (let ((n (cdr (assoc "unix::inode" attributes))))
+             (if n
+                 (string-to-number n)
+               (tramp-get-inode (tramp-dissect-file-name filename)))))
+      (setq res-device
+           (let ((n (cdr (assoc "unix::device" attributes))))
+             (if n
+                 (string-to-number n)
+               (tramp-get-device (tramp-dissect-file-name filename)))))
+
+      ;; Return data gathered.
+      (list
+       ;; 0. t for directory, string (name linked to) for
+       ;; symbolic link, or nil.
+       (or dirp res-symlink-target)
+       ;; 1. Number of links to file.
+       res-numlinks
+       ;; 2. File uid.
+       res-uid
+       ;; 3. File gid.
+       res-gid
+       ;; 4. Last access time, as a list of integers.
+       ;; 5. Last modification time, likewise.
+       ;; 6. Last status change time, likewise.
+       res-access res-mod res-change
+       ;; 7. Size in bytes (-1, if number is out of range).
+       res-size
+       ;; 8. File modes.
+       res-filemodes
+       ;; 9. t if file's gid would change if file were deleted
+       ;; and recreated.
+       nil
+       ;; 10. Inode number.
+       res-inode
+       ;; 11. Device number.
+       res-device
+       ))))
 
 (defun tramp-gvfs-handle-file-executable-p (filename)
   "Like `file-executable-p' for Tramp files."
@@ -1186,7 +1178,7 @@ If FILE-SYSTEM is non-nil, return file system attributes."
          (tramp-error
           v 'file-notify-error "Monitoring not supported for `%s'" file-name)
        (tramp-message
-        v 6 "Run `%s', %S" (mapconcat #'identity (process-command p) " ") p)
+        v 6 "Run `%s', %S" (string-join (process-command p) " ") p)
        (process-put p 'vector v)
        (process-put p 'events events)
        (process-put p 'watch-name localname)
@@ -1744,13 +1736,7 @@ This is relevant for GNOME Online Accounts."
     ;; Ensure that GNOME Online Accounts are cached.
     (when (member (tramp-file-name-method vec) tramp-goa-methods)
       (tramp-get-goa-accounts vec))
-    (tramp-get-connection-property
-     (make-tramp-goa-name
-      :method (tramp-file-name-method vec)
-      :user (tramp-file-name-user vec)
-      :host (tramp-file-name-host vec)
-      :port (tramp-file-name-port vec))
-     "prefix" "/")))
+    (tramp-get-connection-property (tramp-make-goa-name vec) "prefix" "/")))
 
 (defun tramp-gvfs-maybe-open-connection (vec)
   "Maybe open a connection VEC.
@@ -1781,15 +1767,24 @@ connection if a previous connection has died for some 
reason."
 
       (when (and (string-equal method "afp")
                 (string-equal localname "/"))
-       (tramp-error vec 'file-error "Filename must contain an AFP volume"))
+       (tramp-user-error vec "Filename must contain an AFP volume"))
 
       (when (and (string-match-p "davs?" method)
                 (string-equal localname "/"))
-       (tramp-error vec 'file-error "Filename must contain a WebDAV share"))
+       (tramp-user-error vec "Filename must contain a WebDAV share"))
 
       (when (and (string-equal method "smb")
                 (string-equal localname "/"))
-       (tramp-error vec 'file-error "Filename must contain a Windows share"))
+       (tramp-user-error vec "Filename must contain a Windows share"))
+
+      (when (member method tramp-goa-methods)
+       ;; Ensure that GNOME Online Accounts are cached.
+       (tramp-get-goa-accounts vec)
+       (when (tramp-get-connection-property
+              (tramp-make-goa-name vec) "FilesDisabled" t)
+         (tramp-user-error
+          vec "There is no Online Account `%s'"
+          (tramp-make-tramp-file-name vec 'noloc))))
 
       (with-tramp-progress-reporter
          vec 3
@@ -1910,6 +1905,15 @@ is applied, and it returns t if the return code is zero."
 
 ;; D-Bus GNOME Online Accounts functions.
 
+(defun tramp-make-goa-name (vec)
+  "Transform VEC into a `tramp-goa-name' structure."
+  (when (tramp-file-name-p vec)
+    (make-tramp-goa-name
+     :method (tramp-file-name-method vec)
+     :user (tramp-file-name-user vec)
+     :host (tramp-file-name-host vec)
+     :port (tramp-file-name-port vec))))
+
 (defun tramp-get-goa-accounts (vec)
   "Retrieve GNOME Online Accounts, and cache them.
 The hash key is a `tramp-goa-name' structure.  The value is an
@@ -1917,52 +1921,55 @@ alist of the properties of 
`tramp-goa-interface-account' and
 `tramp-goa-interface-files' of the corresponding GNOME online
 account.  Additionally, a property \"prefix\" is added.
 VEC is used only for traces."
-  (dolist
-      (object-path
-       (mapcar
-       #'car
-       (tramp-dbus-function
-        vec #'dbus-get-all-managed-objects
-        `(:session ,tramp-goa-service ,tramp-goa-path))))
-    (let* ((account-properties
-           (with-tramp-dbus-get-all-properties vec
-             :session tramp-goa-service object-path
-             tramp-goa-interface-account))
-          (files-properties
-           (with-tramp-dbus-get-all-properties vec
-             :session tramp-goa-service object-path
-             tramp-goa-interface-files))
-          (identity
-           (or (cdr (assoc "PresentationIdentity" account-properties)) ""))
-          key)
-      ;; Only accounts which matter.
-      (when (and
-            (not (cdr (assoc "FilesDisabled" account-properties)))
-            (member
-             (cdr (assoc "ProviderType" account-properties))
-             '("google" "owncloud"))
-            (string-match tramp-goa-identity-regexp identity))
-       (setq key (make-tramp-goa-name
-                  :method (cdr (assoc "ProviderType" account-properties))
-                  :user (match-string 1 identity)
-                  :host (match-string 2 identity)
-                  :port (match-string 3 identity)))
-       (when (string-equal (tramp-goa-name-method key) "google")
-         (setf (tramp-goa-name-method key) "gdrive"))
-       (when (string-equal (tramp-goa-name-method key) "owncloud")
-         (setf (tramp-goa-name-method key) "nextcloud"))
-       ;; Cache all properties.
-       (dolist (prop (nconc account-properties files-properties))
-         (tramp-set-connection-property key (car prop) (cdr prop)))
-       ;; Cache "prefix".
-       (tramp-message
-        vec 10 "%s prefix %s" key
-        (tramp-set-connection-property
-         key "prefix"
-         (directory-file-name
-          (url-filename
-           (url-generic-parse-url
-            (tramp-get-connection-property key "Uri" "file:///"))))))))))
+  (with-tramp-connection-property (tramp-make-goa-name vec) "goa-accounts"
+    (dolist
+       (object-path
+        (mapcar
+         #'car
+         (tramp-dbus-function
+          vec #'dbus-get-all-managed-objects
+          `(:session ,tramp-goa-service ,tramp-goa-path))))
+      (let* ((account-properties
+             (with-tramp-dbus-get-all-properties vec
+               :session tramp-goa-service object-path
+               tramp-goa-interface-account))
+            (files-properties
+             (with-tramp-dbus-get-all-properties vec
+               :session tramp-goa-service object-path
+               tramp-goa-interface-files))
+            (identity
+             (or (cdr (assoc "PresentationIdentity" account-properties)) ""))
+            key)
+       ;; Only accounts which matter.
+       (when (and
+              (not (cdr (assoc "FilesDisabled" account-properties)))
+              (member
+               (cdr (assoc "ProviderType" account-properties))
+               '("google" "owncloud"))
+              (string-match tramp-goa-identity-regexp identity))
+         (setq key (make-tramp-goa-name
+                    :method (cdr (assoc "ProviderType" account-properties))
+                    :user (match-string 1 identity)
+                    :host (match-string 2 identity)
+                    :port (match-string 3 identity)))
+         (when (string-equal (tramp-goa-name-method key) "google")
+           (setf (tramp-goa-name-method key) "gdrive"))
+         (when (string-equal (tramp-goa-name-method key) "owncloud")
+           (setf (tramp-goa-name-method key) "nextcloud"))
+         ;; Cache all properties.
+         (dolist (prop (nconc account-properties files-properties))
+           (tramp-set-connection-property key (car prop) (cdr prop)))
+         ;; Cache "prefix".
+         (tramp-message
+          vec 10 "%s prefix %s" key
+          (tramp-set-connection-property
+           key "prefix"
+           (directory-file-name
+            (url-filename
+             (url-generic-parse-url
+              (tramp-get-connection-property key "Uri" "file:///")))))))))
+    ;; Mark, that goa accounts have been cached.
+    "cached"))
 
 
 ;; D-Bus zeroconf functions.
@@ -1985,15 +1992,12 @@ VEC is used only for traces."
        (list user host)))
    (zeroconf-list-services service)))
 
-;; We use the TRIM argument of `split-string', which exist since Emacs
-;; 24.4.  I mask this for older Emacs versions, there is no harm.
 (defun tramp-gvfs-parse-device-names (service)
   "Return a list of (user host) tuples allowed to access.
 This uses \"avahi-browse\" in case D-Bus is not enabled in Avahi."
   (let ((result
         (ignore-errors
-          (tramp-compat-funcall
-           'split-string
+          (split-string
            (shell-command-to-string (format "avahi-browse -trkp %s" service))
            "[\n\r]+" 'omit "^\\+;.*$"))))
     (delete-dups
@@ -2001,8 +2005,7 @@ This uses \"avahi-browse\" in case D-Bus is not enabled 
in Avahi."
       (lambda (x)
        (let* ((list (split-string x ";"))
               (host (nth 6 list))
-              (text (tramp-compat-funcall
-                     'split-string (nth 9 list) "\" \"" 'omit "\""))
+              (text (split-string (nth 9 list) "\" \"" 'omit "\""))
               user)
          ;; A user is marked in a TXT field like "u=guest".
          (while text
diff --git a/tramp-integration.el b/tramp-integration.el
index 6e3b027..0c706da 100644
--- a/tramp-integration.el
+++ b/tramp-integration.el
@@ -123,18 +123,17 @@ been set up by `rfn-eshadow-setup-minibuffer'."
        (mapconcat
         #'identity (butlast (tramp-compat-exec-path)) path-separator)))
 
-(eval-after-load "esh-util"
-  '(progn
-     (add-hook 'eshell-mode-hook
-              #'tramp-eshell-directory-change)
-     (add-hook 'eshell-directory-change-hook
-              #'tramp-eshell-directory-change)
-     (add-hook 'tramp-integration-unload-hook
-              (lambda ()
-                (remove-hook 'eshell-mode-hook
-                             #'tramp-eshell-directory-change)
-                (remove-hook 'eshell-directory-change-hook
-                             #'tramp-eshell-directory-change)))))
+(with-eval-after-load 'esh-util
+  (add-hook 'eshell-mode-hook
+           #'tramp-eshell-directory-change)
+  (add-hook 'eshell-directory-change-hook
+           #'tramp-eshell-directory-change)
+  (add-hook 'tramp-integration-unload-hook
+           (lambda ()
+             (remove-hook 'eshell-mode-hook
+                          #'tramp-eshell-directory-change)
+             (remove-hook 'eshell-directory-change-hook
+                          #'tramp-eshell-directory-change))))
 
 ;;; Integration of recentf.el:
 
@@ -158,41 +157,36 @@ NAME must be equal to `tramp-current-connection'."
     (let ((recentf-exclude '(file-remote-p)))
       (recentf-cleanup))))
 
-(eval-after-load "recentf"
-  '(progn
-     (add-hook 'tramp-cleanup-connection-hook
-              #'tramp-recentf-cleanup)
-     (add-hook 'tramp-cleanup-all-connections-hook
-              #'tramp-recentf-cleanup-all)
-     (add-hook 'tramp-integration-unload-hook
-              (lambda ()
-                (remove-hook 'tramp-cleanup-connection-hook
-                             #'tramp-recentf-cleanup)
-                (remove-hook 'tramp-cleanup-all-connections-hook
-                             #'tramp-recentf-cleanup-all)))))
+(with-eval-after-load 'recentf
+  (add-hook 'tramp-cleanup-connection-hook
+           #'tramp-recentf-cleanup)
+  (add-hook 'tramp-cleanup-all-connections-hook
+           #'tramp-recentf-cleanup-all)
+  (add-hook 'tramp-integration-unload-hook
+           (lambda ()
+             (remove-hook 'tramp-cleanup-connection-hook
+                          #'tramp-recentf-cleanup)
+             (remove-hook 'tramp-cleanup-all-connections-hook
+                          #'tramp-recentf-cleanup-all))))
 
 ;;; Default connection-local variables for Tramp:
 
 (defconst tramp-connection-local-default-profile
-  ;; `w32-shell-name' is derived from `shell-file-name'.  Don't let it
-  ;; be confused.
-  (unless (eq system-type 'windows-nt)
-    '((shell-file-name . "/bin/sh")
-      (shell-command-switch . "-c")))
+  '((shell-file-name . "/bin/sh")
+    (shell-command-switch . "-c"))
   "Default connection-local variables for remote connections.")
 
 ;; `connection-local-set-profile-variables' and
 ;; `connection-local-set-profiles' exists since Emacs 26.1.
-(eval-after-load "shell"
-  '(progn
-     (tramp-compat-funcall
-      'connection-local-set-profile-variables
-      'tramp-connection-local-default-profile
-      tramp-connection-local-default-profile)
-     (tramp-compat-funcall
-      'connection-local-set-profiles
-      `(:application tramp)
-      'tramp-connection-local-default-profile)))
+(with-eval-after-load 'shell
+  (tramp-compat-funcall
+   'connection-local-set-profile-variables
+   'tramp-connection-local-default-profile
+   tramp-connection-local-default-profile)
+  (tramp-compat-funcall
+   'connection-local-set-profiles
+   `(:application tramp)
+   'tramp-connection-local-default-profile))
 
 (add-hook 'tramp-unload-hook
          (lambda () (unload-feature 'tramp-integration 'force)))
diff --git a/tramp-loaddefs.el b/tramp-loaddefs.el
index cf981ff..0ddfee3 100644
--- a/tramp-loaddefs.el
+++ b/tramp-loaddefs.el
@@ -477,7 +477,7 @@ UU-encode the region between BEG and END.
 ;;;### (autoloads nil "trampver" "trampver.el" (0 0 0 0))
 ;;; Generated autoloads from trampver.el
 
-(defconst tramp-version "0" "\
+(defconst tramp-version "2.4.2" "\
 This version of Tramp.")
 
 (defconst tramp-bug-report-address "address@hidden" "\
diff --git a/tramp-sh.el b/tramp-sh.el
index 34fda5a..cee61f1 100644
--- a/tramp-sh.el
+++ b/tramp-sh.el
@@ -1135,19 +1135,15 @@ component is used as the target of the symlink."
                  (setq thisstep (pop steps))
                  (tramp-message
                   v 5 "Check %s"
-                  (mapconcat #'identity
-                             (append '("") (reverse result) (list thisstep))
-                             "/"))
+                  (string-join
+                   (append '("") (reverse result) (list thisstep)) "/"))
                  (setq symlink-target
                        (tramp-compat-file-attribute-type
                         (file-attributes
                          (tramp-make-tramp-file-name
                           v
-                          (mapconcat #'identity
-                                     (append '("")
-                                             (reverse result)
-                                             (list thisstep))
-                                     "/")
+                          (string-join
+                           (append '("") (reverse result) (list thisstep)) "/")
                           'nohop))))
                  (cond ((string= "." thisstep)
                         (tramp-message v 5 "Ignoring step `.'"))
@@ -1173,12 +1169,8 @@ component is used as the target of the symlink."
                   "Maximum number (%d) of symlinks exceeded" numchase-limit))
                (setq result (reverse result))
                ;; Combine list to form string.
-               (setq result
-                     (if result
-                         (mapconcat #'identity (cons "" result) "/")
-                       "/"))
-               (when (string= "" result)
-                 (setq result "/")))))
+               (setq result (if result (string-join (cons "" result) "/") "/"))
+               (when (string-empty-p result) (setq result "/")))))
 
          ;; Detect cycle.
          (when (and (file-symlink-p filename)
@@ -1993,7 +1985,6 @@ file names."
          (t2 (tramp-tramp-file-p newname))
          (length (tramp-compat-file-attribute-size
                   (file-attributes (file-truename filename))))
-         ;; `file-extended-attributes' exists since Emacs 24.4.
          (attributes (and preserve-extended-attributes
                           (apply #'file-extended-attributes (list filename)))))
 
@@ -2065,7 +2056,6 @@ file names."
 
          ;; Handle `preserve-extended-attributes'.  We ignore possible
          ;; errors, because ACL strings could be incompatible.
-         ;; `set-file-extended-attributes' exists since Emacs 24.4.
          (when attributes
            (ignore-errors
              (apply #'set-file-extended-attributes (list newname attributes))))
@@ -2364,7 +2354,7 @@ The method used must be an out-of-band method."
               (mapcar
                (lambda (x)
                  (setq x (mapcar (lambda (y) (format-spec y spec)) x))
-                 (unless (member "" x) (mapconcat #'identity x " ")))
+                 (unless (member "" x) (string-join x " ")))
                (tramp-get-method-parameter v 'tramp-copy-env)))
 
              remote-copy-program
@@ -3636,8 +3626,8 @@ Fall back to normal file name handler if no Tramp handler 
exists."
          (tramp-error
           v 'file-notify-error
           "`%s' failed to start on remote host"
-          (mapconcat #'identity sequence " "))
-       (tramp-message v 6 "Run `%s', %S" (mapconcat #'identity sequence " ") p)
+          (string-join sequence " "))
+       (tramp-message v 6 "Run `%s', %S" (string-join sequence " ") p)
        (process-put p 'vector v)
        ;; Needed for process filter.
        (process-put p 'events events)
@@ -3699,10 +3689,6 @@ Fall back to normal file name handler if no Tramp 
handler exists."
               (concat remote-prefix file)
               (when file1 (concat remote-prefix file1)))))
        (setq string (replace-match "" nil nil string))
-       ;; Remove watch when file or directory to be watched is deleted.
-       (when (and (member (cl-caadr object) '(moved deleted))
-                  (string-equal file (process-get proc 'watch-name)))
-         (delete-process proc))
        ;; Usually, we would add an Emacs event now.  Unfortunately,
        ;; `unread-command-events' does not accept several events at
        ;; once.  Therefore, we apply the handler directly.
@@ -3754,10 +3740,6 @@ file-notify events."
               (concat remote-prefix file)
               (when file1 (concat remote-prefix file1)))))
        (setq string (replace-match "" nil nil string))
-       ;; Remove watch when file or directory to be watched is deleted.
-       (when (and (member (cl-caadr object) '(moved deleted))
-                  (string-equal file (process-get proc 'watch-name)))
-         (delete-process proc))
        ;; Usually, we would add an Emacs event now.  Unfortunately,
        ;; `unread-command-events' does not accept several events at
        ;; once.  Therefore, we apply the handler directly.
@@ -3794,9 +3776,6 @@ file-notify events."
                  (replace-regexp-in-string "_" "-" (downcase x))))
               (split-string (match-string 1 line) "," 'omit))
              (match-string 3 line))))
-       ;; Remove watch when file or directory to be watched is deleted.
-       (when (member (cl-caadr object) '(move-self delete-self ignored))
-         (delete-process proc))
        ;; Usually, we would add an Emacs event now.  Unfortunately,
        ;; `unread-command-events' does not accept several events at
        ;; once.  Therefore, we apply the handler directly.
@@ -3939,7 +3918,7 @@ This function expects to be in the right *tramp* buffer."
                           "%s\n%s"))
                 progname progname progname
                 tramp-end-of-heredoc
-                (mapconcat #'identity dirlist "\n")
+                (string-join dirlist "\n")
                 tramp-end-of-heredoc))
        (goto-char (point-max))
        (when (search-backward "tramp_executable " nil t)
@@ -3957,8 +3936,8 @@ 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."
   (let ((command
-        (format "PATH=%s; export PATH"
-                (mapconcat #'identity (tramp-get-remote-path vec) ":")))
+        (format
+         "PATH=%s; export PATH" (string-join (tramp-get-remote-path vec) ":")))
        (pipe-buf
         (or (with-tramp-connection-property vec "pipe-buf"
               (tramp-send-command-and-read
@@ -4301,7 +4280,7 @@ process to set up.  VEC specifies the connection."
                     (append `(,(tramp-get-remote-locale vec))
                             (copy-sequence tramp-remote-process-environment))))
        (setq item (split-string item "=" 'omit))
-       (setcdr item (mapconcat #'identity (cdr item) "="))
+       (setcdr item (string-join (cdr item) "="))
        (if (and (stringp (cdr item)) (not (string-equal (cdr item) "")))
            (push (format "%s %s" (car item) (cdr item)) vars)
          (push (car item) unset)))
@@ -4311,12 +4290,12 @@ process to set up.  VEC specifies the connection."
         (format
          "while read var val; do export $var=\"$val\"; done <<'%s'\n%s\n%s"
          tramp-end-of-heredoc
-         (mapconcat #'identity vars "\n")
+         (string-join vars "\n")
          tramp-end-of-heredoc)
         t))
       (when unset
        (tramp-send-command
-        vec (format "unset %s" (mapconcat #'identity unset " ")) t)))))
+        vec (format "unset %s" (string-join unset " ")) t)))))
 
 ;; Old text from documentation of tramp-methods:
 ;; Using a uuencode/uudecode inline method is discouraged, please use one
@@ -4544,6 +4523,7 @@ means discard it)."
     ("env GZIP= gzip" "env GZIP= gzip -d")
     ("bzip2" "bzip2 -d")
     ("xz" "xz -d")
+    ("zstd --rm" "zstd -d --rm")
     ("compress" "compress -d"))
   "List of compress and decompress commands for inline transfer.
 Each item is a list that looks like this:
@@ -4578,9 +4558,11 @@ Goes through the list `tramp-inline-compress-commands'."
                 ;; the pipe symbol be quoted if they use forward
                 ;; slashes as directory separators.
                 (mapconcat
-                 #'shell-quote-argument (split-string compress) " ")
+                 #'tramp-unquote-shell-quote-argument
+                 (split-string compress) " ")
                 (mapconcat
-                 #'shell-quote-argument (split-string decompress) " "))
+                 #'tramp-unquote-shell-quote-argument
+                 (split-string decompress) " "))
                nil nil))
            (throw 'next nil))
          (tramp-message
@@ -4881,8 +4863,7 @@ connection if a previous connection has died for some 
reason."
                (set-process-query-on-exit-flag p nil)
                (setq tramp-current-connection (cons vec (current-time)))
 
-               (tramp-message
-                vec 6 "%s" (mapconcat #'identity (process-command p) " "))
+               (tramp-message vec 6 "%s" (string-join (process-command p) " "))
 
                ;; Check whether process is alive.
                (tramp-barf-if-no-shell-prompt
@@ -4959,7 +4940,7 @@ connection if a previous connection has died for some 
reason."
                       (mapcar
                        (lambda (x)
                          (setq x (mapcar (lambda (y) (format-spec y spec)) x))
-                         (unless (member "" x) (mapconcat #'identity x " ")))
+                         (unless (member "" x) (string-join x " ")))
                        login-env))
                      (while login-env
                        (setq command
@@ -4988,7 +4969,7 @@ connection if a previous connection has died for some 
reason."
                      (mapconcat
                       (lambda (x)
                         (setq x (mapcar (lambda (y) (format-spec y spec)) x))
-                        (unless (member "" x) (mapconcat #'identity x " ")))
+                        (unless (member "" x) (string-join x " ")))
                       login-args " ")
                      ;; Local shell could be a Windows COMSPEC.  It
                      ;; doesn't know the ";" syntax, but we must exit
@@ -5049,7 +5030,7 @@ function waits for output unless NOOUTPUT is set."
       ;; `tramp-echo-mark', so the remote shell sees two consecutive
       ;; trailing line endings and sends two prompts after executing
       ;; the command, which confuses `tramp-wait-for-output'.
-      (when (and (not (string= command ""))
+      (when (and (not (string-empty-p command))
                 (string-equal (substring command -1) "\n"))
        (setq command (substring command 0 -1)))
       ;; No need to restore a trailing newline here since `tramp-send-string'
@@ -5282,8 +5263,9 @@ Return ATTR."
      ((tramp-get-method-parameter vec 'tramp-remote-copy-program)
       localname)
      ((not (zerop (length user)))
-      (format "%s@%s:%s" user host (shell-quote-argument localname)))
-     (t (format "%s:%s" host (shell-quote-argument localname))))))
+      (format
+       "%s@%s:%s" user host (tramp-unquote-shell-quote-argument localname)))
+     (t (format "%s:%s" host (tramp-unquote-shell-quote-argument 
localname))))))
 
 (defun tramp-method-out-of-band-p (vec size)
   "Return t if this is an out-of-band method, nil otherwise."
diff --git a/tramp-smb.el b/tramp-smb.el
index 84725db..695f552 100644
--- a/tramp-smb.el
+++ b/tramp-smb.el
@@ -468,7 +468,8 @@ pass to the OPERATION."
                        (append args
                                (list "-D" (tramp-unquote-shell-quote-argument
                                            localname)
-                                     "-c" (shell-quote-argument "tar qc - *")
+                                     "-c" (tramp-unquote-shell-quote-argument
+                                           "tar qc - *")
                                      "|" "tar" "xfC" "-"
                                      (tramp-unquote-shell-quote-argument
                                       tmpdir)))
@@ -479,7 +480,8 @@ pass to the OPERATION."
                              args
                              (list "-D" (tramp-unquote-shell-quote-argument
                                          localname)
-                                   "-c" (shell-quote-argument "tar qx -")))))
+                                   "-c" (tramp-unquote-shell-quote-argument
+                                         "tar qx -")))))
 
              (unwind-protect
                  (with-temp-buffer
@@ -511,7 +513,7 @@ pass to the OPERATION."
                               tramp-smb-program args)))
 
                      (tramp-message
-                      v 6 "%s" (mapconcat #'identity (process-command p) " "))
+                      v 6 "%s" (string-join (process-command p) " "))
                      (process-put p 'vector v)
                      (process-put p 'adjust-window-size-function #'ignore)
                      (set-process-query-on-exit-flag p nil)
@@ -772,7 +774,7 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are 
completely ignored."
                            tramp-smb-acl-program args)))
 
                    (tramp-message
-                    v 6 "%s" (mapconcat #'identity (process-command p) " "))
+                    v 6 "%s" (string-join (process-command p) " "))
                    (process-put p 'vector v)
                    (process-put p 'adjust-window-size-function #'ignore)
                    (set-process-query-on-exit-flag p nil)
@@ -1256,7 +1258,7 @@ component is used as the target of the symlink."
        (setq outbuf (current-buffer))))
 
       ;; Construct command.
-      (setq command (mapconcat #'identity (cons program args) " ")
+      (setq command (string-join (cons program args) " ")
            command (if input
                        (format
                         "get-content %s | & %s"
@@ -1423,8 +1425,7 @@ component is used as the target of the symlink."
                          (tramp-get-connection-buffer v)
                          tramp-smb-acl-program args)))
 
-                 (tramp-message
-                  v 6 "%s" (mapconcat #'identity (process-command p) " "))
+                 (tramp-message v 6 "%s" (string-join (process-command p) " "))
                  (process-put p 'vector v)
                  (process-put p 'adjust-window-size-function #'ignore)
                  (set-process-query-on-exit-flag p nil)
@@ -1468,7 +1469,7 @@ component is used as the target of the symlink."
                (get-buffer-create buffer)
              ;; BUFFER can be nil.  We use a temporary buffer.
              (generate-new-buffer tramp-temp-buffer-name)))
-          (command (mapconcat #'identity (cons program args) " "))
+          (command (string-join (cons program args) " "))
           (bmp (and (buffer-live-p buffer) (buffer-modified-p buffer)))
           (name1 name)
           (i 0))
@@ -1963,8 +1964,7 @@ If ARGUMENT is non-nil, use it as argument for
                                   tramp-smb-winexe-program tramp-smb-program)
                               args))))
 
-             (tramp-message
-              vec 6 "%s" (mapconcat #'identity (process-command p) " "))
+             (tramp-message vec 6 "%s" (string-join (process-command p) " "))
              (process-put p 'vector vec)
              (process-put p 'adjust-window-size-function #'ignore)
              (set-process-query-on-exit-flag p nil)
@@ -2037,8 +2037,8 @@ Removes smb prompt.  Returns nil if an error message has 
appeared."
 
       ;; Read pending output.
       (while (not (re-search-forward tramp-smb-prompt nil t))
-       (while (tramp-accept-process-output p 0)
-         (goto-char (point-min))))
+       (while (tramp-accept-process-output p 0))
+       (goto-char (point-min)))
       (tramp-message vec 6 "\n%s" (buffer-string))
 
       ;; Remove prompt.
diff --git a/tramp-sudoedit.el b/tramp-sudoedit.el
index f056e73..bbe7800 100644
--- a/tramp-sudoedit.el
+++ b/tramp-sudoedit.el
@@ -232,7 +232,6 @@ absolute file names."
          (file-times (tramp-compat-file-attribute-modification-time
                       (file-attributes filename)))
          (file-modes (tramp-default-file-modes filename))
-         ;; `file-extended-attributes' exists since Emacs 24.4.
          (attributes (and preserve-extended-attributes
                           (apply #'file-extended-attributes (list filename))))
          (sudoedit-operation
@@ -284,7 +283,6 @@ absolute file names."
 
        ;; Handle `preserve-extended-attributes'.  We ignore possible
        ;; errors, because ACL strings could be incompatible.
-       ;; `set-file-extended-attributes' exists since Emacs 24.4.
        (when attributes
          (ignore-errors
            (apply #'set-file-extended-attributes (list newname attributes))))
@@ -660,8 +658,7 @@ component is used as the target of the symlink."
   (with-parsed-tramp-file-name (expand-file-name filename) nil
     (when (and (stringp acl-string) (tramp-sudoedit-remote-acl-p v))
       ;; Massage `acl-string'.
-      (setq acl-string
-           (mapconcat #'identity (split-string acl-string "\n" 'omit) ","))
+      (setq acl-string (string-join (split-string acl-string "\n" 'omit) ","))
       (prog1
          (tramp-sudoedit-send-command
           v "setfacl" "-m"
@@ -830,7 +827,7 @@ in case of error, t otherwise."
           (tramp-verbose (if (= tramp-verbose 3) 2 tramp-verbose))
           ;; We do not want to save the password.
           auth-source-save-behavior)
-      (tramp-message vec 6 "%s" (mapconcat #'identity (process-command p) " "))
+      (tramp-message vec 6 "%s" (string-join (process-command p) " "))
       ;; Avoid process status message in output buffer.
       (set-process-sentinel p #'ignore)
       (process-put p 'vector vec)
diff --git a/tramp.el b/tramp.el
index 6a3dc19..667dc1d 100644
--- a/tramp.el
+++ b/tramp.el
@@ -7,8 +7,8 @@
 ;; Maintainer: Michael Albinus <address@hidden>
 ;; Keywords: comm, processes
 ;; Package: tramp
-;; Version: 0
-;; Package-Requires: ((emacs "24.1"))
+;; Version: 2.4.2
+;; Package-Requires: ((emacs "24.4"))
 ;; URL: https://savannah.gnu.org/projects/tramp
 
 ;; This file is part of GNU Emacs.
@@ -64,7 +64,6 @@
 (require 'cl-lib)
 (declare-function netrc-parse "netrc")
 (defvar auto-save-file-name-transforms)
-(defvar ls-lisp-use-insert-directory-program)
 (defvar outline-regexp)
 
 ;;; User Customizable Internal Variables:
@@ -135,8 +134,10 @@ This setting has precedence over 
`auto-save-file-name-transforms'."
   :type '(choice (const :tag "Use default" nil)
                 (directory :tag "Auto save directory name")))
 
+;; Suppress `shell-file-name' for w32 systems.
 (defcustom tramp-encoding-shell
-  (or (tramp-compat-funcall 'w32-shell-name) "/bin/sh")
+  (let (shell-file-name)
+    (or (tramp-compat-funcall 'w32-shell-name) "/bin/sh"))
   "Use this program for encoding and decoding commands on the local host.
 This shell is used to execute the encoding and decoding command on the
 local host, so if you want to use `~' in those commands, you should
@@ -159,15 +160,19 @@ use for the remote host."
   :group 'tramp
   :type '(file :must-match t))
 
+;; Suppress `shell-file-name' for w32 systems.
 (defcustom tramp-encoding-command-switch
-  (if (tramp-compat-funcall 'w32-shell-dos-semantics) "/c" "-c")
+  (let (shell-file-name)
+    (if (tramp-compat-funcall 'w32-shell-dos-semantics) "/c" "-c"))
   "Use this switch together with `tramp-encoding-shell' for local commands.
 See the variable `tramp-encoding-shell' for more information."
   :group 'tramp
   :type 'string)
 
+;; Suppress `shell-file-name' for w32 systems.
 (defcustom tramp-encoding-command-interactive
-  (unless (tramp-compat-funcall 'w32-shell-dos-semantics) "-i")
+  (let (shell-file-name)
+    (unless (tramp-compat-funcall 'w32-shell-dos-semantics) "-i"))
   "Use this switch together with `tramp-encoding-shell' for interactive shells.
 See the variable `tramp-encoding-shell' for more information."
   :version "24.1"
@@ -567,10 +572,7 @@ This regexp must match both `tramp-initial-end-of-output' 
and
   :type 'regexp)
 
 (defcustom tramp-password-prompt-regexp
-  (format "^.*\\(%s\\).*:\^@? *"
-         ;; `password-word-equivalents' has been introduced with Emacs 24.4.
-          (regexp-opt (or (bound-and-true-p password-word-equivalents)
-                          '("password" "passphrase"))))
+  (format "^.*\\(%s\\).*:\^@? *" (regexp-opt password-word-equivalents))
   "Regexp matching password-like prompts.
 The regexp should match at end of buffer.
 
@@ -1215,7 +1217,9 @@ means to use always cached values for the directory 
contents."
 ;;; Internal Variables:
 
 (defvar tramp-current-connection nil
-  "Last connection timestamp.")
+  "Last connection timestamp.
+It is a cons cell of the actual `tramp-file-name-structure', and
+the (optional) timestamp of last activity on this connection.")
 
 (defvar tramp-password-save-function nil
   "Password save function.
@@ -1720,11 +1724,11 @@ ARGUMENTS to actually emit the message (if applicable)."
                      (regexp-opt
                       '("tramp-backtrace"
                         "tramp-compat-funcall"
-                        "tramp-condition-case-unless-debug"
                         "tramp-debug-message"
                         "tramp-error"
                         "tramp-error-with-buffer"
                         "tramp-message"
+                        "tramp-signal-hook-function"
                         "tramp-user-error")
                       t)
                      "$"))
@@ -1812,7 +1816,7 @@ function is meant for debugging purposes."
 VEC-OR-PROC identifies the connection to use, SIGNAL is the
 signal identifier to be raised, remaining arguments passed to
 `tramp-message'.  Finally, signal SIGNAL is raised."
-  (let (tramp-message-show-message)
+  (let (tramp-message-show-message signal-hook-function)
     (tramp-backtrace vec-or-proc)
     (unless arguments
       ;; FMT-STRING could be just a file name, as in
@@ -1866,12 +1870,9 @@ an input event arrives.  The other arguments are passed 
to `tramp-error'."
 
 ;; We must make it a defun, because it is used earlier already.
 (defun tramp-user-error (vec-or-proc fmt-string &rest arguments)
-  "Signal a pilot error."
+  "Signal a user error (or \"pilot error\")."
   (unwind-protect
-      (apply
-       #'tramp-error vec-or-proc
-       ;; `user-error' has appeared in Emacs 24.3.
-       (if (fboundp 'user-error) 'user-error 'error) fmt-string arguments)
+      (apply #'tramp-error vec-or-proc 'user-error fmt-string arguments)
     ;; Save exit.
     (when (and tramp-message-show-message
               (not (zerop tramp-verbose))
@@ -1901,6 +1902,12 @@ the resulting error message."
          (progn ,@body)
        (error (tramp-message ,vec-or-proc 3 ,format ,err) nil))))
 
+;; This function provides traces in case of errors not triggered by
+;; Tramp functions.
+(defun tramp-signal-hook-function (error-symbol data)
+  "Funtion to be called via `signal-hook-function'."
+  (tramp-error (car tramp-current-connection) error-symbol "%s" data))
+
 (defmacro with-parsed-tramp-file-name (filename var &rest body)
   "Parse a Tramp filename and make components available in the body.
 
@@ -1935,12 +1942,12 @@ If VAR is nil, then we bind `v' to the structure and 
`method', `user',
 (put 'with-parsed-tramp-file-name 'edebug-form-spec '(form symbolp body))
 (font-lock-add-keywords 'emacs-lisp-mode 
'("\\<with-parsed-tramp-file-name\\>"))
 
-(defun tramp-progress-reporter-update (reporter &optional value)
+(defun tramp-progress-reporter-update (reporter &optional value suffix)
   "Report progress of an operation for Tramp."
   (let* ((parameters (cdr reporter))
         (message (aref parameters 3)))
     (when (string-match-p message (or (current-message) ""))
-      (progress-reporter-update reporter value))))
+      (tramp-compat-progress-reporter-update reporter value suffix))))
 
 (defmacro with-tramp-progress-reporter (vec level message &rest body)
   "Executes BODY, spinning a progress reporter with MESSAGE.
@@ -2103,21 +2110,7 @@ value of `default-file-modes', without execute 
permissions."
 (defun tramp-replace-environment-variables (filename)
  "Replace environment variables in FILENAME.
 Return the string with the replaced variables."
- (or (ignore-errors
-       ;; Optional arg has been introduced with Emacs 24.4.
-       (tramp-compat-funcall 'substitute-env-vars filename 'only-defined))
-     ;; We need an own implementation.
-     (save-match-data
-       (let ((idx (string-match "\\$\\(\\w+\\)" filename)))
-        ;; `$' is coded as `$$'.
-        (when (and idx
-                   (or (zerop idx) (not (eq ?$ (aref filename (1- idx)))))
-                   (getenv (match-string 1 filename)))
-          (setq filename
-                (replace-match
-                 (substitute-in-file-name (match-string 0 filename))
-                 t nil filename)))
-        filename))))
+ (substitute-env-vars filename 'only-defined))
 
 (defun tramp-find-file-name-coding-system-alist (filename tmpname)
   "Like `find-operation-coding-system' for Tramp filenames.
@@ -2147,7 +2140,8 @@ pass to the OPERATION."
            .
            ,(and (eq inhibit-file-name-operation operation)
                  inhibit-file-name-handlers)))
-        (inhibit-file-name-operation operation))
+        (inhibit-file-name-operation operation)
+        signal-hook-function)
     (apply operation args)))
 
 ;; We handle here all file primitives.  Most of them have the file
@@ -2257,16 +2251,6 @@ Must be handled by the callers."
                res (cdr elt))))
       res)))
 
-(defvar tramp-debug-on-error nil
-  "Like `debug-on-error' but used Tramp internal.")
-
-(defmacro tramp-condition-case-unless-debug
-  (var bodyform &rest handlers)
-  "Like `condition-case-unless-debug' but `tramp-debug-on-error'."
-  (declare (debug condition-case) (indent 2))
-  `(let ((debug-on-error tramp-debug-on-error))
-     (condition-case-unless-debug ,var ,bodyform ,@handlers)))
-
 ;; In Emacs, there is some concurrency due to timers.  If a timer
 ;; interrupts Tramp and wishes to use the same connection buffer as
 ;; the "main" Emacs, then garbage might occur in the connection
@@ -2324,108 +2308,97 @@ If Emacs is compiled --with-threads, the body is 
protected by a mutex."
            ;; The mutex allows concurrent run of operations.  It
            ;; guarantees, that the threads are not mixed.
            (tramp-compat-with-mutex (tramp-get-mutex v)
-             (let ((completion (tramp-completion-mode-p))
+             (let ((current-connection tramp-current-connection)
                    (foreign
                     (tramp-find-foreign-file-name-handler filename operation))
+                   (signal-hook-function #'tramp-signal-hook-function)
                    result)
+               ;; Set `tramp-current-connection'.
+               (unless
+                   (tramp-file-name-equal-p v (car tramp-current-connection))
+                 (setq tramp-current-connection (list v)))
+
                ;; Call the backend function.
-               (if foreign
-                   (tramp-condition-case-unless-debug err
-                     (let ((sf (symbol-function foreign))
-                           p)
-                       ;; Some packages set the default directory to
-                       ;; a remote path, before respective Tramp
-                       ;; packages are already loaded.  This results
-                       ;; in recursive loading.  Therefore, we load
-                       ;; the Tramp packages locally.
-                       (when (autoloadp sf)
-                         (let ((default-directory
-                                 (tramp-compat-temporary-file-directory))
-                               file-name-handler-alist)
-                           (load (cadr sf) 'noerror 'nomessage)))
-                       ;; (tramp-message
-                       ;;  v 4 "Running `%s'..." (cons operation args))
-                       ;; Switch process thread.
-                       (when (and tramp-mutex
-                                  (setq p (tramp-get-connection-process v)))
-                         (tramp-compat-funcall
-                          'set-process-thread p (tramp-compat-current-thread)))
-                       ;; If `non-essential' is non-nil, Tramp shall
-                       ;; not open a new connection.
-                       ;; If Tramp detects that it shouldn't continue
-                       ;; to work, it throws the `suppress' event.
-                       ;; This could happen for example, when Tramp
-                       ;; tries to open the same connection twice in
-                       ;; a short time frame.
-                       ;; In both cases, we try the default handler
-                       ;; then.
-                       (setq result
-                             (catch 'non-essential
-                               (catch 'suppress
-                                 (when (and tramp-locked (not tramp-locker))
-                                   (setq tramp-locked nil)
-                                   (tramp-error
-                                    (car-safe tramp-current-connection)
-                                    'file-error
-                                    "Forbidden reentrant call of Tramp"))
-                                 (let ((tl tramp-locked))
-                                   (setq tramp-locked t)
-                                   (unwind-protect
-                                       (let ((tramp-locker t))
-                                         (apply foreign operation args))
-                                     (setq tramp-locked tl))))))
-                       ;; (tramp-message
-                       ;;  v 4 "Running `%s'...`%s'" (cons operation args) 
result)
-                       (cond
-                        ((eq result 'non-essential)
-                         (tramp-message
-                          v 5 "Non-essential received in operation %s"
-                          (cons operation args))
-                         (tramp-run-real-handler operation args))
-                        ((eq result 'suppress)
-                         (let (tramp-message-show-message)
+               (unwind-protect
+                   (if foreign
+                       (let ((sf (symbol-function foreign))
+                             p)
+                         ;; Some packages set the default directory
+                         ;; to a remote path, before respective Tramp
+                         ;; packages are already loaded.  This
+                         ;; results in recursive loading.  Therefore,
+                         ;; we load the Tramp packages locally.
+                         (when (autoloadp sf)
+                            ;; FIXME: Not clear why we need these bindings 
here.
+                            ;; The explanation above is not convincing and
+                            ;; the bug#9114 for which it was added doesn't
+                            ;; clarify the core of the problem.
+                           (let ((default-directory
+                                   (tramp-compat-temporary-file-directory))
+                                 file-name-handler-alist)
+                             (autoload-do-load sf foreign)))
+                         ;; (tramp-message
+                         ;;  v 4 "Running `%s'..." (cons operation args))
+                         ;; Switch process thread.
+                         (when (and tramp-mutex
+                                    (setq p (tramp-get-connection-process v)))
+                           (tramp-compat-funcall
+                            'set-process-thread
+                            p (tramp-compat-current-thread)))
+                         ;; If `non-essential' is non-nil, Tramp
+                         ;; shall not open a new connection.
+                         ;; If Tramp detects that it shouldn't
+                         ;; continue to work, it throws the
+                         ;; `suppress' event.  This could happen for
+                         ;; example, when Tramp tries to open the
+                         ;; same connection twice in a short time
+                         ;; frame.
+                         ;; In both cases, we try the default handler
+                         ;; then.
+                         (setq result
+                               (catch 'non-essential
+                                 (catch 'suppress
+                                   (when (and tramp-locked (not tramp-locker))
+                                     (setq tramp-locked nil)
+                                     (tramp-error
+                                      v 'file-error
+                                      "Forbidden reentrant call of Tramp"))
+                                   (let ((tl tramp-locked))
+                                     (setq tramp-locked t)
+                                     (unwind-protect
+                                         (let ((tramp-locker t))
+                                           (apply foreign operation args))
+                                       (setq tramp-locked tl))))))
+                         ;; (tramp-message
+                         ;;  v 4 "Running `%s'...`%s'" (cons operation args) 
result)
+                         (cond
+                          ((eq result 'non-essential)
                            (tramp-message
-                            v 1 "Suppress received in operation %s"
+                            v 5 "Non-essential received in operation %s"
                             (cons operation args))
-                           (tramp-cleanup-connection v t)
-                           (tramp-run-real-handler operation args)))
-                        (t result)))
-
-                     ;; Trace that somebody has interrupted the operation.
-                     ((debug quit)
-                      (let (tramp-message-show-message)
-                        (tramp-message
-                         v 1 "Interrupt received in operation %s"
-                         (cons operation args)))
-                      ;; Propagate the signal.
-                      (signal (car err) (cdr err)))
-
-                     ;; When we are in completion mode, some failed
-                     ;; operations shall return at least a default
-                     ;; value in order to give the user a chance to
-                     ;; correct the file name in the minibuffer.  In
-                     ;; order to get a full backtrace, one could
-                     ;; apply (setq tramp-debug-on-error t)
-                     (error
-                      (cond
-                       ((and completion (zerop (length localname))
-                             (memq operation
-                                   '(file-exists-p file-directory-p)))
-                        t)
-                       ((and completion (zerop (length localname))
-                             (memq operation
-                                   '(expand-file-name file-name-as-directory)))
-                        filename)
-                       ;; Propagate the error.
-                       (t (signal (car err) (cdr err))))))
-
-                 ;; Nothing to do for us.  However, since we are in
-                 ;; `tramp-mode', we must suppress the volume letter
-                 ;; on MS Windows.
-                 (setq result (tramp-run-real-handler operation args))
-                 (if (stringp result)
-                     (tramp-drop-volume-letter result)
-                   result))))))
+                           (tramp-run-real-handler operation args))
+                          ((eq result 'suppress)
+                           (let (tramp-message-show-message)
+                             (tramp-message
+                              v 1 "Suppress received in operation %s"
+                              (cons operation args))
+                             (tramp-cleanup-connection v t)
+                             (tramp-run-real-handler operation args)))
+                          (t result)))
+
+                     ;; Nothing to do for us.  However, since we are
+                     ;; in `tramp-mode', we must suppress the volume
+                     ;; letter on MS Windows.
+                     (setq result (tramp-run-real-handler operation args))
+                     (if (stringp result)
+                         (tramp-drop-volume-letter result)
+                       result))
+
+                 ;; Reset `tramp-current-connection'.
+                 (unless
+                     (tramp-file-name-equal-p
+                      (car current-connection) (car tramp-current-connection))
+                   (setq tramp-current-connection current-connection)))))))
 
       ;; When `tramp-mode' is not enabled, or the file name is quoted,
       ;; we don't do anything.
@@ -3160,9 +3133,8 @@ User is always nil."
   ;; Native `file-equalp-p' calls `file-truename', which requires a
   ;; remote connection.  This can be avoided, if FILENAME1 and
   ;; FILENAME2 are not located on the same remote host.
-  (when (string-equal
-        (file-remote-p (expand-file-name filename1))
-        (file-remote-p (expand-file-name filename2)))
+  (when (tramp-equal-remote
+        (expand-file-name filename1) (expand-file-name filename2))
     (tramp-run-real-handler #'file-equal-p (list filename1 filename2))))
 
 (defun tramp-handle-file-exists-p (filename)
@@ -3174,9 +3146,8 @@ User is always nil."
   ;; Native `file-in-directory-p' calls `file-truename', which
   ;; requires a remote connection.  This can be avoided, if FILENAME
   ;; and DIRECTORY are not located on the same remote host.
-  (when (string-equal
-        (file-remote-p (expand-file-name filename))
-        (file-remote-p (expand-file-name directory)))
+  (when (tramp-equal-remote
+        (expand-file-name filename) (expand-file-name directory))
     (tramp-run-real-handler #'file-in-directory-p (list filename directory))))
 
 (defun tramp-handle-file-local-copy (filename)
@@ -3438,9 +3409,9 @@ User is always nil."
     (access-file filename "Reading directory"))
   (with-parsed-tramp-file-name (expand-file-name filename) nil
     (with-tramp-progress-reporter v 0 (format "Opening directory %s" filename)
-      ;; We must load it in order to get the advice around `insert-directory'.
-      (require 'ls-lisp)
       (let (ls-lisp-use-insert-directory-program start)
+       ;; Silence byte compiler.
+       ls-lisp-use-insert-directory-program
        (tramp-run-real-handler
         #'insert-directory
         (list filename switches wildcard full-directory-p))
@@ -3898,6 +3869,8 @@ of."
   ;; The descriptor must be a process object.
   (unless (processp proc)
     (tramp-error proc 'file-notify-error "Not a valid descriptor %S" proc))
+  ;; There might be pending output.
+  (while (tramp-accept-process-output proc 0))
   (tramp-message proc 6 "Kill %S" proc)
   (delete-process proc))
 
@@ -4107,7 +4080,9 @@ performed successfully.  Any other value means an error."
          (widen)
          (tramp-message vec 6 "\n%s" (buffer-string)))
        (if (eq exit 'ok)
-           (ignore-errors (funcall tramp-password-save-function))
+           (ignore-errors
+             (and (functionp tramp-password-save-function)
+                  (funcall tramp-password-save-function)))
          ;; Not successful.
          (tramp-clear-passwd vec)
          (delete-process proc)
@@ -4194,31 +4169,34 @@ Erase echoed commands if exists."
 Expects the output of PROC to be sent to the current buffer.  Returns
 the string that matched, or nil.  Waits indefinitely if TIMEOUT is
 nil."
-  (with-current-buffer (process-buffer proc)
-    (let ((found (tramp-check-for-regexp proc regexp)))
-      (cond (timeout
-            (with-timeout (timeout)
-              (while (not found)
-                (tramp-accept-process-output proc)
-                (unless (process-live-p proc)
-                  (tramp-error-with-buffer
-                   nil proc 'file-error "Process has died"))
-                (setq found (tramp-check-for-regexp proc regexp)))))
-           (t
+  (let ((found (tramp-check-for-regexp proc regexp)))
+    (cond (timeout
+          (with-timeout (timeout)
             (while (not found)
               (tramp-accept-process-output proc)
               (unless (process-live-p proc)
                 (tramp-error-with-buffer
                  nil proc 'file-error "Process has died"))
               (setq found (tramp-check-for-regexp proc regexp)))))
-      (tramp-message proc 6 "\n%s" (buffer-string))
-      (unless found
-       (if timeout
-           (tramp-error
-            proc 'file-error "[[Regexp `%s' not found in %d secs]]"
-            regexp timeout)
-         (tramp-error proc 'file-error "[[Regexp `%s' not found]]" regexp)))
-      found)))
+         (t
+          (while (not found)
+            (tramp-accept-process-output proc)
+            (unless (process-live-p proc)
+              (tramp-error-with-buffer
+               nil proc 'file-error "Process has died"))
+            (setq found (tramp-check-for-regexp proc regexp)))))
+    ;; The process could have timed out, for example due to session
+    ;; timeout of sudo.  The process buffer does not exist any longer then.
+    (ignore-errors
+      (with-current-buffer (process-buffer proc)
+       (tramp-message proc 6 "\n%s" (buffer-string))))
+    (unless found
+      (if timeout
+         (tramp-error
+          proc 'file-error "[[Regexp `%s' not found in %d secs]]"
+          regexp timeout)
+       (tramp-error proc 'file-error "[[Regexp `%s' not found]]" regexp)))
+    found))
 
 ;; It seems that Tru64 Unix does not like it if long strings are sent
 ;; to it in one go.  (This happens when sending the Perl
@@ -4245,7 +4223,7 @@ the remote host use line-endings as defined in the 
variable
       (setq string
            (mapconcat
             #'identity (split-string string "\n") tramp-rsh-end-of-line))
-      (unless (or (string= string "")
+      (unless (or (string-empty-p string)
                  (string-equal (substring string -1) tramp-rsh-end-of-line))
        (setq string (concat string tramp-rsh-end-of-line)))
       ;; Send the string.
@@ -4301,10 +4279,12 @@ Example:
 
 would yield t.  On the other hand, the following check results in nil:
 
-  (tramp-equal-remote \"/sudo::/etc\" \"/su::/etc\")"
-  (and (tramp-tramp-file-p file1)
-       (tramp-tramp-file-p file2)
-       (string-equal (file-remote-p file1) (file-remote-p file2))))
+  (tramp-equal-remote \"/sudo::/etc\" \"/su::/etc\")
+
+If both files are local, the function returns t."
+  (or (and (null (file-remote-p file1)) (null (file-remote-p file2)))
+      (and (tramp-tramp-file-p file1) (tramp-tramp-file-p file2)
+          (string-equal (file-remote-p file1) (file-remote-p file2)))))
 
 (defun tramp-mode-string-to-int (mode-string)
   "Converts a ten-letter `drwxrwxrwx'-style mode string into mode bits."
@@ -4430,13 +4410,13 @@ If FILENAME is remote, a file name handler is called."
   (let ((handler (find-file-name-handler filename 'tramp-set-file-uid-gid)))
     (if handler
        (funcall handler #'tramp-set-file-uid-gid filename uid gid)
-      ;; On W32 "chown" does not work.
+      ;; On W32 systems, "chown" does not work.
       (unless (memq system-type '(ms-dos windows-nt))
        (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) (shell-quote-argument filename)))))))
+          nil "chown" nil nil nil (format "%d:%d" uid gid)
+          (tramp-unquote-shell-quote-argument filename)))))))
 
 (defun tramp-get-local-uid (id-format)
   "The uid of the local user, in ID-FORMAT.
@@ -4451,12 +4431,10 @@ ID-FORMAT valid values are `string' and `integer'."
   ;; We use key nil for local connection properties.
   (with-tramp-connection-property nil (format "gid-%s" id-format)
     (cond
-     ;; `group-gid' has been introduced with Emacs 24.4.
-     ((and (fboundp 'group-gid) (equal id-format 'integer))
-      (tramp-compat-funcall 'group-gid))
+     ((equal id-format 'integer) (group-gid))
      ;; `group-name' has been introduced with Emacs 27.1.
      ((and (fboundp 'group-name) (equal id-format 'string))
-      (tramp-compat-funcall 'group-name (tramp-compat-funcall 'group-gid)))
+      (tramp-compat-funcall 'group-name (group-gid)))
      ((tramp-compat-file-attribute-group-id
        (file-attributes "~/" id-format))))))
 
@@ -4690,7 +4668,7 @@ are written with verbosity of 6."
        output error result)
     (tramp-message
      vec 6 "`%s %s' %s %s"
-     program (mapconcat #'identity args " ") infile destination)
+     program (string-join args " ") infile destination)
     (condition-case err
        (with-temp-buffer
          (setq result
@@ -4723,7 +4701,7 @@ are written with verbosity of 6."
        result)
     (tramp-message
      vec 6 "`%s %s' %s %s %s %s"
-     program (mapconcat #'identity args " ") start end delete buffer)
+     program (string-join args " ") start end delete buffer)
     (condition-case err
        (progn
          (setq result
@@ -4752,7 +4730,7 @@ verbosity of 6."
        (vec (or vec (car tramp-current-connection)))
        result)
     (if args
-       (tramp-message vec 6 "%s %s" program (mapconcat #'identity args " "))
+       (tramp-message vec 6 "%s %s" program (string-join args " "))
       (tramp-message vec 6 "%s" program))
     (setq result
          (condition-case err
@@ -4854,8 +4832,11 @@ T1 and T2 are time values (as returned by `current-time' 
for example)."
   (float-time (time-subtract t1 t2)))
 
 (defun tramp-unquote-shell-quote-argument (s)
-  "Remove quotation prefix \"/:\" from string S, and quote it then for shell."
-  (shell-quote-argument (tramp-compat-file-name-unquote s)))
+  "Remove quotation prefix \"/:\" from string S, and quote it then for shell.
+Suppress `shell-file-name'.  This is needed on w32 systems, which
+would use a wrong quoting for local file names.  See `w32-shell-name'."
+  (let (shell-file-name)
+    (shell-quote-argument (tramp-compat-file-name-unquote s))))
 
 ;; Currently (as of Emacs 20.5), the function `shell-quote-argument'
 ;; does not deal well with newline characters.  Newline is replaced by
diff --git a/tramp.info b/tramp.info
index f671985..1f416c9 100644
--- a/tramp.info
+++ b/tramp.info
@@ -21,10 +21,11 @@ END-INFO-DIR-ENTRY
 
 File: tramp.info,  Node: Top,  Next: Overview,  Prev: (dir),  Up: (dir)
 
-TRAMP 0 User Manual
-*******************
+TRAMP 2.4.2 User Manual
+***********************
 
-This file documents TRAMP 0, a remote file editing package for Emacs.
+This file documents TRAMP 2.4.2, a remote file editing package for
+Emacs.
 
    TRAMP stands for “Transparent Remote (file) Access, Multiple
 Protocol”.  This package provides remote file editing, similar to Ange
@@ -244,16 +245,32 @@ File: tramp.info,  Node: Obtaining TRAMP,  Next: Quick 
Start Guide,  Prev: Overv
 TRAMP is included as part of Emacs (since Emacs 22.1).
 
    TRAMP is also freely packaged for download on the Internet at
-<https://ftp.gnu.org/gnu/tramp/>.
+<https://ftp.gnu.org/gnu/tramp/>.  The version number of TRAMP can be
+obtained by the variable ‘tramp-version’.  For released TRAMP versions,
+this is a three-number string like “2.4.2”.
+
+   A TRAMP release, which is packaged with Emacs, could differ slightly
+from the corresponding standalone release.  This is because it isn’t
+always possible to synchronize release dates between Emacs and TRAMP.
+Such version numbers have the Emacs version number as suffix, like
+“2.3.5.26.3”.  This means TRAMP 2.3.5 as integrated in Emacs 26.3.  A
+complete list of TRAMP versions packaged with Emacs can be retrieved by
+
+     (assoc 'Tramp customize-package-emacs-version-alist)
 
-   TRAMP is available as GNU ELPA (https://elpa.gnu.org) package.
+   TRAMP is also available as GNU ELPA (https://elpa.gnu.org) package.
+Besides the standalone releases, further minor version of TRAMP will
+appear on GNU ELPA, until the next TRAMP release appears.  These minor
+versions have a four-number string, like “2.4.2.1”.
 
    TRAMP development versions are available on Git servers.  Development
-versions contain new and incomplete features.
+versions contain new and incomplete features.  The development version
+of TRAMP is always the version number of the next release, plus the
+suffix “-pre”, like “2.4.3-pre”.
 
-   One way to obtain from Git server is to visit the Savannah project
-page at the following URL and then clicking on the Git link in the
-navigation bar at the top.
+   One way to obtain TRAMP from Git server is to visit the Savannah
+project page at the following URL and then clicking on the Git link in
+the navigation bar at the top.
 
 <https://savannah.gnu.org/projects/tramp/>
 
@@ -2516,7 +2533,8 @@ They are
 
    • ‘.shar’ — Shell archives
 
-   • ‘.tar’, ‘.tbz’, ‘.tgz’, ‘.tlz’, ‘.txz’ — (Compressed) tape archives
+   • ‘.tar’, ‘.tbz’, ‘.tgz’, ‘.tlz’, ‘.txz’, ‘.tzst’ — (Compressed) tape
+     archives
 
    • ‘.warc’ — Web archives
 
@@ -2531,9 +2549,9 @@ They are
    File archives could also be compressed, identified by an additional
 compression suffix.  Valid compression suffixes are listed in the
 constant ‘tramp-archive-compression-suffixes’.  They are ‘.bz2’, ‘.gz’,
-‘.lrz’, ‘.lz’, ‘.lz4’, ‘.lzma’, ‘.lzo’, ‘.uu’, ‘.xz’ and ‘.Z’.  A valid
-archive file name would be ‘/path/to/dir/file.tar.gz/dir/file’.  Even
-several suffixes in a row are possible, like
+‘.lrz’, ‘.lz’, ‘.lz4’, ‘.lzma’, ‘.lzo’, ‘.uu’, ‘.xz’, ‘.Z’, and ‘.zst’.
+A valid archive file name would be ‘/path/to/dir/file.tar.gz/dir/file’.
+Even several suffixes in a row are possible, like
 ‘/path/to/dir/file.tar.gz.uu/dir/file’.
 
    An archive file name could be a remote file name, as in
@@ -3082,8 +3100,8 @@ File: tramp.info,  Node: Frequently Asked Questions,  
Next: Files directories an
           Since ‘filecache’ remembers visited places, add the remote
           directory to the cache:
 
-               (eval-after-load "filecache"
-                 '(file-cache-add-directory
+               (with-eval-after-load 'filecache
+                 (file-cache-add-directory
                    "/ssh:address@hidden.domain:/opt/news/etc/"))
 
           Then use directory completion in the minibuffer with ‘C-x C-f
@@ -3888,6 +3906,7 @@ Variable Index
 * backup-directory-alist:                Auto-save and Backup.
                                                               (line   6)
 * COLUMNS, environment variable:         Remote processes.    (line 165)
+* customize-package-emacs-version-alist: Obtaining TRAMP.     (line  20)
 * DISPLAY, environment variable:         Remote processes.    (line  93)
 * EDITOR, environment variable:          Frequently Asked Questions.
                                                               (line 536)
@@ -3918,8 +3937,8 @@ Variable Index
 * tramp-actions-before-shell:            Remote shell setup.  (line 102)
 * tramp-adb-connect-if-not-connected:    External methods.    (line 190)
 * tramp-adb-program:                     External methods.    (line 182)
-* tramp-archive-all-gvfs-methods:        Archive file names.  (line  90)
-* tramp-archive-compression-suffixes:    Archive file names.  (line  82)
+* tramp-archive-all-gvfs-methods:        Archive file names.  (line  91)
+* tramp-archive-compression-suffixes:    Archive file names.  (line  83)
 * tramp-archive-suffixes:                Archive file names.  (line  27)
 * tramp-auto-save-directory:             Auto-save and Backup.
                                                               (line  68)
@@ -3970,6 +3989,8 @@ Variable Index
                                                               (line 257)
 * tramp-use-ssh-controlmaster-options:   Frequently Asked Questions.
                                                               (line 197)
+* tramp-verbose:                         Traces and Profiles. (line   6)
+* tramp-version:                         Obtaining TRAMP.     (line   6)
 * tramp-wrong-passwd-regexp:             Remote shell setup.  (line  33)
 
 
@@ -4075,12 +4096,13 @@ Concept Index
 * file archive suffix tgz:               Archive file names.  (line  71)
 * file archive suffix tlz:               Archive file names.  (line  71)
 * file archive suffix txz:               Archive file names.  (line  71)
-* file archive suffix warc:              Archive file names.  (line  72)
-* file archive suffix xar:               Archive file names.  (line  74)
-* file archive suffix xpi:               Archive file names.  (line  76)
-* file archive suffix xps:               Archive file names.  (line  78)
-* file archive suffix zip:               Archive file names.  (line  80)
-* file archive suffix ZIP:               Archive file names.  (line  80)
+* file archive suffix tzst:              Archive file names.  (line  71)
+* file archive suffix warc:              Archive file names.  (line  73)
+* file archive suffix xar:               Archive file names.  (line  75)
+* file archive suffix xpi:               Archive file names.  (line  77)
+* file archive suffix xps:               Archive file names.  (line  79)
+* file archive suffix zip:               Archive file names.  (line  81)
+* file archive suffix ZIP:               Archive file names.  (line  81)
 * file archives:                         Archive file names.  (line   6)
 * file name completion:                  File name completion.
                                                               (line   6)
@@ -4283,78 +4305,79 @@ Concept Index
 * tset unix command:                     Remote shell setup.  (line  92)
 * txz file archive suffix:               Archive file names.  (line  71)
 * type-ahead:                            Usage.               (line  12)
+* tzst file archive suffix:              Archive file names.  (line  71)
 * unix command nc:                       Remote shell setup.  (line 180)
 * unix command tset:                     Remote shell setup.  (line  92)
 * using non-standard methods:            Customizing Methods. (line   6)
 * using TRAMP:                           Usage.               (line   6)
 * uuencode:                              Inline methods.      (line  16)
 * vagrant method:                        Customizing Methods. (line  48)
-* warc file archive suffix:              Archive file names.  (line  72)
+* warc file archive suffix:              Archive file names.  (line  73)
 * winexe:                                Remote processes.    (line 239)
-* xar file archive suffix:               Archive file names.  (line  74)
-* xpi file archive suffix:               Archive file names.  (line  76)
-* xps file archive suffix:               Archive file names.  (line  78)
-* zip file archive suffix:               Archive file names.  (line  80)
-* ZIP file archive suffix:               Archive file names.  (line  80)
+* xar file archive suffix:               Archive file names.  (line  75)
+* xpi file archive suffix:               Archive file names.  (line  77)
+* xps file archive suffix:               Archive file names.  (line  79)
+* zip file archive suffix:               Archive file names.  (line  81)
+* ZIP file archive suffix:               Archive file names.  (line  81)
 
 
 
 Tag Table:
 Node: Top933
-Node: Overview5348
-Node: Obtaining TRAMP10682
-Node: Quick Start Guide12047
-Ref: Quick Start Guide: File name syntax12824
-Ref: Quick Start Guide: ssh and plink methods13926
-Ref: Quick Start Guide: su, sudo and sg methods14470
-Ref: Quick Start Guide: ssh, plink, su, sudo and sg methods15034
-Ref: Quick Start Guide: sudoedit method15564
-Ref: Quick Start Guide: smb method15975
-Ref: Quick Start Guide: GVFS-based methods16306
-Ref: Quick Start Guide: GNOME Online Accounts based methods16718
-Ref: Quick Start Guide: Android17260
-Ref: Quick Start Guide: rclone method17492
-Node: Configuration17819
-Node: Connection types20291
-Node: Inline methods21705
-Node: External methods26368
-Node: GVFS based methods36887
-Node: Default Method39777
-Node: Default User42794
-Node: Default Host44317
-Node: Multi-hops45449
-Node: Firewalls49641
-Node: Customizing Methods51098
-Node: Customizing Completion53438
-Node: Password handling56928
-Ref: Using an authentication file57398
-Ref: Caching passwords58900
-Node: Connection caching59418
-Node: Predefined connection information60348
-Node: Remote programs62693
-Node: Remote shell setup65614
-Node: Android shell setup73824
-Node: Auto-save and Backup76211
-Node: Windows setup hints79286
-Node: Usage80906
-Node: File name syntax82204
-Node: Change file name syntax84211
-Node: File name completion85642
-Node: Ad-hoc multi-hops88715
-Node: Remote processes90781
-Ref: Running a debugger on a remote host99535
-Node: Cleanup remote connections101505
-Node: Archive file names102953
-Node: Bug Reports107312
-Node: Frequently Asked Questions109694
-Node: Files directories and localnames131975
-Node: Localname deconstruction132411
-Node: External packages133064
-Node: Traces and Profiles135109
-Node: GNU Free Documentation License137078
-Node: Function Index162449
-Node: Variable Index165053
-Node: Concept Index171877
+Node: Overview5360
+Node: Obtaining TRAMP10694
+Node: Quick Start Guide13046
+Ref: Quick Start Guide: File name syntax13823
+Ref: Quick Start Guide: ssh and plink methods14925
+Ref: Quick Start Guide: su, sudo and sg methods15469
+Ref: Quick Start Guide: ssh, plink, su, sudo and sg methods16033
+Ref: Quick Start Guide: sudoedit method16563
+Ref: Quick Start Guide: smb method16974
+Ref: Quick Start Guide: GVFS-based methods17305
+Ref: Quick Start Guide: GNOME Online Accounts based methods17717
+Ref: Quick Start Guide: Android18259
+Ref: Quick Start Guide: rclone method18491
+Node: Configuration18818
+Node: Connection types21290
+Node: Inline methods22704
+Node: External methods27367
+Node: GVFS based methods37886
+Node: Default Method40776
+Node: Default User43793
+Node: Default Host45316
+Node: Multi-hops46448
+Node: Firewalls50640
+Node: Customizing Methods52097
+Node: Customizing Completion54437
+Node: Password handling57927
+Ref: Using an authentication file58397
+Ref: Caching passwords59899
+Node: Connection caching60417
+Node: Predefined connection information61347
+Node: Remote programs63692
+Node: Remote shell setup66613
+Node: Android shell setup74823
+Node: Auto-save and Backup77210
+Node: Windows setup hints80285
+Node: Usage81905
+Node: File name syntax83203
+Node: Change file name syntax85210
+Node: File name completion86641
+Node: Ad-hoc multi-hops89714
+Node: Remote processes91780
+Ref: Running a debugger on a remote host100534
+Node: Cleanup remote connections102504
+Node: Archive file names103952
+Node: Bug Reports108340
+Node: Frequently Asked Questions110722
+Node: Files directories and localnames133006
+Node: Localname deconstruction133442
+Node: External packages134095
+Node: Traces and Profiles136140
+Node: GNU Free Documentation License138109
+Node: Function Index163480
+Node: Variable Index166084
+Node: Concept Index173127
 
 End Tag Table
 
diff --git a/trampver.el b/trampver.el
index b82a57a..e3de54b 100644
--- a/trampver.el
+++ b/trampver.el
@@ -31,7 +31,7 @@
 ;; aclocal.m4; should be changed only there.
 
 ;;;###tramp-autoload
-(defconst tramp-version "0"
+(defconst tramp-version "2.4.2"
   "This version of Tramp.")
 
 ;;;###tramp-autoload
@@ -63,9 +63,9 @@
   "The repository revision of the Tramp sources.")
 
 ;; Check for Emacs version.
-(let ((x   (if (not (string-lessp emacs-version "24.1"))
+(let ((x   (if (not (string-lessp emacs-version "24.4"))
       "ok"
-    (format "Tramp 0 is not fit for %s"
+    (format "Tramp 2.4.2 is not fit for %s"
             (replace-regexp-in-string "\n" "" (emacs-version))))))
   (unless (string-equal "ok" x) (error "%s" x)))
 
@@ -83,7 +83,8 @@
         ("2.2.9-24.4" . "24.4") ("2.2.11-24.5" . "24.5")
         ("2.2.13.25.1" . "25.1") ("2.2.13.25.2" . "25.2")
         ("2.2.13.25.2" . "25.3")
-         ("2.3.3" . "26.1") ("2.3.3.26.1" . "26.1") ("2.3.5.26.2" . "26.2")))
+         ("2.3.3" . "26.1") ("2.3.3.26.1" . "26.1") ("2.3.5.26.2" . "26.2")
+         ("2.3.5.26.3" . "26.3")))
 
 (add-hook 'tramp-unload-hook
          (lambda ()



reply via email to

[Prev in Thread] Current Thread [Next in Thread]