branch: externals/tramp commit dbda6788b09afed1b2d3a7aedea93f76466bd7d1 Author: Michael Albinus <michael.albi...@gmx.de> Commit: Michael Albinus <michael.albi...@gmx.de>
Tramp ELPA version 2.5.0.4 released --- test/tramp-tests.el | 40 ++++----- texi/tramp.texi | 53 ++++++----- texi/trampver.texi | 2 +- tramp-archive.el | 6 +- tramp-sh.el | 247 +++++++++++++++++++++++----------------------------- tramp.el | 115 ++++++++++++++---------- trampver.el | 6 +- 7 files changed, 232 insertions(+), 237 deletions(-) diff --git a/test/tramp-tests.el b/test/tramp-tests.el index 3189fa1..99ea62e 100644 --- a/test/tramp-tests.el +++ b/test/tramp-tests.el @@ -59,6 +59,7 @@ (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 ange-ftp-make-backup-files) (defvar auto-save-file-name-transforms) @@ -3097,6 +3098,7 @@ This tests also `file-directory-p' and `file-accessible-directory-p'." (skip-unless (tramp--test-enabled)) (skip-unless (tramp--test-sh-p)) (skip-unless (not (tramp--test-rsync-p))) + (skip-unless (not (tramp--test-windows-nt-and-scp-p))) ;; Wildcards are not supported in tramp-crypt.el. (skip-unless (not (tramp--test-crypt-p))) ;; Since Emacs 26.1. @@ -4369,7 +4371,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'." (delete-file tmp-name)))))) (defun tramp--test-shell-file-name () - "Return default remote shell.." + "Return default remote shell." (if (tramp--test-adb-p) "/system/bin/sh" "/bin/sh")) (ert-deftest tramp-test28-process-file () @@ -5838,18 +5840,18 @@ This requires restrictions of file name syntax." "Check, whether the locale host runs MS Windows." (eq system-type 'windows-nt)) -(defun tramp--test-windows-nt-and-batch-p () - "Check, whether the locale host runs MS Windows in batch mode. -This does not support special characters." - (and (eq system-type 'windows-nt) noninteractive)) +(defun tramp--test-windows-nt-and-out-of-band-p () + "Check, whether the locale host runs MS Windows and an out-of-band method. +This does not support utf8 based file transfer." + (and (eq system-type 'windows-nt) + (tramp-method-out-of-band-p tramp-test-vec 1))) -(defun tramp--test-windows-nt-and-pscp-psftp-p () - "Check, whether the locale host runs MS Windows, and ps{cp,ftp} is used. +(defun tramp--test-windows-nt-and-scp-p () + "Check, whether the locale host runs MS Windows, and scpx? is used. This does not support utf8 based file transfer." (and (eq system-type 'windows-nt) (string-match-p - (regexp-opt '("pscp" "psftp")) - (file-remote-p tramp-test-temporary-file-directory 'method)))) + "^scpx?" (file-remote-p tramp-test-temporary-file-directory 'method)))) (defun tramp--test-windows-nt-or-smb-p () "Check, whether the locale or remote host runs MS Windows. @@ -6112,7 +6114,7 @@ This requires restrictions of file name syntax." "Check special characters in file names." (skip-unless (tramp--test-enabled)) (skip-unless (not (tramp--test-rsync-p))) - (skip-unless (not (tramp--test-windows-nt-and-pscp-psftp-p))) + (skip-unless (not (tramp--test-windows-nt-and-scp-p))) (skip-unless (or (tramp--test-emacs26-p) (not (tramp--test-rclone-p)))) (tramp--test-special-characters)) @@ -6124,7 +6126,7 @@ Use the `stat' command." (skip-unless (tramp--test-enabled)) (skip-unless (tramp--test-sh-p)) (skip-unless (not (tramp--test-rsync-p))) - (skip-unless (not (tramp--test-windows-nt-and-pscp-psftp-p))) + (skip-unless (not (tramp--test-windows-nt-and-scp-p))) ;; We cannot use `tramp-test-vec', because this fails during compilation. (with-parsed-tramp-file-name tramp-test-temporary-file-directory nil (skip-unless (tramp-get-remote-stat v))) @@ -6143,7 +6145,7 @@ Use the `perl' command." (skip-unless (tramp--test-enabled)) (skip-unless (tramp--test-sh-p)) (skip-unless (not (tramp--test-rsync-p))) - (skip-unless (not (tramp--test-windows-nt-and-pscp-psftp-p))) + (skip-unless (not (tramp--test-windows-nt-and-scp-p))) ;; We cannot use `tramp-test-vec', because this fails during compilation. (with-parsed-tramp-file-name tramp-test-temporary-file-directory nil (skip-unless (tramp-get-remote-perl v))) @@ -6165,7 +6167,7 @@ Use the `ls' command." (skip-unless (tramp--test-enabled)) (skip-unless (tramp--test-sh-p)) (skip-unless (not (tramp--test-rsync-p))) - (skip-unless (not (tramp--test-windows-nt-and-pscp-psftp-p))) + (skip-unless (not (tramp--test-windows-nt-and-scp-p))) (let ((tramp-connection-properties (append @@ -6230,8 +6232,7 @@ Use the `ls' command." (skip-unless (tramp--test-enabled)) (skip-unless (not (tramp--test-docker-p))) (skip-unless (not (tramp--test-rsync-p))) - (skip-unless (not (tramp--test-windows-nt-and-batch-p))) - (skip-unless (not (tramp--test-windows-nt-and-pscp-psftp-p))) + (skip-unless (not (tramp--test-windows-nt-and-out-of-band-p))) (skip-unless (not (tramp--test-ksh-p))) (skip-unless (not (tramp--test-gdrive-p))) (skip-unless (not (tramp--test-crypt-p))) @@ -6247,8 +6248,7 @@ Use the `stat' command." (skip-unless (tramp--test-sh-p)) (skip-unless (not (tramp--test-docker-p))) (skip-unless (not (tramp--test-rsync-p))) - (skip-unless (not (tramp--test-windows-nt-and-batch-p))) - (skip-unless (not (tramp--test-windows-nt-and-pscp-psftp-p))) + (skip-unless (not (tramp--test-windows-nt-and-out-of-band-p))) (skip-unless (not (tramp--test-ksh-p))) (skip-unless (not (tramp--test-crypt-p))) ;; We cannot use `tramp-test-vec', because this fails during compilation. @@ -6270,8 +6270,7 @@ Use the `perl' command." (skip-unless (tramp--test-sh-p)) (skip-unless (not (tramp--test-docker-p))) (skip-unless (not (tramp--test-rsync-p))) - (skip-unless (not (tramp--test-windows-nt-and-batch-p))) - (skip-unless (not (tramp--test-windows-nt-and-pscp-psftp-p))) + (skip-unless (not (tramp--test-windows-nt-and-out-of-band-p))) (skip-unless (not (tramp--test-ksh-p))) (skip-unless (not (tramp--test-crypt-p))) ;; We cannot use `tramp-test-vec', because this fails during compilation. @@ -6296,8 +6295,7 @@ Use the `ls' command." (skip-unless (tramp--test-sh-p)) (skip-unless (not (tramp--test-docker-p))) (skip-unless (not (tramp--test-rsync-p))) - (skip-unless (not (tramp--test-windows-nt-and-batch-p))) - (skip-unless (not (tramp--test-windows-nt-and-pscp-psftp-p))) + (skip-unless (not (tramp--test-windows-nt-and-out-of-band-p))) (skip-unless (not (tramp--test-ksh-p))) (skip-unless (not (tramp--test-crypt-p))) diff --git a/texi/tramp.texi b/texi/tramp.texi index 7baf26c..6319a2d 100644 --- a/texi/tramp.texi +++ b/texi/tramp.texi @@ -5067,33 +5067,46 @@ remote files}. @item -I get a warning @samp{Tramp has been compiled with Emacs a.b, this is Emacs c.d} +How to prevent @value{tramp} from clearing the @code{recentf-list}? -@value{tramp} comes with compatibility code for different Emacs -versions. When you see this warning, you don't use the Emacs built-in -version of @value{tramp}. In case you have installed @value{tramp} -from GNU ELPA, you must delete and reinstall it. -@ifset installchapter -In case you have installed it from its Git repository, @ref{Recompilation}. -@end ifset +When @value{tramp} cleans a connection, it removes the respective +remote file name(s) from @code{recentf-list}. This is needed, because +an unresponsive remote host could trigger @code{recentf} to connect +that host again and again. + +If you find the cleanup disturbing, because the file names in +@code{recentf-list} are precious to you, you could add the following +two forms in your @file{~/.emacs} after loading the @code{tramp} and +@code{recentf} packages: +@lisp +@group +(remove-hook + 'tramp-cleanup-connection-hook + #'tramp-recentf-cleanup) +@end group +@group +(remove-hook + 'tramp-cleanup-all-connections-hook + #'tramp-recentf-cleanup-all) +@end group +@end lisp + +@item +I get a warning @samp{Tramp has been compiled with Emacs a.b, this is Emacs c.d} @item I get an error @samp{tramp-file-name-handler: Invalid function: tramp-compat-with-mutex} -Likely, you have a running Emacs session with loaded @value{tramp}, -and you try to upgrade it to another version from GNU ELPA. Since -@value{tramp} is not forward compatible, you must unload / reload it. -Try the following steps: - -@example -@kbd{M-x tramp-unload-tramp @key{RET}} -@kbd{M-x load-library @key{RET} tramp @key{RET}} -@end example - -If this doesn't work, you must restart Emacs with proper -@code{load-path} for the new @value{tramp} version. +@value{tramp} comes with compatibility code for different Emacs +versions. When you see such a message (the text might differ), you +don't use the Emacs built-in version of @value{tramp}. In case you +have installed @value{tramp} from GNU ELPA, see the package README +file for instructions how to recompile it. +@ifset installchapter +@xref{Recompilation}. +@end ifset @item diff --git a/texi/trampver.texi b/texi/trampver.texi index dc41564..168fdb1 100644 --- a/texi/trampver.texi +++ b/texi/trampver.texi @@ -8,7 +8,7 @@ @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.5.0.3 +@set trampver 2.5.0.4 @set trampurl https://www.gnu.org/software/tramp/ @set tramp-bug-report-address tramp-devel@@gnu.org @set emacsver 25.1 diff --git a/tramp-archive.el b/tramp-archive.el index 0bbd927..61c40ff 100644 --- a/tramp-archive.el +++ b/tramp-archive.el @@ -628,10 +628,8 @@ offered." (let ((result (insert-file-contents (tramp-archive-gvfs-file-name filename) visit beg end replace))) - (prog1 - (list (expand-file-name filename) - (cadr result)) - (when visit (setq buffer-file-name filename))))) + (when visit (setq buffer-file-name filename)) + (cons (expand-file-name filename) (cdr result)))) (defun tramp-archive-handle-load (file &optional noerror nomessage nosuffix must-suffix) diff --git a/tramp-sh.el b/tramp-sh.el index 1764f2e..b51ba11 100644 --- a/tramp-sh.el +++ b/tramp-sh.el @@ -103,12 +103,12 @@ detected as prompt when being sent on echoing hosts, therefore.") (defconst tramp-end-of-heredoc (md5 tramp-end-of-output) "String used to recognize end of heredoc strings.") -(defcustom tramp-use-ssh-controlmaster-options t +(defcustom tramp-use-ssh-controlmaster-options (not (eq system-type 'windows-nt)) "Whether to use `tramp-ssh-controlmaster-options'. Set it to nil, if you use Control* or Proxy* options in your ssh configuration." :group 'tramp - :version "24.4" + :version "28.1" :type 'boolean) (defvar tramp-ssh-controlmaster-options nil @@ -169,7 +169,8 @@ The string is used in `tramp-methods'.") (tramp-login-program "ssh") (tramp-login-args (("-l" "%u") ("-p" "%p") ("%c") ("-e" "none") ("-t" "-t") - ("-o" "RemoteCommand='%l'") ("%h"))) + ("-o" "RemoteCommand=\"%l\"") + ("%h"))) (tramp-async-args (("-q"))) (tramp-remote-shell ,tramp-default-remote-shell) (tramp-remote-shell-login ("-l")) @@ -225,7 +226,8 @@ The string is used in `tramp-methods'.") (tramp-login-program "ssh") (tramp-login-args (("-l" "%u") ("-p" "%p") ("%c") ("-e" "none") ("-t" "-t") - ("-o" "RemoteCommand='%l'") ("%h"))) + ("-o" "RemoteCommand=\"%l\"") + ("%h"))) (tramp-async-args (("-q"))) (tramp-remote-shell ,tramp-default-remote-shell) (tramp-remote-shell-login ("-l")) @@ -399,16 +401,34 @@ The string is used in `tramp-methods'.") ;;;###tramp-autoload (defconst tramp-completion-function-alist-ssh - '((tramp-parse-rhosts "/etc/hosts.equiv") + `((tramp-parse-rhosts "/etc/hosts.equiv") (tramp-parse-rhosts "/etc/shosts.equiv") - (tramp-parse-shosts "/etc/ssh_known_hosts") - (tramp-parse-sconfig "/etc/ssh_config") + ;; On W32 systems, the ssh directory is located somewhere else. + (tramp-parse-shosts ,(expand-file-name + "ssh/ssh_known_hosts" + (or (and (eq system-type 'windows-nt) + (getenv "ProgramData")) + "/etc/"))) + (tramp-parse-sconfig ,(expand-file-name + "ssh/ssh_config" + (or (and (eq system-type 'windows-nt) + (getenv "ProgramData")) + "/etc/"))) (tramp-parse-shostkeys "/etc/ssh2/hostkeys") (tramp-parse-sknownhosts "/etc/ssh2/knownhosts") (tramp-parse-rhosts "~/.rhosts") (tramp-parse-rhosts "~/.shosts") - (tramp-parse-shosts "~/.ssh/known_hosts") - (tramp-parse-sconfig "~/.ssh/config") + ;; On W32 systems, the .ssh directory is located somewhere else. + (tramp-parse-shosts ,(expand-file-name + ".ssh/known_hosts" + (or (and (eq system-type 'windows-nt) + (getenv "USERPROFILE")) + "~/"))) + (tramp-parse-sconfig ,(expand-file-name + ".ssh/config" + (or (and (eq system-type 'windows-nt) + (getenv "USERPROFILE")) + "~/"))) (tramp-parse-shostkeys "~/.ssh2/hostkeys") (tramp-parse-sknownhosts "~/.ssh2/knownhosts")) "Default list of (FUNCTION FILE) pairs to be examined for ssh methods.") @@ -431,7 +451,7 @@ The string is used in `tramp-methods'.") ;;;###tramp-autoload (defconst tramp-completion-function-alist-putty `((tramp-parse-putty - ,(if (memq system-type '(windows-nt)) + ,(if (eq system-type 'windows-nt) "HKEY_CURRENT_USER\\Software\\SimonTatham\\PuTTY\\Sessions" "~/.putty/sessions"))) "Default list of (FUNCTION REGISTRY) pairs to be examined for putty sessions.") @@ -941,7 +961,7 @@ Format specifiers \"%s\" are replaced before the script is used.") (file-name-directory . tramp-handle-file-name-directory) (file-name-nondirectory . tramp-handle-file-name-nondirectory) ;; `file-name-sans-versions' performed by default handler. - (file-newer-than-file-p . tramp-sh-handle-file-newer-than-file-p) + (file-newer-than-file-p . tramp-handle-file-newer-than-file-p) (file-notify-add-watch . tramp-sh-handle-file-notify-add-watch) (file-notify-rm-watch . tramp-handle-file-notify-rm-watch) (file-notify-valid-p . tramp-handle-file-notify-valid-p) @@ -1549,49 +1569,6 @@ ID-FORMAT valid values are `string' and `integer'." (or (tramp-check-cached-permissions v ?r) (tramp-run-test "-r" filename))))) -;; When the remote shell is started, it looks for a shell which groks -;; tilde expansion. Here, we assume that all shells which grok tilde -;; expansion will also provide a `test' command which groks `-nt' (for -;; newer than). If this breaks, tell me about it and I'll try to do -;; something smarter about it. -(defun tramp-sh-handle-file-newer-than-file-p (file1 file2) - "Like `file-newer-than-file-p' for Tramp files." - (cond ((not (file-exists-p file1)) nil) - ((not (file-exists-p file2)) t) - (t ;; We are sure both files exist at this point. We try to - ;; get the mtime of both files. If they are not equal to - ;; the "dont-know" value, then we subtract the times and - ;; obtain the result. - (let ((fa1 (file-attributes file1)) - (fa2 (file-attributes file2))) - (if (and - (not - (tramp-compat-time-equal-p - (tramp-compat-file-attribute-modification-time fa1) - tramp-time-dont-know)) - (not - (tramp-compat-time-equal-p - (tramp-compat-file-attribute-modification-time fa2) - tramp-time-dont-know))) - (time-less-p - (tramp-compat-file-attribute-modification-time fa2) - (tramp-compat-file-attribute-modification-time fa1)) - ;; If one of them is the dont-know value, then we can - ;; still try to run a shell command on the remote host. - ;; However, this only works if both files are Tramp - ;; files and both have the same method, same user, same - ;; host. - (unless (tramp-equal-remote file1 file2) - (with-parsed-tramp-file-name - (if (tramp-tramp-file-p file1) file1 file2) nil - (tramp-error - v 'file-error - "Files %s and %s must have same method, user, host" - file1 file2))) - (with-parsed-tramp-file-name file1 nil - (tramp-run-test2 - (tramp-get-test-nt-command v) file1 file2))))))) - ;; Functions implemented using the basic functions above. (defun tramp-sh-handle-file-directory-p (filename) @@ -2241,7 +2218,7 @@ The method used must be an out-of-band method." (t2 (tramp-tramp-file-p newname)) (orig-vec (tramp-dissect-file-name (if t1 filename newname))) copy-program copy-args copy-env copy-keep-date listener spec - options source target remote-copy-program remote-copy-args) + options source target remote-copy-program remote-copy-args p) (with-parsed-tramp-file-name (if t1 filename newname) nil (if (and t1 t2) @@ -2276,10 +2253,10 @@ The method used must be an out-of-band method." #'identity) (if t1 (tramp-make-copy-program-file-name v) - (tramp-unquote-shell-quote-argument filename))) + (tramp-compat-file-name-unquote filename))) target (if t2 (tramp-make-copy-program-file-name v) - (tramp-unquote-shell-quote-argument newname))) + (tramp-compat-file-name-unquote newname))) ;; Check for user. There might be an interactive setting. (setq user (or (tramp-file-name-user v) @@ -2311,6 +2288,13 @@ The method used must be an out-of-band method." ;; keep-date argument is non-nil), or a replacement for ;; the whole keep-date sublist. (delete " " (apply #'tramp-expand-args v 'tramp-copy-args spec)) + ;; `tramp-ssh-controlmaster-options' is a string instead + ;; of a list. Unflatten it. + copy-args + (tramp-compat-flatten-tree + (mapcar + (lambda (x) (if (string-match-p " " x) (split-string x) x)) + copy-args)) copy-env (apply #'tramp-expand-args v 'tramp-copy-env spec) remote-copy-program (tramp-get-method-parameter v 'tramp-remote-copy-program) @@ -2372,31 +2356,26 @@ The method used must be an out-of-band method." copy-args (if remote-copy-program (list (if t1 (concat ">" target) (concat "<" source))) - (list source target)))) - - ;; Use an asynchronous process. By this, password can - ;; be handled. We don't set a timeout, because the - ;; copying of large files can last longer than 60 secs. - (let* ((command - (mapconcat - #'identity (append (list copy-program) copy-args) - " ")) - (p (let ((default-directory - (tramp-compat-temporary-file-directory))) - (start-process-shell-command - (tramp-get-connection-name v) - (tramp-get-connection-buffer v) - command)))) - (tramp-message orig-vec 6 "%s" command) - (process-put p 'vector orig-vec) - (process-put p 'adjust-window-size-function #'ignore) - (set-process-query-on-exit-flag p nil) - - ;; We must adapt `tramp-local-end-of-line' for - ;; sending the password. - (let ((tramp-local-end-of-line tramp-rsh-end-of-line)) - (tramp-process-actions - p v nil tramp-actions-copy-out-of-band)))) + (list source target))) + ;; Use an asynchronous process. By this, password + ;; can be handled. We don't set a timeout, because + ;; the copying of large files can last longer than 60 + ;; secs. + p (apply + #'start-process + (tramp-get-connection-name v) + (tramp-get-connection-buffer v) + copy-program copy-args)) + (tramp-message orig-vec 6 "%s" (string-join (process-command p) " ")) + (process-put p 'vector orig-vec) + (process-put p 'adjust-window-size-function #'ignore) + (set-process-query-on-exit-flag p nil) + + ;; We must adapt `tramp-local-end-of-line' for + ;; sending the password. + (let ((tramp-local-end-of-line tramp-rsh-end-of-line)) + (tramp-process-actions + p v nil tramp-actions-copy-out-of-band))) ;; Reset the transfer process properties. (tramp-flush-connection-property v "process-name") @@ -2584,12 +2563,9 @@ The method used must be an out-of-band method." (save-restriction (narrow-to-region beg-marker end-marker) ;; Check for "--dired" output. - (forward-line -2) - (when (looking-at-p "//SUBDIRED//") - (forward-line -1)) - (when (looking-at "//DIRED//\\s-+") - (let ((beg (match-end 0)) - (end (point-at-eol))) + (when (re-search-backward "^//DIRED//\\s-+\\(.+\\)$" nil 'noerror) + (let ((beg (match-beginning 1)) + (end (match-end 0))) ;; Now read the numeric positions of file names. (goto-char beg) (while (< (point) end) @@ -2599,7 +2575,7 @@ The method used must be an out-of-band method." ;; End is followed by \n or by " -> ". (put-text-property start end 'dired-filename t)))))) ;; Remove trailing lines. - (goto-char (point-at-bol)) + (beginning-of-line) (while (looking-at "//") (forward-line 1) (delete-region (match-beginning 0) (point)))) @@ -2947,15 +2923,19 @@ alternative implementation will be used." ;; until the process is deleted. (when (bufferp stderr) (with-current-buffer stderr - (insert-file-contents-literally remote-tmpstderr)) + ;; There's a mysterious error, see + ;; <https://github.com/joaotavora/eglot/issues/662>. + (ignore-errors + (insert-file-contents-literally remote-tmpstderr))) ;; Delete tmpstderr file. (add-function :after (process-sentinel p) (lambda (_proc _msg) (when (file-exists-p remote-tmpstderr) (with-current-buffer stderr - (insert-file-contents-literally - remote-tmpstderr nil nil nil 'replace)) + (ignore-errors + (insert-file-contents-literally + remote-tmpstderr nil nil nil 'replace))) (delete-file remote-tmpstderr))))) ;; Return process. p))) @@ -3728,7 +3708,8 @@ Fall back to normal file name handler if no Tramp handler exists." (remote-prefix (with-current-buffer (process-buffer proc) (file-remote-p default-directory))) - (rest-string (process-get proc 'rest-string))) + (rest-string (process-get proc 'rest-string)) + pos) (when rest-string (tramp-message proc 10 "Previous string:\n%s" rest-string)) (tramp-message proc 6 "%S\n%s" proc string) @@ -3750,23 +3731,27 @@ Fall back to normal file name handler if no Tramp handler exists." ;; Determine monitor name. (unless (tramp-connection-property-p proc "gio-file-monitor") - (cond - ;; We have seen this only on cygwin gio, which uses the - ;; GPollFileMonitor. - ((string-match - "Can't find module 'help' specified in GIO_USE_FILE_MONITOR" string) - (tramp-set-connection-property - proc "gio-file-monitor" 'GPollFileMonitor)) - ;; TODO: What happens, if several monitor names are reported? - ((string-match "\ + (tramp-set-connection-property + proc "gio-file-monitor" + (cond + ;; We have seen this on cygwin gio and on emba. Let's make + ;; some assumptions. + ((string-match + "Can't find module 'help' specified in GIO_USE_FILE_MONITOR" string) + (setq pos (match-end 0)) + (cond + ((getenv "EMACS_EMBA_CI") 'GInotifyFileMonitor) + ((eq system-type 'cygwin) 'GPollFileMonitor) + (t nil))) + ;; TODO: What happens, if several monitor names are reported? + ((string-match "\ Supported arguments for GIO_USE_FILE_MONITOR environment variable: \\s-*\\([[:alpha:]]+\\) - 20" string) - (tramp-set-connection-property - proc "gio-file-monitor" + (setq pos (match-end 0)) (intern - (format "G%sFileMonitor" (capitalize (match-string 1 string)))))) - (t (throw 'doesnt-work nil))) - (setq string (replace-match "" nil nil string))) + (format "G%sFileMonitor" (capitalize (match-string 1 string))))) + (t (setq pos (length string)) nil))) + (setq string (substring string pos))) ;; Delete empty lines. (setq string (tramp-compat-string-replace "\n\n" "\n" string)) @@ -3800,6 +3785,8 @@ Supported arguments for GIO_USE_FILE_MONITOR environment variable: `(file-notify ,object file-notify-callback)))))) ;; Save rest of the string. + (while (string-match "^\n" string) + (setq string (replace-match "" nil nil string))) (when (zerop (length string)) (setq string nil)) (when string (tramp-message proc 10 "Rest string:\n%s" string)) (process-put proc 'rest-string string))) @@ -3949,24 +3936,6 @@ Returns the exit code of the `test' program." switch (tramp-shell-quote-argument localname))))) -(defun tramp-run-test2 (format-string file1 file2) - "Run `test'-like program on the remote system, given FILE1, FILE2. -FORMAT-STRING contains the program name, switches, and place holders. -Returns the exit code of the `test' program. Barfs if the methods, -hosts, or files, disagree." - (unless (tramp-equal-remote file1 file2) - (with-parsed-tramp-file-name (if (tramp-tramp-file-p file1) file1 file2) nil - (tramp-error - v 'file-error - "tramp-run-test2 only implemented for same method, user, host"))) - (with-parsed-tramp-file-name file1 v1 - (with-parsed-tramp-file-name file1 v2 - (tramp-send-command-and-check - v1 - (format format-string - (tramp-shell-quote-argument v1-localname) - (tramp-shell-quote-argument v2-localname)))))) - (defconst tramp-sunos-unames (regexp-opt '("SunOS 5.10" "SunOS 5.11")) "Regexp to determine remote SunOS.") @@ -4972,11 +4941,7 @@ connection if a previous connection has died for some reason." ?h (or l-host "") ?u (or l-user "") ?p (or l-port "") ?c (format-spec options (format-spec-make ?t tmpfile)) ?l (concat remote-shell " " extra-args " -i")) - ;; Local shell could be a Windows COMSPEC. It - ;; doesn't know the ";" syntax, but we must - ;; exit always for `start-file-process'. It - ;; could also be a restricted shell, which does - ;; not allow "exec". + ;; A restricted shell does not allow "exec". (when r-shell '("&&" "exit" "||" "exit"))) " ")) @@ -5264,15 +5229,17 @@ Return ATTR." (directory-file-name (tramp-file-name-unquote-localname vec)))) (when (string-match-p tramp-ipv6-regexp host) (setq host (format "[%s]" host))) + ;; This does not work yet for MS Windows scp, if there are + ;; characters to be quoted. Win32 OpenSSH 7.9 is said to support + ;; this, see + ;; <https://github.com/PowerShell/Win32-OpenSSH/releases/tag/v7.9.0.0p1-Beta> (unless (string-match-p "ftp$" method) (setq localname (tramp-shell-quote-argument localname))) (cond ((tramp-get-method-parameter vec 'tramp-remote-copy-program) localname) - ((not (zerop (length user))) - (format - "%s@%s:%s" user host (tramp-unquote-shell-quote-argument localname))) - (t (format "%s:%s" host (tramp-unquote-shell-quote-argument localname)))))) + ((zerop (length user)) (format "%s:%s" host localname)) + (t (format "%s@%s:%s" user host localname))))) (defun tramp-method-out-of-band-p (vec size) "Return t if this is an out-of-band method, nil otherwise." @@ -5523,15 +5490,15 @@ Nonexistent directories are removed from spec." ;; Check whether stat(1) returns usable syntax. "%s" does not ;; work on older AIX systems. Recent GNU stat versions ;; (8.24?) use shell quoted format for "%N", we check the - ;; boundaries "`" and "'", therefore. See Bug#23422 in - ;; coreutils. Since GNU stat 8.26, environment variable - ;; QUOTING_STYLE is supported. + ;; boundaries "`" and "'" and their localized variants, + ;; therefore. See Bug#23422 in coreutils. Since GNU stat + ;; 8.26, environment variable QUOTING_STYLE is supported. (when result (setq result (concat "env QUOTING_STYLE=locale " result) tmp (tramp-send-command-and-read vec (format "%s -c '(\"%%N\" %%s)' /" result) 'noerror)) (unless (and (listp tmp) (stringp (car tmp)) - (string-match-p "^\\(`/'\\|‘/’\\)$" (car tmp)) + (string-match-p "^[\"`‘„”«「]/[\"'’“”»」]$" (car tmp)) (integerp (cadr tmp))) (setq result nil))) result)))) @@ -5825,7 +5792,7 @@ function cell is returned to be applied on a buffer." ;; slashes as directory separators. (cond ((and (string-match-p "local" prop) - (memq system-type '(windows-nt))) + (eq system-type 'windows-nt)) "(%s | \"%s\")") ((string-match-p "local" prop) "(%s | %s)") (t "(%s | %s >%%s)")) @@ -5836,7 +5803,7 @@ function cell is returned to be applied on a buffer." ;; the pipe symbol be quoted if they use forward ;; slashes as directory separators. (if (and (string-match-p "local" prop) - (memq system-type '(windows-nt))) + (eq system-type 'windows-nt)) "(%s <%%s | \"%s\")" "(%s <%%s | %s)") compress coding)) diff --git a/tramp.el b/tramp.el index de7d758..499789b 100644 --- a/tramp.el +++ b/tramp.el @@ -64,8 +64,7 @@ (declare-function netrc-parse "netrc") (defvar auto-save-file-name-transforms) -;; Reload `tramp-compat` when we reload `tramp-autoloads' of the GNU -;; ELPA package. +;; Reload `tramp-compat' when we reload `tramp-autoloads' of the GNU ELPA package. ;;;###autoload (when (featurep 'tramp-compat) ;;;###autoload (load "tramp-compat" 'noerror 'nomessage)) @@ -359,12 +358,13 @@ Notes: All these arguments can be overwritten by connection properties. See Info node `(tramp) Predefined connection information'. -When using `su' or `sudo' the phrase \"open connection to a remote -host\" sounds strange, but it is used nevertheless, for consistency. -No connection is opened to a remote host, but `su' or `sudo' is -started on the local host. You should specify a remote host -`localhost' or the name of the local host. Another host name is -useful only in combination with `tramp-default-proxies-alist'.") +When using `su', `sudo' or `doas' the phrase \"open connection to +a remote host\" sounds strange, but it is used nevertheless, for +consistency. No connection is opened to a remote host, but `su', +`sudo' or `doas' is started on the local host. You should +specify a remote host `localhost' or the name of the local host. +Another host name is useful only in combination with +`tramp-default-proxies-alist'.") (defcustom tramp-default-method ;; An external copy method seems to be preferred, because it performs @@ -492,7 +492,7 @@ interpreted as a regular expression which always matches." ;; either lower case or upper case letters. See ;; <https://debbugs.gnu.org/cgi/bugreport.cgi?bug=38079#20>. (defcustom tramp-restricted-shell-hosts-alist - (when (memq system-type '(windows-nt)) + (when (eq system-type 'windows-nt) (list (format "\\`\\(%s\\|%s\\)\\'" (regexp-quote (downcase tramp-system-name)) (regexp-quote (upcase tramp-system-name))))) @@ -562,7 +562,7 @@ usually suffice.") the remote shell.") (defcustom tramp-local-end-of-line - (if (memq system-type '(windows-nt)) "\r\n" "\n") + (if (eq system-type 'windows-nt) "\r\n" "\n") "String used for end of line in local processes." :version "24.1" :type 'string) @@ -1082,7 +1082,13 @@ initial value is overwritten by the car of `tramp-file-name-structure'.") (defconst tramp-completion-file-name-regexp-default (concat - "\\`/\\(" + "\\`" + ;; `file-name-completion' uses absolute paths for matching. This + ;; means that on W32 systems, something like "/ssh:host:~/path" + ;; becomes "c:/ssh:host:~/path". See also `tramp-drop-volume-letter'. + (when (eq system-type 'windows-nt) + "\\(?:[[:alpha:]]:\\)?") + "/\\(" ;; Optional multi hop. "\\([^/|:]+:[^/|:]*|\\)*" ;; Last hop. @@ -1101,7 +1107,13 @@ On W32 systems, the volume letter must be ignored.") (defconst tramp-completion-file-name-regexp-simplified (concat - "\\`/\\(" + "\\`" + ;; Allow the volume letter at the beginning of the path. See the + ;; comment in `tramp-completion-file-name-regexp-default' for more + ;; details. + (when (eq system-type 'windows-nt) + "\\(?:[[:alpha:]]:\\)?") + "/\\(" ;; Optional multi hop. "\\([^/|:]*|\\)*" ;; Last hop. @@ -1117,7 +1129,14 @@ See `tramp-file-name-structure' for more explanations. On W32 systems, the volume letter must be ignored.") (defconst tramp-completion-file-name-regexp-separate - "\\`/\\(\\[[^]]*\\)?\\'" + (concat + "\\`" + ;; Allow the volume letter at the beginning of the path. See the + ;; comment in `tramp-completion-file-name-regexp-default' for more + ;; details. + (when (eq system-type 'windows-nt) + "\\(?:[[:alpha:]]:\\)?") + "/\\(\\[[^]]*\\)?\\'") "Value for `tramp-completion-file-name-regexp' for separate remoting. See `tramp-file-name-structure' for more explanations.") @@ -1813,6 +1832,7 @@ The outline level is equal to the verbosity of the Tramp message." "Get the debug buffer for VEC." (with-current-buffer (get-buffer-create (tramp-debug-buffer-name vec)) (when (bobp) + (set-buffer-file-coding-system 'utf-8) (setq buffer-undo-list t) ;; Activate `outline-mode'. This runs `text-mode-hook' and ;; `outline-mode-hook'. We must prevent that local processes @@ -1853,7 +1873,7 @@ ARGUMENTS to actually emit the message (if applicable)." (when (bobp) (insert (format - ";; Emacs: %s Tramp: %s -*- mode: outline; -*-" + ";; Emacs: %s Tramp: %s -*- mode: outline; coding: utf-8; -*-" emacs-version tramp-version)) (when (>= tramp-verbose 10) (let ((tramp-verbose 0)) @@ -2176,14 +2196,15 @@ without a visible progress reporter." FILE must be a local file name on a connection identified via VEC." (declare (indent 3) (debug t)) `(if (file-name-absolute-p ,file) - (let ((value (tramp-get-file-property ,vec ,file ,property 'undef))) - (when (eq value 'undef) - ;; We cannot pass @body as parameter to - ;; `tramp-set-file-property' because it mangles our - ;; debug messages. - (setq value (progn ,@body)) - (tramp-set-file-property ,vec ,file ,property value)) - value) + (let ((value (tramp-get-file-property + ,vec ,file ,property tramp-cache-undefined))) + (when (eq value tramp-cache-undefined) + ;; We cannot pass @body as parameter to + ;; `tramp-set-file-property' because it mangles our debug + ;; messages. + (setq value (progn ,@body)) + (tramp-set-file-property ,vec ,file ,property value)) + value) ,@body)) (font-lock-add-keywords 'emacs-lisp-mode '("\\<with-tramp-file-property\\>")) @@ -2191,14 +2212,15 @@ FILE must be a local file name on a connection identified via VEC." (defmacro with-tramp-connection-property (key property &rest body) "Check in Tramp for property PROPERTY, otherwise execute BODY and set." (declare (indent 2) (debug t)) - `(let ((value (tramp-get-connection-property ,key ,property 'undef))) - (when (eq value 'undef) - ;; We cannot pass ,@body as parameter to - ;; `tramp-set-connection-property' because it mangles our debug - ;; messages. - (setq value (progn ,@body)) - (tramp-set-connection-property ,key ,property value)) - value)) + `(let ((value (tramp-get-connection-property + ,key ,property tramp-cache-undefined))) + (when (eq value tramp-cache-undefined) + ;; We cannot pass ,@body as parameter to + ;; `tramp-set-connection-property' because it mangles our debug + ;; messages. + (setq value (progn ,@body)) + (tramp-set-connection-property ,key ,property value)) + value)) (font-lock-add-keywords 'emacs-lisp-mode '("\\<with-tramp-connection-property\\>")) @@ -3158,7 +3180,7 @@ User may be nil." (defun tramp-parse-putty (registry-or-dirname) "Return a list of (user host) tuples allowed to access. User is always nil." - (if (memq system-type '(windows-nt)) + (if (eq system-type 'windows-nt) (with-tramp-connection-property nil "parse-putty" (with-temp-buffer (when (zerop (tramp-call-process @@ -3733,21 +3755,19 @@ User is always nil." (signal (car err) (cdr err)))))) ;; Save exit. - (progn - (when visit - (setq buffer-file-name filename - buffer-read-only (not (file-writable-p filename))) - (set-visited-file-modtime) - (set-buffer-modified-p nil)) - (when (and (stringp local-copy) - (or remote-copy (null tramp-temp-buffer-file-name))) - (delete-file local-copy)) - (when (stringp remote-copy) - (delete-file (tramp-make-tramp-file-name v remote-copy 'nohop))))) + (when visit + (setq buffer-file-name filename + buffer-read-only (not (file-writable-p filename))) + (set-visited-file-modtime) + (set-buffer-modified-p nil)) + (when (and (stringp local-copy) + (or remote-copy (null tramp-temp-buffer-file-name))) + (delete-file local-copy)) + (when (stringp remote-copy) + (delete-file (tramp-make-tramp-file-name v remote-copy 'nohop)))) ;; Result. - (list (expand-file-name filename) - (cadr result))))) + (cons (expand-file-name filename) (cdr result))))) (defun tramp-handle-load (file &optional noerror nomessage nosuffix must-suffix) "Like `load' for Tramp files." @@ -3908,8 +3928,7 @@ substitution. SPEC-LIST is a list of char/value pairs used for (or (not (stringp stderr)) (not (tramp-tramp-file-p stderr)))))) (defun tramp-handle-make-process (&rest args) - "An alternative `make-process' implementation for Tramp files. -It does not support `:stderr'." + "An alternative `make-process' implementation for Tramp files." (when args (with-parsed-tramp-file-name (expand-file-name default-directory) nil (let ((default-directory (tramp-compat-temporary-file-directory)) @@ -5010,7 +5029,7 @@ VEC is used for tracing." (let ((candidates '("en_US.utf8" "C.utf8" "en_US.UTF-8")) locale) (with-temp-buffer - (unless (or (memq system-type '(windows-nt)) + (unless (or (eq system-type 'windows-nt) (not (zerop (tramp-call-process nil "locale" nil t nil "-a")))) (while candidates @@ -5101,7 +5120,7 @@ ID-FORMAT valid values are `string' and `integer'." (or (when-let ((handler (find-file-name-handler - (tramp-make-tramp-file-name vec) 'tramp-get-remote-uid))) + (tramp-make-tramp-file-name vec) 'tramp-get-remote-gid))) (funcall handler #'tramp-get-remote-gid vec id-format)) ;; Ensure there is a valid result. (and (equal id-format 'integer) tramp-unknown-id-integer) diff --git a/trampver.el b/trampver.el index 34032c0..ecf730d 100644 --- a/trampver.el +++ b/trampver.el @@ -7,7 +7,7 @@ ;; Maintainer: Michael Albinus <michael.albi...@gmx.de> ;; Keywords: comm, processes ;; Package: tramp -;; Version: 2.5.0.3 +;; Version: 2.5.0.4 ;; Package-Requires: ((emacs "25.1")) ;; Package-Type: multi ;; URL: https://www.gnu.org/software/tramp/ @@ -40,7 +40,7 @@ ;; ./configure" to change them. ;;;###tramp-autoload -(defconst tramp-version "2.5.0.3" +(defconst tramp-version "2.5.0.4" "This version of Tramp.") ;;;###tramp-autoload @@ -76,7 +76,7 @@ ;; Check for Emacs version. (let ((x (if (not (string-lessp emacs-version "25.1")) "ok" - (format "Tramp 2.5.0.3 is not fit for %s" + (format "Tramp 2.5.0.4 is not fit for %s" (replace-regexp-in-string "\n" "" (emacs-version)))))) (unless (string-equal "ok" x) (error "%s" x)))